51单片机时钟12C887+温度18b20C程序

发布者:740322lwj最新更新时间:2015-11-17 来源: eefocus关键字:51单片机 手机看文章 扫描二维码
随时随地手机看文章
51单片机时钟12C887+温度18b20C程序

 

#include
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
sbit rs=P3^5;
sbit lcden=P3^4;
sbit s1=P3^0;//功能键选择
sbit s2=P3^1;//数值加1
sbit s3=P3^2;//数值减1
sbit s4=P3^6;//闹钟查看设置键
sbit rd=P3^7;//
sbit beep=P2^3;//蜂鸣器
sbit dscs=P1^4;
sbit dsas=P1^5;
sbit dsrw=P1^6;
sbit dsds=P1^7;
sbit dsirq=P3^3;
sbit DQ=P2^2;  //温度数据通信线

uint temp,tplsb,tpmsb;  //温度   
uchar s1num,s4num,flag,flag1;
uchar miao,shi,fen,week,ri,yue,nian,amiao,afen,ashi;

uchar code table1[]="      ";
uchar code table2[]="           ";
                     //    周一周二 周三 周四周五 周六周日             
uchar code table3[]={0xff,0x4d,0x54,0x57,0x54,0x46,0x53,0x53};
                     //                 S
uchar code table4[]={0xff,0x4f,0x55,0x45,0x48,0x52,0x41,0x55};
     //                  U
uchar code table5[]={0xff,0x4e,0x45,0x44,0x55,0x49,0x54,0x4e};
                    //                  N
void write_ds(uchar,uchar);
void set_alarm(uchar,uchar,uchar);
uchar read_ds(uchar);
//void set_time();
void read_alarm();


void delay(uint z)
{
 uint x,y;
 for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}

void Delay_DS18B20(uint num)
{
  while(num--) ;
}

void write_com(uchar com)
{
 rs=0;
 lcden=0;
 P0=com;
 delay(3);
 lcden=1;
 delay(3);
 lcden=0; 
}

void write_date(uchar date)
{
 rs=1;
 lcden=0;
 P0=date;
 delay(3);
 lcden=1;
 delay(3);
 lcden=0; 
}

void init()             
{
 uchar num;
 EA=1; //打开总中断
 EX1=1;//开定时器0中断
 IT1=1;//

 flag1=0;//闹钟设置,0为不响
 s1num=0;
 dula=0;//关闭数码管
 wela=0;//关闭数码管
 lcden=0;
 rd=0;
// set_time();
 read_alarm();
 write_ds(0x0a,0x20);//时钟芯片寄存器A 
 write_ds(0x0b,0x26);//时钟芯片寄存器B
// read_ds(0x0c);      //时钟芯片寄存器C
 write_com(0x38);    //液晶显示模式
 write_com(0x0c);    //液晶显示、开关、光标打开
 write_com(0x06);    //液晶地址指针及光标移动情况
 write_com(0x01);    //清屏
    write_com(0x80);    //屏幕第一行
 for(num=0;num<12;num++)
  {
   write_date(table1[num]);
   delay(1);
  }
 write_com(0x80+0x40);//屏幕第二行
 for(num=0;num<16;num++)
  {
   write_date(table2[num]);
   delay(1);
  }
}

void Init_DS18B20()
{
 uchar x=0;
 DQ = 1;         //DQ复位
 Delay_DS18B20(8);//稍做延时
 DQ = 0;         //单片机将DQ拉低
 Delay_DS18B20(80);//精确延时,大于480us
 DQ = 1;         //拉高总线
 Delay_DS18B20(14);
 x = DQ;        //稍做延时后,如果x=0则初始化成功,x=1则初始化失败
 Delay_DS18B20(20);
}

uchar ReadOneChar()
{
 uchar i=0;
 uchar dat = 0;
 for (i=8;i>0;i--)
 {
  DQ = 0;     // 给脉冲信号
  dat>>=1;
  DQ = 1;     // 给脉冲信号
  if(DQ)
  dat|=0x80;
  Delay_DS18B20(4);
 }
 return(dat);
}

void WriteOneChar(uchar dat)
{
 uchar i=0;
 for (i=8; i>0; i--)
 {
  DQ = 0;
  DQ = dat&0x01;
  Delay_DS18B20(5);
  DQ = 1;
  dat>>=1;
 }
}
 [page]
