找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8492|回复: 9
打印 上一主题 下一主题
收起左侧

单片机电子闹钟proteus仿真

  [复制链接]
跳转到指定楼层
楼主
电子闹钟仿真原理图:


  1. /************************************************
  2. 下面是一个多功能的电子万年历的程序。
  3. 主要功能:
  4.                 1、显示当前的日期及标准北京时间
  5.                 2、实时检测当前温度并通过1602显示出来
  6.                 3、具有可调的闹钟功能,通过按键调整闹钟的起
  7.                    闹时间
  8.                 4、通过按键实现画面的切换
  9. ************************************************/
  10. #include<reg51.h>
  11. #include<intrins.h>
  12. #define uchar unsigned char
  13. #define uint unsigned int
  14. uchar code digit[]={"0123456789"};     //定义字符数组显示数字
  15. uchar code Error[]="Error!Check!";     //说明没有检测到DS18B20
  16. uchar code table[]="Alarm Clock";
  17. uchar code table1[]="0123456789";
  18. uchar code table2[]="WEEK";
  19. uchar code table3[]="Today is fine!";
  20. uchar code table4[]="HELLO!";
  21. uchar code table5[]="Made by Xiaopeng";
  22. uchar code table6[]="Happy new year!!";//1.1
  23. uchar code table7[]="Valentine's Day"; //2.14
  24. /*uchar code table8[]="Qing Ming jie!";//4.5
  25. uchar code table9[]="Happy Labor Day!";//5.1
  26. uchar code table10[]="Duan Wu jie!";//6.15
  27. uchar code table11[]="Army day!";//8.1
  28. uchar code table12[]="Teacher's Day!";//9.10
  29. uchar code table13[]="National Day!";//10.1       
  30. /*******************************************************************************
  31. 以下是对液晶模块的操作程序
  32. *******************************************************************************/
  33. sbit RS=P2^0;           //寄存器选择位,将RS位定义为P2.0引脚
  34. sbit RW=P2^1;           //读写选择位,将RW位定义为P2.1引脚
  35. sbit E=P2^2;            //使能信号位,将E位定义为P2.2引脚
  36. sbit BF=P0^7;           //忙碌标志位,,将BF位定义为P0.7引脚
  37. sbit DQ=P2^6;
  38. sbit T_RST=P1^5;
  39. sbit T_CLK=P1^3;               
  40. sbit T_IO=P1^4;
  41. sbit beep=P2^4;
  42. sbit key1=P3^0;          //调闹钟的小时即x
  43. sbit key2=P3^1;          //调闹钟的分钟即y
  44. sbit key3=P3^2;          //显示切换
  45. sbit key4=P3^3;
  46. sbit ACC0=ACC^0;
  47. sbit ACC7=ACC^7;
  48. uchar time;   //设置全局变量,专门用于严格延时
  49. static uchar x=0x08,y=30;
  50. uchar t_sec,sec1,sec2;
  51. uchar t_min,min1,min2;
  52. uchar t_hour,hour1,hour2;
  53. uchar t_mon,mon1,mon2;
  54. uchar t_day,day1,day2;
  55. uchar t_year,year1,year2;
  56. uchar week,week1;
  57. uchar com,inf;
  58. void tixing(unsigned char mm,unsigned dd);
  59. void show();
  60. void delay1(uchar t)
  61. {
  62.         uchar a,b;
  63.         for(a=t;a>0;a--)
  64.         for(b=110;b>0;b--);
  65. }
  66. /*****************************************************
  67. 函数功能:延时1ms
  68. (3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
  69. ***************************************************/
  70. void delay1ms()
  71. {
  72.         uchar i,j;       
  73.         for(i=0;i<10;i++)
  74.          for(j=0;j<33;j++)
  75.            ;                 
  76. }
  77. /*****************************************************
  78. 函数功能:延时若干毫秒
  79. 入口参数:n
  80. ***************************************************/
  81. void delaynms(uchar n)
  82. {
  83.    uchar i;
  84.         for(i=0;i<n;i++)
  85.            delay1ms();
  86. }
  87. /*****************************************************
  88. 函数功能:判断液晶模块的忙碌状态
  89. 返回值:result。result=1,忙碌;result=0,不忙
  90. ***************************************************/
  91. bit BusyTest(void)
  92.   {
  93.     bit result;
  94.         RS=0;       //根据规定,RS为低电平,RW为高电平时,可以读状态
  95.     RW=1;
  96.     E=1;        //E=1,才允许读写
  97.     _nop_();   //空操作
  98.     _nop_();
  99.     _nop_();
  100.     _nop_();   //空操作四个机器周期,给硬件反应时间       
  101.     result=BF;  //将忙碌标志电平赋给result
  102.    E=0;         //将E恢复低电平
  103.    return result;
  104.   }
  105.   /*****************************************************
  106. 函数功能:将模式设置指令或显示地址写入液晶模块
  107. 入口参数:dictate
  108. ***************************************************/
  109. void WriteInstruction (uchar dictate)
  110. {   
  111.     while(BusyTest()==1);   //如果忙就等待
  112.          RS=0;                  //根据规定,RS和R/W同时为低电平时,可以写入指令
  113.          RW=0;   
  114.          E=0;                   //E置低电平(根据表8-6,写指令时,E为高脉冲,
  115.                            // 就是让E从0到1发生正跳变,所以应先置"0"
  116.          _nop_();
  117.          _nop_();               //空操作两个机器周期,给硬件反应时间
  118.          P0=dictate;            //将数据送入P0口,即写入指令或地址
  119.          _nop_();
  120.          _nop_();
  121.          _nop_();
  122.          _nop_();               //空操作四个机器周期,给硬件反应时间
  123.          E=1;                   //E置高电平
  124.          _nop_();
  125.          _nop_();
  126.          _nop_();
  127.          _nop_();               //空操作四个机器周期,给硬件反应时间
  128.           E=0;                  //当E由高电平跳变成低电平时,液晶模块开始执行命令
  129. }
  130. /*****************************************************
  131. 函数功能:指定字符显示的实际地址
  132. 入口参数:x
  133. ***************************************************/
  134. void WriteAddress(unsigned char x)
  135. {
  136.      WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
  137. }
  138. /*****************************************************
  139. 函数功能:将数据(字符的标准ASCII码)写入液晶模块
  140. 入口参数:y(为字符常量)
  141. ***************************************************/
  142. void WriteData(uchar y)
  143. {
  144.     while(BusyTest()==1);  
  145.           RS=1;           //RS为高电平,RW为低电平时,可以写入数据
  146.           RW=0;
  147.           E=0;            //E置低电平(根据表8-6,写指令时,E为高脉冲,
  148.                      // 就是让E从0到1发生正跳变,所以应先置"0"
  149.           P0=y;           //将数据送入P0口,即将数据写入液晶模块
  150.           _nop_();
  151.           _nop_();
  152.           _nop_();
  153.      _nop_();       //空操作四个机器周期,给硬件反应时间
  154.           E=1;           //E置高电平
  155.           _nop_();
  156.           _nop_();
  157.           _nop_();
  158.          _nop_();        //空操作四个机器周期,给硬件反应时间
  159.          E=0;            //当E由高电平跳变成低电平时,液晶模块开始执行命令
  160. }
  161. /*****************************************************
  162. 函数功能:对LCD的显示模式进行初始化设置
  163. ***************************************************/
  164. void LcdInitiate(void)
  165. {
  166.     delaynms(15);               //延时15ms,首次写指令时应给LCD一段较长的反应时间
  167.     WriteInstruction(0x38);     //显示模式设置:16×2显示,5×7点阵,8位数据接口
  168.         delaynms(5);                //延时5ms ,给硬件一点反应时间
  169.     WriteInstruction(0x38);
  170.         delaynms(5);               //延时5ms ,给硬件一点反应时间
  171.         WriteInstruction(0x38);     //连续三次,确保初始化成功
  172.         delaynms(5);               //延时5ms ,给硬件一点反应时间
  173.         WriteInstruction(0x0c);     //显示模式设置:显示开,无光标,光标不闪烁
  174.         delaynms(5);               //延时5ms ,给硬件一点反应时间
  175.         WriteInstruction(0x06);     //显示模式设置:光标右移,字符不移
  176.         delaynms(5);                //延时5ms ,给硬件一点反应时间
  177.         WriteInstruction(0x01);     //清屏幕指令,将以前的显示内容清除
  178.         delaynms(5);             //延时5ms ,给硬件一点反应时间
  179. }
  180. void write_com(uchar com)//向1602写指令
  181. {
  182.          RS=0;
  183.          RW=0;
  184.          P0=com;
  185.          delaynms(10);
  186.          E=1;
  187.          delaynms(10);
  188.          E=0;
  189. }
  190. /*****************************************************
  191. 函数功能:将DS18B20传感器初始化,读取应答信号
  192. 出口参数:flag
  193. ***************************************************/
  194. bit Init_DS18B20(void)       
  195. {
  196.          bit flag;         //储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在
  197.          DQ = 1;           //先将数据线拉高
  198.          for(time=0;time<2;time++) //略微延时约6微秒
  199.              ;
  200.          DQ = 0;           //再将数据线从高拉低,要求保持480~960us
  201.          for(time=0;time<200;time++)  //略微延时约600微秒
  202.              ;         //以向DS18B20发出一持续480~960us的低电平复位脉冲
  203.          DQ = 1;           //释放数据线(将数据线拉高)
  204.          for(time=0;time<10;time++)
  205.              ;  //延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)
  206.          flag=DQ;          //让单片机检测是否输出了存在脉冲(DQ=0表示存在)      
  207.          for(time=0;time<200;time++)  //延时足够长时间,等待存在脉冲输出完毕
  208.               ;
  209.          return (flag);    //返回检测成功标志
  210. }
  211. /*****************************************************
  212. 函数功能:从DS18B20读取一个字节数据
  213. 出口参数:dat
  214. ***************************************************/
  215. uchar ReadOneChar(void)
  216. {
  217.         uchar i=0;       
  218.         uchar dat;  //储存读出的一个字节数据
  219.         for (i=0;i<8;i++)
  220.          {
  221.           
  222.            DQ =1;       // 先将数据线拉高
  223.            _nop_();            //等待一个机器周期         
  224.            DQ = 0;      //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序
  225.                 dat>>=1;
  226.            _nop_();     //等待一个机器周期                  
  227.            DQ = 1;     //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备
  228.            for(time=0;time<2;time++)
  229.          ;      //延时约6us,使主机在15us内采样
  230.            if(DQ==1)
  231.                         dat|=0x80;  //如果读到的数据是1,则将1存入dat
  232.                 else
  233.                         dat|=0x00;//如果读到的数据是0,则将0存入dat
  234.              //将单片机检测到的电平信号DQ存入r[i]       
  235.            for(time=0;time<8;time++)
  236.                       ;              //延时3us,两个读时序之间必须有大于1us的恢复期       
  237.     }                            
  238. return(dat);    //返回读出的十进制数据
  239. }
  240. /*****************************************************
  241. 函数功能:向DS18B20写入一个字节数据
  242. 入口参数:dat
  243. ***************************************************/  
  244. void WriteOneChar(uchar dat)
  245. {
  246.         uchar i=0;
  247.         for (i=0; i<8; i++)
  248.         {
  249.           DQ =1;         // 先将数据线拉高
  250.           _nop_();             //等待一个机器周期         
  251.           DQ=0;          //将数据线从高拉低时即启动写时序      
  252.           DQ=dat&0x01;   //利用与运算取出要写的某位二进制数据,
  253.                        //并将其送到数据线上等待DS18B20采样       
  254.           for(time=0;time<10;time++)       
  255.              ;//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样
  256.           DQ=1;          //释放数据线                    
  257.           for(time=0;time<1;time++)
  258.                   ;//延时3us,两个写时序间至少需要1us的恢复期
  259.           dat>>=1;       //将dat中的各二进制位数据右移1位
  260.         }
  261.                   for(time=0;time<4;time++)
  262.                               ; //稍作延时,给硬件一点反应时间
  263. }
  264. /*****************************************************
  265. 函数功能:显示没有检测到DS18B20
  266. ***************************************************/   
  267. void display_error(void)
  268. {
  269.         uchar i;
  270.     WriteAddress(0x00);    //写显示地址,将在第1行第1列开始显示
  271.         i = 0;                //从第一个字符开始显示
  272.         while(Error[i] != '\0')  //只要没有写到结束标志,就继续写
  273.         {                                               
  274.                 WriteData(Error[i]);   //将字符常量写入LCD
  275.                 i++;                 //指向下一个字符
  276.                 delaynms(100);        //延时100ms较长时间,以看清关于显示的说明
  277.         }       
  278.         while(1)              //进入死循环,等待查明原因
  279.           ;
  280. }
  281. /*****************************************************
  282. 函数功能:显示温度的小数点
  283. ***************************************************/   
  284. void display_dot(void)
  285. {         
  286.          WriteAddress(0x80+0x40+0x03);          //写显示地址,将在第2行第10列开始显示                  
  287.          WriteData('.');      //将小数点的字符常量写入LCD
  288.          delaynms(50);         //延时1ms给硬件一点反应时间               
  289. }
  290. /*****************************************************
  291. 函数功能:显示温度的单位(Cent)
  292. ***************************************************/   
  293. void display_cent(void)
  294. {  
  295.     WriteAddress(0x80+0x40+0x05);        //写显示地址,将在第2行第13列开始显示       
  296.         WriteData(0xdf);
  297.         WriteAddress(0x80+0x40+0x06);
  298.         WriteData('C');       
  299. }
  300. /*****************************************************
  301. 函数功能:显示温度的整数部分
  302. 入口参数:x
  303. ***************************************************/
  304. void display_temp1(unsigned char x)
  305. {
  306.         uchar j,k,l;     //j,k,l分别储存温度的百位、十位和个位
  307.         j=x/100;              //取百位
  308.         k=(x%100)/10;    //取十位
  309.         l=x%10;             //取个位  
  310.         WriteAddress(0x80+0x40);    //写显示地址,将在第2行第7列开始显示
  311.         WriteData(digit[j]);    //将百位数字的字符常量写入LCD
  312.         WriteData(digit[k]);    //将十位数字的字符常量写入LCD
  313.         WriteData(digit[l]);    //将个位数字的字符常量写入LCD
  314.         delaynms(50);         //延时1ms给硬件一点反应时间     
  315. }
  316. /*****************************************************
  317. 函数功能:显示温度的小数数部分
  318. 入口参数:x
  319. ***************************************************/
  320. void display_temp2(uchar x)
  321. {
  322.         WriteAddress(0x80+0x40+0x04);      //写显示地址,将在第2行第11列开始显示
  323.         WriteData(digit[x]);     //将小数部分的第一位数字字符常量写入LCD
  324.         delaynms(50);          //延时1ms给硬件一点反应时间
  325. }
  326. /*****************************************************
  327. 函数功能:做好读温度的准备
  328. ***************************************************/
  329. void ReadyReadTemp(void)
  330. {
  331.         Init_DS18B20();     //将DS18B20初始化
  332.         WriteOneChar(0xCC); // 跳过读序号列号的操作
  333.         WriteOneChar(0x44); // 启动温度转换          
  334.     for(time=0;time<100;time++)
  335.             ;         //温度转换需要一点时间
  336.         Init_DS18B20();     //将DS18B20初始化
  337.         WriteOneChar(0xCC); //跳过读序号列号的操作
  338.         WriteOneChar(0xBE); //读取温度寄存器,前两个分别是温度的低位和高位       
  339. }
  340. /*******************************************
  341. 向1302写一个字节
  342. *******************************************/
  343. void input_BYTE(uchar dat)
  344. {
  345.         uchar i;
  346.         ACC=dat;
  347.         for(i=8;i>0;i--)
  348.         {
  349.                
  350.                 T_IO=ACC0;
  351.                 T_CLK=1;
  352.                 T_CLK=0;
  353.                 ACC=(ACC>>1);
  354.         }
  355. }
  356. /*******************************************
  357. 1302读出一个字节
  358. *******************************************/
  359. uchar output_BYTE()
  360. {
  361.         uchar i;
  362.         for(i=8;i>0;i--)
  363.         {
  364.            ACC=(ACC>>1);
  365.            ACC7=T_IO;
  366.            T_CLK=1;
  367.            T_CLK=0;
  368.         }
  369.         return (ACC);
  370. }
  371. /*******************************************
  372. 写数据
  373. *******************************************/
  374. void write_1302(uchar add,uchar dat)
  375. {
  376.         T_RST=0;
  377.         T_CLK=0;
  378.         T_RST=1;
  379.         input_BYTE(add);
  380.         input_BYTE(dat);
  381.         T_CLK=1;
  382.         T_RST=0;
  383. }
  384. /*******************************************
  385. 读数据
  386. *******************************************/
  387. uchar read_1302(uchar add)
  388. {
  389.         uchar inf;       
  390.         T_RST=0;
  391.     T_CLK=0;
  392.         T_RST=1;
  393.         input_BYTE(add);
  394.         inf=output_BYTE();
  395.         T_CLK=1;
  396.         T_RST=0;
  397.         return (inf);
  398. }
  399. void init_1302()
  400. {
  401.         write_1302(0x8e,0x00);//关闭写保护;
  402. //        write_1302(0x90,0xaa);//设置充电方式;
  403.         write_1302(0x80,0x00);//秒寄存器初始化;
  404.         write_1302(0x82,0x29);//分.......
  405.         write_1302(0x84,0x08);//时.......
  406.         write_1302(0x86,0x03);//日........
  407.         write_1302(0x88,0x06);//月.......
  408.         write_1302(0x8a,0x05);//星期...
  409.         write_1302(0x8c,0x11);//年......                 
  410.         write_1302(0x8e,0x80);//打开写保护;               
  411. }
  412. /**********************************
  413. 闹钟显示子程序
  414. **********************************/
  415. void show_naozhong(uchar x,uchar y)
  416. {
  417.         uchar i,x1,x2,y1,y2;
  418.         x1=x/10; //十位
  419.         x2=x%10;//个位       
  420.         WriteAddress(0x80+0x0b);   //显示闹钟的小时部分
  421.         WriteData(table1[x1]);
  422.         WriteAddress(0x80+0x0c);
  423.         WriteData(table1[x2]);
  424.        
  425.         y1=y/10; //十位
  426.         y2=y%10;//个位       
  427.         WriteAddress(0x80+0x0e);   //显示闹钟的分钟部分
  428.         WriteData(table1[y1]);
  429.         WriteAddress(0x80+0x0f);
  430.         WriteData(table1[y2]);
  431.        
  432.         WriteAddress(0x80+0x0d);   //显示小时与分钟之间的那个冒号
  433.         WriteData(':');

  434.         WriteAddress(0x80);                   //显示字符串:Alarm Clock
  435.         for(i=0;i<11;i++)
  436.         {
  437.                 WriteData(table[i]);       
  438.         }
  439.         WriteAddress(0x80+0x40);   //显示字符串:Today is fine!
  440.         for(i=0;i<14;i++)
  441.         {
  442.                 WriteData(table3[i]);       
  443.         }                       
  444. }
  445. void main(void)
  446. {          
  447.     uchar i;
  448.         uchar TL;     //储存暂存器的温度低位
  449.         uchar TH;    //储存暂存器的温度高位
  450.         uchar TN;      //储存温度的整数部分
  451.         uchar TD;       //储存温度的小数部分
  452.         LcdInitiate();         //将液晶初始化
  453.     init_1302();
  454.     delaynms(5);        //延时5ms给硬件一点反应时间       
  455. //        if(Init_DS18B20()==1)
  456. //   display_error();
  457.         EA=1;//开总中断
  458.         EX1=1;//开外部中断1
  459.         IT1=0;//下降沿触发

  460.         WriteAddress(0x80+0x10);
  461.         for(i=0;i<6;i++)
  462.         {
  463.                 WriteData(table4[i]);               
  464.         }
  465.         WriteAddress(0x80+0x50);
  466.         for(i=0;i<16;i++)
  467.         {
  468.                 WriteData(table5[i]);       
  469.         }
  470.         for(i=0;i<16;i++)
  471.         {
  472.                 write_com(0x18);
  473.                 delaynms(250);       
  474.         }
  475.         delaynms(250);
  476.         delaynms(250);
  477.         delaynms(250);
  478.         write_com(0x01);
  479.         while(1)
  480.         {
  481.                 t_sec=read_1302(0x81);//读秒 ;
  482.                 sec1=t_sec&0x0f;
  483.                 sec2=(t_sec>>4);
  484.        
  485.                 t_min=read_1302(0x83);//读分 ;
  486.                 min1=t_min&0x0f;
  487.                 min2=(t_min>>4);
  488.        
  489.                 t_hour=read_1302(0x85);//读小时 ;
  490.                 hour1=t_hour&0x0f;
  491.                 hour2=(t_hour>>4);

  492. //                WriteAddress(0x80+0x40+0x08); //显示小时
  493. //                WriteData(table1[hour2]);                 
  494. //                WriteAddress(0x80+0x40+0x09);
  495. //                WriteData(table1[hour1]);
  496.        
  497.                 t_day=read_1302(0x87);//读日;
  498.                 day1=t_day&0x0f;
  499.                 day2=(t_day>>4);
  500.        
  501.                 t_mon=read_1302(0x89);//读月 ;
  502.                 mon1=t_mon&0x0f;
  503.                 mon2=(t_mon>>4);
  504.        
  505.                 week=read_1302(0x8b);//读星期 ;
  506.                 week1=week&0x0f;
  507.        
  508.                 t_year=read_1302(0x8d);//读年 ;
  509.                 year1=t_year&0x0f;
  510.                 year2=(t_year>>4);
  511.        
  512.                 WriteAddress(0x80+0x06);         
  513.                 WriteData('2');
  514.                 WriteAddress(0x80+0x07);         
  515.                 WriteData('0');       
  516.                
  517.                
  518.                 WriteAddress(0x80);          //显示星期(0x80~0x80+0x05)
  519.                 for(i=0;i<4;i++)
  520.                 {
  521.                         WriteData(table2[i]);       
  522.                 }
  523.                 WriteAddress(0x80+0x04);
  524.                 WriteData(table1[week1]);
  525.                        
  526.                 WriteAddress(0x80+0x08);//显示年         
  527.                 WriteData(table1[year2]);
  528.                 WriteAddress(0x80+0x09);         
  529.                 WriteData(table1[year1]);
  530.                        
  531.                 WriteAddress(0x80+0x0a);        //显示‘/’
  532.                 WriteData('/');
  533.        
  534.                 WriteAddress(0x80+0x0b);//显示月
  535.                 WriteData(table1[mon2]);                
  536.                 WriteAddress(0x80+0x0c);
  537.                 WriteData(table1[mon1]);
  538.                 WriteAddress(0x80+0x0d);        //显示‘/’
  539.                 WriteData('/');
  540.        
  541.                 WriteAddress(0x80+0x0e);//显示日
  542.                 WriteData(table1[day2]);                
  543.                 WriteAddress(0x80+0x0f);
  544.                 WriteData(table1[day1]);
  545.                 /*第一行在此显示完毕*/                
  546.             display_dot();       //显示温度的小数点
  547.             display_cent();      //显示温度的单位
  548.        
  549.                 WriteAddress(0x80+0x40+0x08); //显示小时
  550.                 WriteData(table1[hour2]);                 
  551.                 WriteAddress(0x80+0x40+0x09);
  552.                 WriteData(table1[hour1]);               
  553.        
  554.                 WriteAddress(0x80+0x40+0x0a);  //显示':'
  555.                 WriteData(':');                                  
  556.        
  557.                 WriteAddress(0x80+0x40+0x0b);  //显示分钟
  558.                 WriteData(table1[min2]);                         
  559.                 WriteAddress(0x80+0x40+0x0c);
  560.                 WriteData(table1[min1]);                 
  561.        
  562.                 WriteAddress(0x80+0x40+0x0d); //显示':'
  563.                 WriteData(':');                               
  564.        
  565.                 WriteAddress(0x80+0x40+0x0e); //显示秒
  566.                 WriteData(table1[sec2]);                         
  567.                 WriteAddress(0x80+0x40+0x0f);
  568.                 WriteData(table1[sec1]);
  569.                 /*第二行在此显示完毕*/
  570.                 ReadyReadTemp();     //读温度准备
  571.             TL=ReadOneChar();    //先读的是温度值低位
  572.                 TH=ReadOneChar();    //接着读的是温度值高位
  573.                 TN=TH*16+TL/16;      //实际温度值=(TH*256+TL)/16,即:TH*16+TL/16
  574.                                           //这样得出的是温度的整数部分,小数部分被丢弃了
  575.             TD=(TL%16)*10/16;    //计算温度的小数部分,将余数乘以10再除以16取整,
  576.                                           //这样得到的是温度小数部分的第一位数字(保留1位小数)
  577.             display_temp1(TN);    //显示温度的整数部分
  578.             display_temp2(TD);    //显示温度的小数部分
  579.                 //以下部分是闹钟键盘检测程序
  580.                 if((x==hour2*10+hour1)&&(y==min2*10+min1))//若时间到了,则开启闹钟
  581.                 {
  582.                         beep=0;       
  583.                 }
  584.                 else                 //否则,关闭闹钟
  585.                 {
  586.                         beep=1;
  587.                 }       
  588.             delaynms(10);
  589.                 tixing(t_mon,t_day);                               
  590.         }                                          
  591. }
  592. void exter1()interrupt 2
  593. {       
  594.         uint k;
  595.         write_com(0x01);
  596.         for(k=0;k<2000;k++)
  597.         {
  598.                 while(key1==0)                   //键盘扫描.当key1按下时,
  599.                 {                                           //闹钟的小时部分加一
  600.                         delaynms(10);
  601.                         if(key1==0)                   //消抖
  602.                         {
  603.                                 delaynms(10);
  604.                                 while(key1==0);        //松手检测
  605.                                 x++;
  606.                                 if(x==24)           //小时部分加到24后自动清零
  607.                                 x=0;
  608.                         }       
  609.                 }
  610.                 while(key2==0)                //键盘检测。当key2按下时,
  611.                 {
  612.                         delaynms(10);        //闹钟的分钟部分加一
  613.                         if(key2==0)                //消抖
  614.                         {
  615.                                 delaynms(10);
  616.                                 while(key2==0);//松手检测
  617.                                 y++;
  618.                                 if(y==60)          //若分钟部分加到60,则自动清零
  619.                                 y=0;
  620.                         }       
  621.                 }                       
  622.                 show_naozhong(x,y);          //调用闹钟显示程序
  623.         }
  624.         write_com(0x01);
  625. }
  626. void tixing(unsigned char mm,unsigned dd)
  627. {
  628.         uchar i;
  629.         if(mm==0x01&&dd==0x01)
  630.         {
  631.                 while(1)
  632.                 {
  633.                         WriteAddress(0x80);
  634.                         for(i=0;i<16;i++)
  635.                         {
  636.                                 WriteData(table6[i]);       
  637.                         }
  638.                         show();
  639.                         if(mm!=0x01||dd!=0x01)
  640.                         break;                       
  641.                 }                               
  642.         }
  643.         if(mm==0x02&&dd==0x14)
  644.         {
  645.                 while(1)
  646.                 {
  647.                         WriteAddress(0x80);
  648.                         for(i=0;i<16;i++)
  649.                         {
  650.                                 WriteData(table7[i]);       
  651.                         }
  652.                         show();
  653.                         if(mm!=0x02||dd!=0x14)
  654.                         break;                       
  655.                 }               
  656.         }
  657. /*        if(mm==0x04&&dd==0x05)
  658.         {
  659.                 while(1)
  660.                 {
  661.                         WriteAddress(0x80);
  662.                         for(i=0;i<16;i++)
  663.                         {
  664.                                 WriteData(table8[i]);       
  665.                         }
  666.                         show();
  667.                         if(mm!=0x04||dd!=0x05)
  668.                         break;                       
  669.                 }               
  670.         }
  671.         if(mm==0x05&&dd==0x01)
  672.         {
  673.                 while(1)
  674.                 {
  675.                         WriteAddress(0x80);
  676.                         for(i=0;i<16;i++)
  677.                         {
  678.                                 WriteData(table9[i]);       
  679.                         }
  680.                         show();
  681.                         if(mm!=0x05||dd!=0x01)
  682.                         break;                       
  683.                 }               
  684.         }
  685.         if(mm==0x06&&dd==0x15)
  686.         {
  687.                 while(1)
  688.                 {
  689.                         WriteAddress(0x80);
  690.                         for(i=0;i<16;i++)
  691.                         {
  692.                                 WriteData(table10[i]);       
  693.                         }
  694.                         show();
  695.                         if(mm!=0x06||dd!=0x15)
  696.                         break;                       
  697.                 }               
  698.         }
  699.         if(mm==0x08&&dd==0x01)
  700.         {
  701.                 while(1)
  702.                 {
  703.                         WriteAddress(0x80);
  704.                         for(i=0;i<16;i++)
  705.                         {
  706.                                 WriteData(table11[i]);       
  707.                         }
  708.                         show();
  709.                         if(mm!=0x08||dd!=0x01)
  710.                         break;                       
  711.                 }               
  712.         }
  713.         if(mm==0x09&&dd==0x10)
  714.         {
  715.                 while(1)
  716.                 {
  717.                         WriteAddress(0x80);
  718.                         for(i=0;i<16;i++)
  719.                         {
  720.                                 WriteData(table12[i]);       
  721.                         }
  722.                         show();
  723.                         if(mm!=0x09||dd!=0x10)
  724.                         break;                       
  725.                 }               
  726.         }
  727.         if(mm==0x10&&dd==0x01)
  728.         {
  729.                 while(1)
  730.                 {
  731.                         WriteAddress(0x80);
  732.                         for(i=0;i<16;i++)
  733.                         {
  734.                                 WriteData(table13[i]);       
  735.                         }
  736.                         show();
  737.                         if(mm!=0x10||dd!=0x01)
  738.                         break;                       
  739.                 }               
  740.         }           */
  741. }
  742. void show()
  743. {
  744. //        uchar i;
  745.         uchar TL;     //储存暂存器的温度低位
  746.         uchar TH;    //储存暂存器的温度高位
  747.         uchar TN;      //储存温度的整数部分
  748.         uchar TD;       //储存温度的小数部分
  749.                
  750.                
  751.                
  752.                 t_day=read_1302(0x87);//读日;
  753.                 day1=t_day&0x0f;
  754.                 day2=(t_day>>4);
  755.        
  756.                 t_mon=read_1302(0x89);//读月 ;
  757.                 mon1=t_mon&0x0f;
  758.                 mon2=(t_mon>>4);
  759.        
  760.                 week=read_1302(0x8b);//读星期 ;
  761.                 week1=week&0x0f;
  762.        
  763.                 t_year=read_1302(0x8d);//读年 ;
  764.                 year1=t_year&0x0f;
  765.                 year2=(t_year>>4);
  766.                 t_sec=read_1302(0x81);//读秒 ;
  767.                 sec1=t_sec&0x0f;
  768.                 sec2=(t_sec>>4);
  769.        
  770.                 t_min=read_1302(0x83);//读分 ;
  771.                 min1=t_min&0x0f;
  772.                 min2=(t_min>>4);
  773.        
  774.                 t_hour=read_1302(0x85);//读小时 ;
  775.                 hour1=t_hour&0x0f;
  776.                 hour2=(t_hour>>4);

  777. //                WriteAddress(0x80+0x40+0x08); //显示小时
  778. //                WriteData(table1[hour2]);                 
  779. //                WriteAddress(0x80+0x40+0x09);
  780. //                WriteData(table1[hour1]);
  781.        
  782.                 t_day=read_1302(0x87);//读日;
  783.                 day1=t_day&0x0f;
  784.                 day2=(t_day>>4);
  785.        
  786.                 t_mon=read_1302(0x89);//读月 ;
  787.                 mon1=t_mon&0x0f;
  788.                 mon2=(t_mon>>4);
  789.        
  790.                 week=read_1302(0x8b);//读星期 ;
  791.                 week1=week&0x0f;
  792.        
  793.                 t_year=read_1302(0x8d);//读年 ;
  794.                 year1=t_year&0x0f;
  795.                 year2=(t_year>>4);

  796.                
  797.                        
  798.             display_dot();       //显示温度的小数点
  799.             display_cent();      //显示温度的单位
  800.        
  801.                 WriteAddress(0x80+0x40+0x08); //显示小时
  802.                 WriteData(table1[hour2]);                 
  803.                 WriteAddress(0x80+0x40+0x09);
  804.                 WriteData(table1[hour1]);               
  805.        
  806.                 WriteAddress(0x80+0x40+0x0a);  //显示':'
  807.                 WriteData(':');                                  
  808.        
  809.                 WriteAddress(0x80+0x40+0x0b);  //显示分钟
  810.                 WriteData(table1[min2]);                         
  811.                 WriteAddress(0x80+0x40+0x0c);
  812.                 WriteData(table1[min1]);                 
  813.        
  814.                 WriteAddress(0x80+0x40+0x0d); //显示':'
  815.                 WriteData(':');                               
  816.        
  817.                 WriteAddress(0x80+0x40+0x0e); //显示秒
  818.                 WriteData(table1[sec2]);                         
  819.                 WriteAddress(0x80+0x40+0x0f);
  820.                 WriteData(table1[sec1]);
  821.                 /*第二行在此显示完毕*/
  822.                 ReadyReadTemp();     //读温度准备
  823.             TL=ReadOneChar();    //先读的是温度值低位
  824.                 TH=ReadOneChar();    //接着读的是温度值高位
  825.                 TN=TH*16+TL/16;      //实际温度值=(TH*256+TL)/16,即:TH*16+TL/16
  826.                                           //这样得出的是温度的整数部分,小数部分被丢弃了
  827.             TD=(TL%16)*10/16;    //计算温度的小数部分,将余数乘以10再除以16取整,
  828.                                           //这样得到的是温度小数部分的第一位数字(保留1位小数)
  829.             display_temp1(TN);    //显示温度的整数部分
  830.             display_temp2(TD);    //显示温度的小数部分
  831.                 //以下部分是闹钟键盘检测程序
  832.                 if((x==hour2*10+hour1)&&(y==min2*10+min1))//若时间到了,则开启闹钟
  833.                 {
  834.                         beep=0;       
  835.                 }
  836.                 else                 //否则,关闭闹钟
  837.                 {
  838.                         beep=1;
  839.                 }       
  840.             delaynms(10);                               
  841. }