uint Readtemp()
{
 uchar a=0;
 uchar b=0;
 uint t=0;
 float tt=0;
 Init_DS18B20();
 WriteOneChar(0xCC);  //跳过读序号列号的操作
 WriteOneChar(0x44);  //启动温度转换
 Init_DS18B20();
 WriteOneChar(0xCC);  //跳过读序号列号的操作
 WriteOneChar(0xBE);  //读取温度寄存器
 a=ReadOneChar();     //读低8位
 b=ReadOneChar();     //读高8位
 t=b;
 t<<=8;
 t=t|a;
 tt=t*0.0625;
 t= tt*10+0.5;     //放大10倍输出并四舍五入
 return(t);
}

void display(uint temp)          
{
 uchar A1,A2,A3;
 A1=temp/100;
 A2=temp%100/10;
 A3=temp%10; 
 write_com(0x80+0x40+10);
 write_date(0x30+A1);//十位
 write_date(0x30+A2);//个位
 write_date(0x2e);//小数点
 write_date(0x30+A3);//小数点后一位
 write_date(0xdf);//
 write_date(0x43);//C

}



void didi()      
{
 beep=0;
 delay(100);
 beep=1;
}

void write_nyrx(uchar add,uchar date)
{
 uchar shi,ge;
 shi=date/10;
 ge=date%10;
 write_com(0x80+add);
 write_date(0x30+shi);
 write_date(0x30+ge);
}


void write_sfm(uchar add,uchar date)//
{
 uchar shi,ge;
 shi=date/10;
 ge=date%10;
 write_com(0x80+0x40+add);
 write_date(0x30+shi);
 write_date(0x30+ge);
}

void keyscan() 
{
 
// rd=0;
 if(flag1==1)//按s1 s4键消除报警
 {
  if((s1==0)||(s4==0))
  {
   delay(5);
   if((s1==0)||(s4==0))
   while(!(s1&&s4));
   didi();
   flag1=0;//消除报警标志
  }
 }
      
 if(s1==0) //调时功能键
 {
  delay(5);
  if(s1==0)
  
   s1num++;
   flag=1;//flag功能键标志位  0为显示,1为不显示
   while(!s1);
   didi();
   if(s1num==1)
   {
    TR1=0;
    write_com(0x80+0x40+8);
    write_com(0x0f);
   }

   if(s1num==2)
   {
    write_com(0x80+0x40+5);
   }
   if(s1num==3)
   {
    write_com(0x80+0x40+2);
   }
   if(s1num==4)
   {
    write_com(0x80+9);
   }
   if(s1num==5)
   {
    write_com(0x80+6);
   }
   if(s1num==6)
   {
    write_com(0x80+3);
   }
   if(s1num==7)
   {
    write_com(0x80+0);
   }
   if(s1num==8)
   {
    s1num=0;
    write_com(0x0c);
    flag=0;
    write_ds(0,miao);
    write_ds(2,fen);
    write_ds(4,shi);
    write_ds(6,week);
    write_ds(7,ri); 
    write_ds(8,yue);
    write_ds(9,nian); 
   }
  }
    
 }
 if(s1num!=0)
 {
  if(s2==0)//功能键加1
  {
   delay(5);
   if(s2==0)
   {
    delay(5);
    while(!s2);
    didi();
    if(s1num==1)
    {
     miao++;
     if(miao==60)
      miao=0;
     write_sfm(7,miao);
     write_com(0x80+0x40+8);            
    }
    if(s1num==2)
    {
     fen++;
     if(fen==60)
      fen=0;
     write_sfm(4,fen);
     write_com(0x80+0x40+5);
    }
    if(s1num==3)
    {
     shi++;
     if(shi==24)
      shi=0;
     write_sfm(1,shi);
     write_com(0x80+0x40+2);
    }
    if(s1num==4)
    {
     week++;
     if(week==8)
      week=0;
     write_com(0x80+9);      
     write_date(table3[week]);
     write_date(table4[week]);
     write_date(table5[week]);             
    }
    if(s1num==5)
    {
     ri++;
     if(ri==32)
      ri=1;
     write_nyrx(6,ri);
     write_com(0x80+6);      
    }
    if(s1num==6)
    {
     yue++;
     if(yue==13)
      yue=1;
     write_nyrx(3,yue);
     write_com(0x80+3);
    }
    if(s1num==7)
    {
     nian++;
     if(nian==99)
      nian=0;
     write_nyrx(0,nian);
     write_com(0x80+0); 
    }
   }
  }
  if(s3==0)//功能键减1
  {
   delay(5);
   if(s3==0)
   
    delay(5);
    while(!s3);
    didi();
    if(s1num==1)
    {
     miao--;
     if(miao==-1)
      miao=59;
     write_sfm(7,miao);
     write_com(0x80+0x40+8);
    }
    if(s1num==2)
    {
     fen--;
     if(fen==-1)
      fen=59;
     write_sfm(4,fen);
     write_com(0x80+0x40+5);
    }
    if(s1num==3)
    {
     shi--;
     if(shi==-1)
      shi=23;
     write_sfm(1,shi);
     write_com(0x80+0x40+2);
    }
    if(s1num==4)
    {
     week--;
     if(week==0)
      week=7;
     write_com(0x80+9);      
     write_date(table3[week]);
     write_date(table4[week]);
     write_date(table5[week]);             
    }
    if(s1num==5)
    {
     ri--;
     if(ri==0)
      ri=31;
     write_nyrx(6,ri);
     write_com(0x80+6);
    }
    if(s1num==6)
    {
     yue--;
     if(yue==0)
      yue=12;
     write_nyrx(3,yue);
     write_com(0x80+3);     
    }
    if(s1num==7)
    {
     nian--;
     if(nian==-1)
      nian=99;
     write_nyrx(0,nian);
     write_com(0x80+0); 
        
   }
  }
 }
  [page]
 if(s4==0)//闹钟设置键 
 {
  delay(5);
  if(s4==0)
  
   s4num++;
   flag=1;  //
   while(!s4);
   didi();
   if(s4num==1)
   {
    write_com(0x80);
    write_date(' ');
    write_date(' ');
    write_date('S');
    write_date('E');
    write_date('T');
    write_date(' ');
    write_date(' ');
    write_date('A');
    write_date('L');
    write_date('A');
    write_date('R');
    write_date('M');
    write_com(0x80+0x40);
    write_date(' ');
    write_date('0');
    write_date('0');
    write_date(':');
    write_date('0');
    write_date('0');
    write_date(':');
    write_date('0');
    write_date('0');
    write_com(0x80+0x40+8);
    write_com(0x0f);
   }
   if(s4num==2)
    write_com(0x80+0x40+5);
   if(s4num==3)
    write_com(0x80+0x40+2);
   if(s4num==4)
   {
    s4num=0;
    write_com(0x0c);
    flag=0;
    write_com(0x80+2);
    write_date('-');
    write_com(0x80+5);
    write_date('-');
    write_com(0x80+8);
    write_date(' ');
    write_ds(0,miao);
    write_ds(1,amiao);
    write_ds(2,fen);
    write_ds(3,afen);
    write_ds(4,shi);
    write_ds(5,ashi);
    write_ds(6,week);
    write_ds(7,ri); 
    write_ds(8,yue);
    write_ds(9,nian); 
   }
  }
    
 }
 if(s4num!=0)
 {
  if(s2==0)//加1
  {
   delay(5);
   if(s2==0)
   {
    delay(5);
    while(!s2);
    didi();
    if(s4num==1)
    {
     amiao++;
     if(amiao==60)
      amiao=0;
     write_sfm(7,amiao);
     write_com(0x80+0x40+8);            
    }
    if(s4num==2)
    {
     afen++;
     if(afen==60)
      afen=0;
     write_sfm(4,afen);
     write_com(0x80+0x40+5);
    }
    if(s4num==3)
    {
     ashi++;
     if(ashi==24)
      ashi=0;
     write_sfm(1,ashi);
     write_com(0x80+0x40+2);
    }
   }
  }
  if(s3==0)//减1
  {
   delay(5);
   if(s3==0)
   
    delay(5);
    while(!s3);
    didi();
    if(s4num==1)
    {
     amiao--;
     if(amiao==-1)
      amiao=59;
     write_sfm(7,amiao);
     write_com(0x80+0x40+8);
    }
    if(s4num==2)
    {
     afen--;
     if(afen==-1)
      afen=59;
     write_sfm(4,afen);
     write_com(0x80+0x40+5);
    }
    if(s4num==3)
    {
     ashi--;
     if(ashi==-1)
      ashi=23;
     write_sfm(1,ashi);
     write_com(0x80+0x40+2);
    }
   }
  }
 }

}