复制代码


所有资料下载:
电子闹钟.zip (135.6 KB, 下载次数: 156)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:160146 发表于 2017-1-11 16:53 | 只看该作者
我看了下,响的时间有一分钟,能不能减少到十秒啊?而且怎么改铃声啊
回复

使用道具 举报

板凳
ID:156885 发表于 2017-1-31 16:12 | 只看该作者
修改代码啊,再烧录
回复

使用道具 举报

地板
ID:223127 发表于 2017-11-1 17:40 | 只看该作者
我们的强大 源于 亲 的无私奉献!!!!!
回复

使用道具 举报

5#
ID:520987 发表于 2019-4-27 11:16 | 只看该作者
怎样修改时间呢?
回复

使用道具 举报

6#
ID:523687 发表于 2019-4-28 15:19 | 只看该作者
怎么修改时间啊?
回复

使用道具 举报

7#
ID:659185 发表于 2019-12-8 22:39 | 只看该作者
这个源程序如何改为基于单片机的电子时钟及带闹钟装置设计
回复

使用道具 举报

8#
ID:683548 发表于 2020-1-8 14:24 来自手机 | 只看该作者
程序好像少点什么吧
回复

使用道具 举报

9#
ID:692455 发表于 2020-2-13 17:58 | 只看该作者
很强,感谢
回复

使用道具 举报

10#
ID:253767 发表于 2020-2-14 07:50 | 只看该作者
谢谢分享!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表