void write_ds(uchar add,uchar date)
{
 dscs=0;
 dsas=1;
 dsds=1;
 dsrw=1;
 P0=add;   //先写地址
 dsas=0;
 dsrw=0;
 P0=date;  //再写数据
 dsrw=1;
 dsas=1;
 dscs=1;    
}

uchar read_ds(uchar add)         
{
  uchar ds_date;
 dsas=1;
 dsds=1;
 dsrw=1;
 dscs=0; 
 P0=add;    //先写地址
 dsas=0;
 dsds=0;
 P0=0xff;
 ds_date=P0; //再读数据
 dsds=1;
 dsas=1;
 dscs=1;
 return ds_date; 
}



void read_alarm()
{
 amiao=read_ds(1);
 afen=read_ds(3);
 ashi=read_ds(5);
}



void main()  
{
 Readtemp();    // 读温度
 flag=0;        //时钟芯片的显示标志
  init();      //时钟芯片的初始化   
 while(1)
 {
  keyscan();

  if(flag1==1)//闹钟设置
  {
   didi();
   delay(100);
   didi();
   delay(500);
  }

  if(flag==0)//flag显示标志位 0为显示
  {
   keyscan();
   miao=read_ds(0);//读12C887数据 
   fen=read_ds(2);
   shi=read_ds(4);
   week=read_ds(6);
   ri =read_ds(7);
   yue=read_ds(8);
   nian=read_ds(9);
   write_sfm(7,miao);//送液晶显示
   write_sfm(4,fen);
   write_sfm(1,shi);
   write_nyrx(6,ri);
   write_nyrx(3,yue);
   write_nyrx(0,nian);
   write_com(0x80+9);
    write_date(table3[week]);
   write_date(table4[week]);
   write_date(table5[week]);  
          display(Readtemp());//显示温度
  }
 }
}

void exter() interrupt 2  //闹钟中断
{
 uchar c;
 flag1=1;
 c=read_ds(0x0c);
}

关键字:51单片机 引用地址:51单片机时钟12C887+温度18b20C程序

上一篇:MSP430采集电压信号程序
下一篇:单片机上的RS485接口

推荐阅读最新更新时间:2024-03-16 14:39

基于51单片机的倒计时器设计
// 本程序的电路很简单就不画图了,就是8位数码管的段选接在P0口, //为了节约端口8个位接在了74hc138上,由P2.1 P2.0 P2.2控制译码器输出位选. //本程序完全测试通过.完整代码下载地址: http://www.51hei.com/f/djsq.rar /************************************************************************/ /************8位数码管倒计时显示 时间格式24 00 00~~00-00-00**************/ /*******************************************
[单片机]
51单片机 动态数码管显示
本章博客写的内容主要围绕动态数码管显示,动态数码管显示与静态数码管显示比较稍有变化,主要在添加延时函数这点上 1.首先将上一章节使用子函数方法的代码复制过来 将Nixie( , )移到下方while循环中(因为要实现效果为动态的) void main() { while(1) { Nixie(1,1); Nixie(2,2); Nixie(3,3); } } 编译下载后效果为: 对于这种效果要进行消影的处理 因为单片机编译处理顺序是按照:位选 段选 (清零),位选 段选 ,位选 段选 由上一段的段选到下一部分的位选需要进行清零处理 接下来主要进行:增添延时函数和清零
[单片机]
<font color='red'>51单片机</font> 动态数码管显示
基于USB总线和89C51单片机的数据采集系统设计
在工业生产和科学技术研究过程的各行业中,常常要对各种数据进行采集,现在常用的采集方式是在PC机或工控机内安装数据采集卡,如A/D卡及RS-422卡、RS-485卡。采集卡不仅安装麻烦,易受机箱内环境的影响,而且由于受计算机插槽数量和地址、中断资源的限制,不可能挂接很多设备。而通用串行总线(Universal Serial Bus,简称USB)的出现能很好地解决以上这些冲突。我们利用89C51单片机设计了基于USB总线的数据采集设备,并可与MAX485结合起来实现数据的远程采集。 系统硬件设计 USB数据采集系统硬件模块主要由串行A/D转换器、89C51芯片、USB接口芯片和多路模拟开关等组成。硬件总体结构框图如图1所示。
[应用]
18-基于51单片机的排队叫号系统
具体实现功能 系统由STC89C52单片机+按键模块+LCD1602液晶屏+蜂鸣器呼叫模块+电源构成。 具体功能: 1、主机通过按键完成叫号,LCD1602液晶显示屏显示被叫的号码及服务的柜台号;同时,蜂鸣器响,以提醒顾客接收服务; 2、从机按下按键实现取号,并通过串行通信方式实现排队取号功能; 3、从机还可以实时显示自己的排队号及及当前正在等待的人数。 设计背景 排队论(又称随机服务系统)是研究系统由于随机因素的干扰而出现排队(或拥塞)现象的规律的一门学科,它适用于一切服务系统,包括公共服务系统、通信系统、计算机系统等。可以说,凡是出现拥塞现象的系统,都属于随机服务系统。一个对象通过拥塞系统接受服务必须经过三
[单片机]
18-基于<font color='red'>51单片机</font>的排队叫号系统
c51单片机第一课笔记
1,串口 并口的区别 串行接口,简称串口,也就是COM接口,是采用串行通信协议的扩展接口。串口的出现是在1980年前后,数据传输率是115kbps~230kbps,串口一般用来连接鼠标和外置Modem以及老式摄像头和写字板等设备,目前部分新主板已开始取消该接口。 并行接口,简称并口,也就是LPT接口,是采用并行通信协议的扩展接口。并口的数据传输率比串口快8倍,标准并口的数据传输率为1Mbps,一般用来连接打印机、扫描仪等。所以并口又被称为打印口。 2什么是下拉电阻 什么是上拉电阻分别的作用。 3 ttl电平 5型号介绍 stc89c52 40c-pdip 0721cv4336 c 是指cmos 52 51 55 52 2x4k
[单片机]
用Proteus学习51单片机之数码管
今天学的是数码管和锁存器的使用。用锁存器的目的,是为了减小IO口的使用,本来至少得用15根IO口的,用了锁存器后,只需要用10根IO口,若是继续增加数码管,IO口的增加也是一根根增加了。 锁存器的作用,是把当然IO口的状态保存下来,具体由锁存器的LE脚控制,当LE脚为高电平时,锁存器的输出和输入一样,若LE脚为低电平时,则把LE脚电平改变前的输入脚的状态保存下来作为输出,此时不管输入怎么变,它的输出也不会变了。这样,就做到了单片机的1组输出脚,可以控制多个设备的目的。 原理图请见上图,在图中,可以看到导线很少,这是因为要连接的导线很多,如果直接用导线连接的话,会导致整个设计图乱成一片,根本看不清楚,所以,这里使用标号来连接
[单片机]
用Proteus学习<font color='red'>51单片机</font>之数码管
51单片机的串行通信口原理解析
MCS-51单片机内部有一个全双工的串行通信口,即串行接收和发送缓冲器(SBUF),这两个在物理上独立的接收发送器,既可以接收数据也可以发送数据。但接收缓冲器只能读出不能写入,而发送缓冲器则只能写入不能读出,它们的地址为99H。这个通信口既可以用于网络通信,亦可实现串行异步通信,还可以构成同步移位寄存器使用。如果在传行口的输入输出引脚上加上电平转换器,就可方便地构成标准的RS-232接口。下面我们分别介绍。 [1]。 基本概念 数据通信的传输方式 常用于数据通信的传输方式有单工、半双工、全双工和多工方式。 单工方式:数据仅按一个固定方向传送。因而这种传输方式的用途有限,常用于串行口的打印数据传输与简单系统间的数据采集。 半双工
[单片机]
<font color='red'>51单片机</font>的串行通信口原理解析
谈谈51单片机的RETI指令
  最近在基于51 单片机 编程的过程中出现了个很奇怪的问题 程序执行中在寄存器EA=1,ET0=1,TR0=1条件下,单TF0=1时并没有执行中断 。   在有过单片机中断编程经历者都知道当EA=1,ET0=1的条件下,满足TF0=1时,如果在此期间没有更高优先级的中断执行的情况下定时器中断0必定会产生中断响应。而在我所编写的程序中仅使用了定时器中断0,一个中断也就谈不上存在优先级问题。经过我对自己程序的检查并对各教材中断程序对比发现我的程序中的一个问题:由于中断的不可控性决定其跳出中断返回主程序的不确定,而由于程序需要中断跳出后能跳到指定的地址。为了解决这个问题我在中断结束的地方直接用了无条件跳转指令 LJMP ADR16 其
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved