找回密码
 立即注册

QQ登录

只需一步,快速开始

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

多功能电子时钟程序

[复制链接]
跳转到指定楼层
楼主
ID:531648 发表于 2019-5-27 08:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit rs=P1^5;//寄存器选择
  6. sbit rw=P1^6;//读写信号线
  7. sbit lcden=P1^7;//led使能端

  8. sbit scl=P3^4;//时钟线
  9. sbit rst=P3^5;//复位线
  10. sbit io=P3^3;//数据口

  11. sbit key_set_time=P2^4;//设置时间键
  12. sbit key_add=P2^5;//加键
  13. sbit key_minus=P2^6;//减键
  14. sbit key_set_alarm=P2^7;//设置闹钟键
  15. sbit bee=P3^2;//蜂鸣器接口
  16. sbit dq=P1^4;//ds18b20测温

  17. uchar getTimebuf[7];//存放时间数据
  18. uchar time[]={"  :  :  "};//时间格式字符串
  19. uchar date[]={"20  -  -  "};//日期格式字符串
  20. uchar weeklist[]={"SunMonTueWedThuFriSat"};//星期字符列表
  21. uchar week[]={"   "};//星期格式字符串

  22. int count;//设定秒分时日月星期年的时候count的值分别为1235647
  23. int alarm;//是否进入闹钟设置界面 123分别代表开关 分 小时的设置
  24. int isOpen;//闹钟是否开启  默认不开启
  25. int fen,shi;//闹钟的分钟小时
  26. int isRing;//闹钟是否在响

  27. uchar isInit_1302;//是否初始化时钟完毕

  28. int num;
  29. int temperature;//温度
  30. int temp_flag;//温度正负标志

  31. void delay(uint x){
  32.         int y;
  33.         while(x--){
  34.                 for(y=100;y>0;y--);
  35.         }
  36. }
  37. void write_1602com(uchar com){
  38.         //1602写指令
  39.         rs=0;
  40.         lcden=0;
  41.         P0=com;
  42.         delay(5);
  43.         lcden=1;
  44.         delay(5);
  45.         lcden=0;
  46. }
  47. void write_1602data(uchar dat){
  48.         //1602写数据
  49.         rs=1;
  50.         lcden=0;
  51.         P0=dat;
  52.         delay(5);
  53.         lcden=1;
  54.         delay(5);
  55.         lcden=0;
  56. }
  57. void init_1602(){
  58.         //初始化1602液晶
  59.         rw=0;
  60.         lcden=0;
  61.         write_1602com(0x38);//设置显示模?
  62.         write_1602com(0x38);
  63.         write_1602com(0x0c);//显示开关及光标是否显示和闪动
  64.         write_1602com(0x06);//光标移动方向
  65.         write_1602com(0x01);//清屏
  66. }
  67. void write_ds1302_byte(uchar temp){
  68.         //ds1302写一个字节数据
  69.         uchar i;
  70.         for(i=0;i<8;i++){
  71.                 io=temp&0x01;//将数据放到IO口上
  72.                 scl=0;//scl为低时准备数据
  73.                 scl=1;//上升沿写入
  74.                 temp>>=1;
  75.         }
  76. }
  77. void write_ds1302(uchar add,uchar dat){
  78.         //向地址add写入数据dat
  79.         rst=0;
  80.         scl=0;
  81.         rst=1;
  82.         write_ds1302_byte(add);
  83.         write_ds1302_byte(dat);
  84.         scl=1;
  85.         rst=0;
  86. }
  87. uchar read_ds1302(uchar add){
  88.         //ds1302读数据
  89.         uchar i,dat;
  90.         rst=0;
  91.         scl=0;
  92.         rst=1;
  93.         write_ds1302_byte(add);//首先写入要读的数据处的地址
  94.         for(i=0;i<8;i++){
  95.                 if(io==1){
  96.                         dat|=0x80;
  97.                 }
  98.                 scl=1;
  99.                 scl=0;//下降沿读取数据
  100.                 dat>>=1;
  101.         }
  102.         scl=1;
  103.         rst=0;
  104.         return dat;
  105. }
  106. void read_time(uchar curr_time[]){
  107.           uchar i;
  108.           uchar ucAddr = 0x81;
  109.           for (i=0;i<7;i++){
  110.                 curr_time[i] = read_ds1302(ucAddr);//格式为: 秒 分 时 日 月 星期 年
  111.                 ucAddr += 2;
  112.           }
  113. }
  114. void set_time(uchar *pSecDa){
  115.         //设定时间
  116.         uchar i;
  117.         uchar ucAddr = 0x80;
  118.         write_ds1302(0x8e,0x00);        
  119.         for(i =7;i>0;i--){
  120.                 write_ds1302(ucAddr,*pSecDa); //秒 分 时 日 月 星期 年
  121.                 pSecDa++;
  122.                 ucAddr+=2;
  123.         }
  124.         write_ds1302(0x8e,0x80);
  125. }
  126. void init_ds1302(){
  127.         //ds1302初始化
  128.         isInit_1302=read_ds1302(0x81);//读出时钟状态
  129.         if(isInit_1302&0x80){//说明没有初始化
  130.                 write_ds1302(0x8e,0x00);//关闭写保护  以后一直开着
  131.                 write_ds1302(0x90,0xa5); //辅助电源充电命令 一个二极管  一个2K电阻
  132.                 write_ds1302(0x80,0x00);//秒 CH置0 开启时钟
  133.                 write_ds1302(0x82,0x59);//分
  134.                 write_ds1302(0x84,0x10);//时
  135.                 write_ds1302(0x86,0x07);//日
  136.                 write_ds1302(0x88,0x05);//月
  137.                 write_ds1302(0x8a,0x04);//星期
  138.                 write_ds1302(0x8c,0x14);//年
  139.                 write_ds1302(0x8e,0x80);
  140.         }
  141. }
  142. char int_to_char(int temp){
  143.         //把0到9对应的数字转为字符
  144.         char x='0';
  145.         switch(temp){
  146.                 case 0:x='0';break;
  147.                 case 1:x='1';break;
  148.                 case 2:x='2';break;
  149.                 case 3:x='3';break;
  150.                 case 4:x='4';break;
  151.                 case 5:x='5';break;
  152.                 case 6:x='6';break;
  153.                 case 7:x='7';break;
  154.                 case 8:x='8';break;
  155.                 case 9:x='9';break;
  156.         }
  157.         return x;
  158. }
  159. int ds18b20_read_temp();
  160. void display(){
  161.         uchar bai,shi,ge,point,fuhao;
  162.         read_time(getTimebuf);//时时读取时间
  163.     time[6]=(getTimebuf[0])/16+48;//格式化时间秒
  164.     time[7]=(getTimebuf[0])%16+48;

  165.     time[3]=(getTimebuf[1])/16+48;//格式化时间分
  166.     time[4]=(getTimebuf[1])%16+48;

  167.     time[0]=(getTimebuf[2])/16+48;//格式化时间小时
  168.     time[1]=(getTimebuf[2])%16+48;

  169.     date[8]=getTimebuf[3]/16+48;//格式化日期日
  170.     date[9]=getTimebuf[3]%16+48;

  171.     date[5]=getTimebuf[4]/16+48;//格式化日期月
  172.     date[6]=getTimebuf[4]%16+48;

  173.     date[2]=getTimebuf[6]/16+48;//格式化日期年
  174.     date[3]=getTimebuf[6]%16+48;

  175.     week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期
  176.     week[1]=weeklist[(getTimebuf[5]%10)*3+1];
  177.     week[2]=weeklist[(getTimebuf[5]%10)*3+2];
  178.         
  179.         write_1602com(0x80+1);
  180.         for(num=0;num<10;num++){
  181.                 write_1602data(date[num]);
  182.         }

  183.         write_1602data(' ');
  184.         for(num=0;num<3;num++){
  185.                 write_1602data(week[num]);
  186.         }

  187.         write_1602com(0x80+0x40);
  188.         for(num=0;num<8;num++){
  189.                 write_1602data(time[num]);
  190.         }
  191.         
  192.         //显示温度值
  193.         write_1602com(0x80+0x40+8);//设置数据指针
  194.         temperature=ds18b20_read_temp();
  195.         bai=temperature/1000+0x30;
  196.         shi=temperature%1000/100+0x30;
  197.         ge=temperature%100/10+0x30;
  198.         point=temperature%100%10+0x30;
  199.         if(temp_flag==1){//说明为正数  不显示符号位 125.6 25.7两种
  200.                 fuhao=0x20;//显示空白
  201.                 if(bai==0x30){
  202.                         bai=0x20;//如果百位为0  不显示
  203.                         if(shi==0x30){
  204.                                 shi=0x20;//如果百位为0  十位也为0  都不显示
  205.                         }
  206.                 }
  207.                 write_1602data(fuhao);
  208.                 write_1602data(bai);
  209.                 write_1602data(shi);
  210.         }else{
  211.                 fuhao=0x2d;//显示负号  -2.5  -25.8两种
  212.                 write_1602data(0x20);//因为负数最低到55,所以不显示百位
  213.                 if(shi==0x30){        
  214.                         write_1602data(0x20);
  215.                         write_1602data(fuhao);
  216.                 }else{
  217.                         write_1602data(fuhao);
  218.                         write_1602data(shi);
  219.                 }
  220.         }
  221.         write_1602data(ge);
  222.         write_1602data('.');
  223.         write_1602data(point);
  224.         write_1602data(0xdf);
  225.         write_1602data('C');
  226. }
  227. void display_alarm(uchar add,int dat){
  228.         //把设定的时分显示出来
  229.         int x,y;
  230.         x=dat/10;
  231.         y=dat%10;
  232.         write_1602com(add);
  233.         write_1602data(int_to_char(x));
  234.         write_1602com(add+1);//防止写后地址自动向后加一  光标闪烁看不到
  235.         write_1602data(int_to_char(y));
  236.         write_1602com(add+1);
  237. }
  238. void init_alarm(){
  239.         //闹钟设置界面  只有首次进入才执行
  240.         uchar code x[]="SET ALARM";
  241.         uchar i;
  242.         if(alarm==0){
  243.                 write_1602com(0x01);//清屏
  244.                 write_1602com(0x80+3);//设置数据指针
  245.                 for(i=0;i<9;i++){
  246.                         write_1602data(x[i]);
  247.                 }
  248.                 display_alarm(0x80+0x40+5,shi);//载入闹钟的时分
  249.                 write_1602com(0x80+0x40+7);
  250.                 write_1602data(':');
  251.                 display_alarm(0x80+0x40+8,fen);
  252.                 if(isOpen){//初始化的时候如果已经设定闹钟则显示ON
  253.                         write_1602com(0x80+0x40+13);
  254.                         write_1602data(' ');
  255.                         write_1602data('O');
  256.                         write_1602data('N');
  257.                 }else{
  258.                         write_1602com(0x80+0x40+13);
  259.                         write_1602data('O');
  260.                         write_1602data('F');
  261.                         write_1602data('F');
  262.                 }
  263.         }
  264. }
  265. void key_scan(){
  266.         int i;
  267.         uchar code tips1[]="SET SUCCESS";//闹钟设置成功的提示
  268.         uchar code tips2[]="CANCEL SUCCESS";//取消闹钟的提示
  269.         if(key_set_time==0){//检测是否按下
  270.                 delay(10);//消抖
  271.                 if(key_set_time==0){//再次检测是否按下
  272.                         while(!key_set_time);//检测是否松开
  273.                         delay(10);//延时消抖
  274.                         while(!key_set_time);//再次检测是否松开
  275.                         if(alarm==0){//当没有显示闹钟界面时才显示时间设定
  276.                                 count++;
  277.                                 write_ds1302(0x80,0x80);//让时钟停止
  278.                                 if(count==8){
  279.                                         //继续走时,说明时间已经设定好了
  280.                                         write_1602com(0x0c);//让光标消失
  281.                                         write_ds1302(0x80,0);//让时钟继续
  282.                                         set_time(getTimebuf);//写入新的时间
  283.                                         count=0;
  284.                                         return;
  285.                                 }
  286.                                 switch(count){
  287.                                         case 1:
  288.                                                 write_1602com(0x80+0x40+7);//在秒的位置
  289.                                                 break;
  290.                                         case 2:
  291.                                                 write_1602com(0x80+0x40+4);//在分的位置
  292.                                                 break;
  293.                                         case 3:
  294.                                                 write_1602com(0x80+0x40+1);//在时的位置
  295.                                                 break;
  296.                                         case 4:
  297.                                                 write_1602com(0x80+14);//在星期的位置
  298.                                                 break;
  299.                                         case 5:
  300.                                                 write_1602com(0x80+10);//在日的位置
  301.                                                 break;
  302.                                         case 6:
  303.                                                 write_1602com(0x80+7);//在月的位置
  304.                                                 break;
  305.                                         case 7:
  306.                                                 write_1602com(0x80+4);//在年的位置
  307.                                                 break;
  308.                                 }
  309.                                 write_1602com(0x0f);//让光标闪烁
  310.                         }
  311.                 }
  312.         }
  313.         if(key_add==0){//检测是否按下
  314.                 delay(10);//消抖
  315.                 if(key_add==0){//再次检测是否按下
  316.                         while(!key_add);//检测是否松开
  317.                         delay(10);//延时消抖
  318.                         while(!key_add);//再次检测是否松开
  319.                         if(count!=0){
  320.                                 switch(count){
  321.                                 case 1:
  322.                                         //在秒的位置
  323.                                         getTimebuf[0]++;
  324.                                         if(getTimebuf[0]==0x5a){
  325.                                                 getTimebuf[0]=0;
  326.                                         }
  327.                                         if(getTimebuf[0]==0x4a){
  328.                                                 getTimebuf[0]=0x50;
  329.                                         }
  330.                                         if(getTimebuf[0]==0x3a){
  331.                                                 getTimebuf[0]=0x40;
  332.                                         }
  333.                                         if(getTimebuf[0]==0x2a){
  334.                                                 getTimebuf[0]=0x30;
  335.                                         }
  336.                                         if(getTimebuf[0]==0x1a){
  337.                                                 getTimebuf[0]=0x20;
  338.                                         }
  339.                                         if(getTimebuf[0]==0x0a){
  340.                                                 getTimebuf[0]=0x10;
  341.                                         }
  342.                                         time[6]=(getTimebuf[0])/16+48;//格式化时间秒
  343.                                         time[7]=(getTimebuf[0])%16+48;
  344.                                         write_1602com(0x80+0x40+6);//在秒的位置
  345.                                         write_1602data(time[6]);
  346.                                         write_1602com(0x80+0x40+7);//在秒的位置
  347.                                         write_1602data(time[7]);
  348.                                         write_1602com(0x80+0x40+7);//让光标在秒的位置闪烁
  349.                                         break;
  350.                                 case 2:
  351.                                         //在分的位置
  352.                                         getTimebuf[1]++;
  353.                                         if(getTimebuf[1]==0x5a){
  354.                                                 getTimebuf[1]=0;
  355.                                         }
  356.                                         if(getTimebuf[1]==0x4a){
  357.                                                 getTimebuf[1]=0x50;
  358.                                         }
  359.                                         if(getTimebuf[1]==0x3a){
  360.                                                 getTimebuf[1]=0x40;
  361.                                         }
  362.                                         if(getTimebuf[1]==0x2a){
  363.                                                 getTimebuf[1]=0x30;
  364.                                         }
  365.                                         if(getTimebuf[1]==0x1a){
  366.                                                 getTimebuf[1]=0x20;
  367.                                         }
  368.                                         if(getTimebuf[1]==0x0a){
  369.                                                 getTimebuf[1]=0x10;
  370.                                         }
  371.                                         time[3]=(getTimebuf[1])/16+48;//格式化时间分
  372.                                         time[4]=(getTimebuf[1])%16+48;
  373.                                         write_1602com(0x80+0x40+3);//在分的位置
  374.                                         write_1602data(time[3]);
  375.                                         write_1602com(0x80+0x40+4);//在分的位置
  376.                                         write_1602data(time[4]);
  377.                                         write_1602com(0x80+0x40+4);//让光标在分的位置闪烁
  378.                                         break;
  379.                                 case 3:
  380.                                         //在时的位置
  381.                                         getTimebuf[2]++;
  382.                                         if(getTimebuf[2]==0x24){
  383.                                                 getTimebuf[2]=0;
  384.                                         }
  385.                                         if(getTimebuf[2]==0x1a){
  386.                                                 getTimebuf[2]=0x20;
  387.                                         }
  388.                                         if(getTimebuf[2]==0x0a){
  389.                                                 getTimebuf[2]=0x10;
  390.                                         }
  391.                                         time[0]=(getTimebuf[2])/16+48;//格式化时间小时
  392.                                         time[1]=(getTimebuf[2])%16+48;
  393.                                         write_1602com(0x80+0x40+0);//在小时的位置
  394.                                         write_1602data(time[0]);
  395.                                         write_1602com(0x80+0x40+1);
  396.                                         write_1602data(time[1]);
  397.                                         write_1602com(0x80+0x40+1);
  398.                                         break;
  399.                                 case 4:
  400.                                         //在星期的位置
  401.                                         getTimebuf[5]++;
  402.                                         if(getTimebuf[5]==0x08){
  403.                                                 getTimebuf[5]=0x01;
  404.                                         }
  405.                                         if((getTimebuf[5]%10)*3==21){//轮完了  重新开始
  406.                                                 week[0]=weeklist[0];
  407.                                                 week[1]=weeklist[1];
  408.                                                 week[2]=weeklist[2];
  409.                                         }else{
  410.                                                 week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期
  411.                                                 week[1]=weeklist[(getTimebuf[5]%10)*3+1];
  412.                                                 week[2]=weeklist[(getTimebuf[5]%10)*3+2];
  413.                                         }
  414.                                         write_1602com(0x80+12);
  415.                                         write_1602data(week[0]);
  416.                                         write_1602com(0x80+13);
  417.                                         write_1602data(week[1]);
  418.                                         write_1602com(0x80+14);
  419.                                         write_1602data(week[2]);
  420.                                         write_1602com(0x80+14);
  421.                                         break;
  422.                                 case 5:
  423.                                         //在日的位置
  424.                                         getTimebuf[3]++;
  425.                                         if(getTimebuf[3]==0x32){
  426.                                                 getTimebuf[3]=0x01;
  427.                                         }
  428.                                         if(getTimebuf[3]==0x2a){
  429.                                                 getTimebuf[3]=0x30;
  430.                                         }
  431.                                         if(getTimebuf[3]==0x1a){
  432.                                                 getTimebuf[3]=0x20;
  433.                                         }
  434.                                         if(getTimebuf[3]==0x0a){
  435.                                                 getTimebuf[3]=0x10;
  436.                                         }
  437.                                         date[8]=(getTimebuf[3])/16+48;
  438.                                         date[9]=(getTimebuf[3])%16+48;
  439.                                         write_1602com(0x80+9);
  440.                                         write_1602data(date[8]);
  441.                                         write_1602com(0x80+10);
  442.                                         write_1602data(date[9]);
  443.                                         write_1602com(0x80+10);
  444.                                         break;
  445.                                 case 6:
  446.                                         //在月的位置
  447.                                         getTimebuf[4]++;
  448.                                         if(getTimebuf[4]==0x13){
  449.                                                 getTimebuf[4]=0x01;
  450.                                         }
  451.                                         if(getTimebuf[4]==0x0a){
  452.                                                 getTimebuf[4]=0x10;
  453.                                         }
  454.                                         date[5]=(getTimebuf[4])/16+48;
  455.                                         date[6]=(getTimebuf[4])%16+48;
  456.                                         write_1602com(0x80+6);
  457.                                         write_1602data(date[5]);
  458.                                         write_1602com(0x80+7);
  459.                                         write_1602data(date[6]);
  460.                                         write_1602com(0x80+7);
  461.                                         break;
  462.                                 case 7:
  463.                                         //在年的位置
  464.                                         getTimebuf[6]++;
  465.                                         if(getTimebuf[6]==0x9a){
  466.                                                 getTimebuf[6]=0x00;
  467.                                         }
  468.                                         if(getTimebuf[6]==0x8a){
  469.                                                 getTimebuf[6]=0x90;
  470.                                         }
  471.                                         if(getTimebuf[6]==0x7a){
  472.                                                 getTimebuf[6]=0x80;
  473.                                         }
  474.                                         if(getTimebuf[6]==0x6a){
  475.                                                 getTimebuf[6]=0x70;
  476.                                         }
  477.                                         if(getTimebuf[6]==0x5a){
  478.                                                 getTimebuf[6]=0x60;
  479.                                         }
  480.                                         if(getTimebuf[6]==0x4a){
  481.                                                 getTimebuf[6]=0x50;
  482.                                         }
  483.                                         if(getTimebuf[6]==0x3a){
  484.                                                 getTimebuf[6]=0x40;
  485.                                         }
  486.                                         if(getTimebuf[6]==0x2a){
  487.                                                 getTimebuf[6]=0x30;
  488.                                         }
  489.                                         if(getTimebuf[6]==0x1a){
  490.                                                 getTimebuf[6]=0x20;
  491.                                         }
  492.                                         if(getTimebuf[6]==0x0a){
  493.                                                 getTimebuf[6]=0x10;
  494.                                         }
  495.                                         date[2]=(getTimebuf[6])/16+48;
  496.                                         date[3]=(getTimebuf[6])%16+48;
  497.                                         write_1602com(0x80+3);
  498.                                         write_1602data(date[2]);
  499.                                         write_1602com(0x80+4);
  500.                                         write_1602data(date[3]);
  501.                                         write_1602com(0x80+4);
  502.                                         break;
  503.                                 }
  504.                         }
  505.                         if(alarm!=0){
  506.                                 switch(alarm){
  507.                                         case 1:
  508.                                                 //调节闹钟的开与关
  509.                                                 if(isOpen==0){
  510.                                                         isOpen=1;
  511.                                                         write_1602com(0x80+0x40+13);
  512.                                                         write_1602data(' ');
  513.                                                         write_1602data('O');
  514.                                                         write_1602data('N');
  515.                                                 }else{
  516.                                                         isOpen=0;
  517.                                                         write_1602com(0x80+0x40+13);
  518.                                                         write_1602data('O');
  519.                                                         write_1602data('F');
  520.                                                         write_1602data('F');
  521.                                                 }
  522.                                                 //防止写后地址自动向后加一  光标闪烁看不到
  523.                                                 write_1602com(0x80+0x40+15);
  524.                                                 break;
  525.                                         case 2:
  526.                                                 //调节闹钟的分
  527.                                                 fen++;
  528.                                                 if(fen==60){
  529.                                                         fen=0;
  530.                                                 }
  531.                                                 display_alarm(0x80+0x40+8,fen);
  532.                                                 break;
  533.                                         case 3:
  534.                                                 //调节闹钟的小时
  535.                                                 shi++;
  536.                                                 if(shi==24){
  537.                                                         shi=0;
  538.                                                 }
  539.                                                 display_alarm(0x80+0x40+5,shi);
  540.                                                 break;
  541.                                 }
  542.                         }
  543.                 }
  544.         }
  545.         if(key_minus==0){//检测是否按下
  546.                 delay(10);//消抖
  547.                 if(key_minus==0){//再次检测是否按下
  548.                         while(!key_minus);//检测是否松开
  549.                         delay(10);//延时消抖
  550.                         while(!key_minus);//再次检测是否松开
  551.                         if(count!=0){
  552.                                 switch(count){
  553.                                 case 1:
  554.                                         //在秒的位置
  555.                                         getTimebuf[0]--;
  556.                                         if(getTimebuf[0]==0xff){
  557.                                                 getTimebuf[0]=0x59;
  558.                                         }
  559.                                         if(getTimebuf[0]==0x4f){
  560.                                                 getTimebuf[0]=0x49;
  561.                                         }
  562.                                         if(getTimebuf[0]==0x3f){
  563.                                                 getTimebuf[0]=0x39;
  564.                                         }
  565.                                         if(getTimebuf[0]==0x2f){
  566.                                                 getTimebuf[0]=0x29;
  567.                                         }
  568.                                         if(getTimebuf[0]==0x1f){
  569.                                                 getTimebuf[0]=0x19;
  570.                                         }
  571.                                         if(getTimebuf[0]==0x0f){
  572.                                                 getTimebuf[0]=0x09;
  573.                                         }
  574.                                         time[6]=(getTimebuf[0])/16+48;//格式化时间秒
  575.                                         time[7]=(getTimebuf[0])%16+48;
  576.                                         write_1602com(0x80+0x40+6);//在秒的位置
  577.                                         write_1602data(time[6]);
  578.                                         write_1602com(0x80+0x40+7);//在秒的位置
  579.                                         write_1602data(time[7]);
  580.                                         write_1602com(0x80+0x40+7);//让光标在秒的位置闪烁
  581.                                         break;
  582.                                 case 2:
  583.                                         //在分的位置
  584.                                         getTimebuf[1]--;
  585.                                         if(getTimebuf[1]==0xff){
  586.                                                 getTimebuf[1]=0x59;
  587.                                         }
  588.                                         if(getTimebuf[1]==0x4f){
  589.                                                 getTimebuf[1]=0x49;
  590.                                         }
  591.                                         if(getTimebuf[1]==0x3f){
  592.                                                 getTimebuf[1]=0x39;
  593.                                         }
  594.                                         if(getTimebuf[1]==0x2f){
  595.                                                 getTimebuf[1]=0x29;
  596.                                         }
  597.                                         if(getTimebuf[1]==0x1f){
  598.                                                 getTimebuf[1]=0x19;
  599.                                         }
  600.                                         if(getTimebuf[1]==0x0f){
  601.                                                 getTimebuf[1]=0x09;
  602.                                         }
  603.                                         time[3]=(getTimebuf[1])/16+48;//格式化时间分
  604.                                         time[4]=(getTimebuf[1])%16+48;
  605.                                         write_1602com(0x80+0x40+3);//在分的位置
  606.                                         write_1602data(time[3]);
  607.                                         write_1602com(0x80+0x40+4);//在分的位置
  608.                                         write_1602data(time[4]);
  609.                                         write_1602com(0x80+0x40+4);//让光标在分的位置闪烁
  610.                                         break;
  611.                                 case 3:
  612.                                         //在时的位置
  613.                                         getTimebuf[2]--;
  614.                                         if(getTimebuf[2]==0xff){
  615.                                                 getTimebuf[2]=0x23;
  616.                                         }
  617.                                         if(getTimebuf[2]==0x1f){
  618.                                                 getTimebuf[2]=0x19;
  619.                                         }
  620.                                         if(getTimebuf[2]==0x0f){
  621.                                                 getTimebuf[2]=0x09;
  622.                                         }
  623.                                         time[0]=(getTimebuf[2])/16+48;//格式化时间小时
  624.                                         time[1]=(getTimebuf[2])%16+48;
  625.                                         write_1602com(0x80+0x40+0);//在小时的位置
  626.                                         write_1602data(time[0]);
  627.                                         write_1602com(0x80+0x40+1);
  628.                                         write_1602data(time[1]);
  629.                                         write_1602com(0x80+0x40+1);
  630.                                         break;
  631.                                 case 4:
  632.                                         //在星期的位置
  633.                                         getTimebuf[5]--;
  634.                                         if(getTimebuf[5]==0){
  635.                                                 getTimebuf[5]=0x07;
  636.                                         }
  637.                                         if((getTimebuf[5]%10)*3==21){//轮完了  重新开始
  638.                                                 week[0]=weeklist[0];
  639.                                                 week[1]=weeklist[1];
  640.                                                 week[2]=weeklist[2];
  641.                                         }else{
  642.                                                 week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期
  643.                                                 week[1]=weeklist[(getTimebuf[5]%10)*3+1];
  644.                                                 week[2]=weeklist[(getTimebuf[5]%10)*3+2];
  645.                                         }
  646.                                         write_1602com(0x80+12);
  647.                                         write_1602data(week[0]);
  648.                                         write_1602com(0x80+13);
  649.                                         write_1602data(week[1]);
  650.                                         write_1602com(0x80+14);
  651.                                         write_1602data(week[2]);
  652.                                         write_1602com(0x80+14);
  653.                                         break;
  654.                                 case 5:
  655.                                         //在日的位置
  656.                                         getTimebuf[3]--;
  657.                                         if(getTimebuf[3]==0){
  658.                                                 getTimebuf[3]=0x31;
  659.                                         }
  660.                                         if(getTimebuf[3]==0x2f){
  661.                                                 getTimebuf[3]=0x29;
  662.                                         }
  663.                                         if(getTimebuf[3]==0x1f){
  664.                                                 getTimebuf[3]=0x19;
  665.                                         }
  666.                                         if(getTimebuf[3]==0x0f){
  667.                                                 getTimebuf[3]=0x09;
  668.                                         }
  669.                                         date[8]=(getTimebuf[3])/16+48;
  670.                                         date[9]=(getTimebuf[3])%16+48;
  671.                                         write_1602com(0x80+9);
  672.                                         write_1602data(date[8]);
  673.                                         write_1602com(0x80+10);
  674.                                         write_1602data(date[9]);
  675.                                         write_1602com(0x80+10);
  676.                                         break;
  677.                                 case 6:
  678.                                         //在月的位置
  679.                                         getTimebuf[4]--;
  680.                                         if(getTimebuf[4]==0){
  681.                                                 getTimebuf[4]=0x12;
  682.                                         }
  683.                                         if(getTimebuf[4]==0x0f){
  684.                                                 getTimebuf[4]=0x09;
  685.                                         }
  686.                                         date[5]=(getTimebuf[4])/16+48;
  687.                                         date[6]=(getTimebuf[4])%16+48;
  688.                                         write_1602com(0x80+6);
  689.                                         write_1602data(date[5]);
  690.                                         write_1602com(0x80+7);
  691.                                         write_1602data(date[6]);
  692.                                         write_1602com(0x80+7);
  693.                                         break;
  694.                                 case 7:
  695.                                         //在年的位置
  696.                                         getTimebuf[6]--;
  697.                                         if(getTimebuf[6]==0xff){
  698.                                                 getTimebuf[6]=0x99;
  699.                                         }
  700.                                         if(getTimebuf[6]==0x8f){
  701.                                                 getTimebuf[6]=0x89;
  702.                                         }
  703.                                         if(getTimebuf[6]==0x7f){
  704.                                                 getTimebuf[6]=0x79;
  705.                                         }
  706.                                         if(getTimebuf[6]==0x6f){
  707.                                                 getTimebuf[6]=0x69;
  708.                                         }
  709.                                         if(getTimebuf[6]==0x5f){
  710.                                                 getTimebuf[6]=0x59;
  711.                                         }
  712.                                         if(getTimebuf[6]==0x4f){
  713.                                                 getTimebuf[6]=0x49;
  714.                                         }
  715.                                         if(getTimebuf[6]==0x3f){
  716.                                                 getTimebuf[6]=0x39;
  717.                                         }
  718.                                         if(getTimebuf[6]==0x2f){
  719.                                                 getTimebuf[6]=0x29;
  720.                                         }
  721.                                         if(getTimebuf[6]==0x1f){
  722.                                                 getTimebuf[6]=0x19;
  723.                                         }
  724.                                         if(getTimebuf[6]==0x0f){
  725.                                                 getTimebuf[6]=0x09;
  726.                                         }
  727.                                         date[2]=(getTimebuf[6])/16+48;
  728.                                         date[3]=(getTimebuf[6])%16+48;
  729.                                         write_1602com(0x80+3);
  730.                                         write_1602data(date[2]);
  731.                                         write_1602com(0x80+4);
  732.                                         write_1602data(date[3]);
  733.                                         write_1602com(0x80+4);
  734.                                         break;
  735.                                 }
  736.                         }
  737.                         if(alarm!=0){
  738.                                 switch(alarm){
  739.                                         case 1:
  740.                                                 //调节闹钟的开与关
  741.                                                 if(isOpen==0){
  742.                                                         isOpen=1;
  743.                                                         write_1602com(0x80+0x40+13);
  744.                                                         write_1602data(' ');
  745.                                                         write_1602data('O');
  746.                                                         write_1602data('N');
  747.                                                 }else{
  748.                                                         isOpen=0;
  749.                                                         write_1602com(0x80+0x40+13);
  750.                                                         write_1602data('O');
  751.                                                         write_1602data('F');
  752.                                                         write_1602data('F');
  753.                                                 }
  754.                                                 //防止写后地址自动向后加一  光标闪烁看不到
  755.                                                 write_1602com(0x80+0x40+15);
  756.                                                 break;
  757.                                         case 2:
  758.                                                 //调节闹钟的分
  759.                                                 fen--;
  760.                                                 if(fen<0){
  761.                                                         fen=59;
  762.                                                 }
  763.                                                 display_alarm(0x80+0x40+8,fen);
  764.                                                 break;
  765.                                         case 3:
  766.                                                 //调节闹钟的小时
  767.                                                 shi--;
  768.                                                 if(shi<0){
  769.                                                         shi=23;
  770.                                                 }
  771.                                                 display_alarm(0x80+0x40+5,shi);
  772.                                                 break;
  773.                                 }
  774.                         }
  775.                 }
  776.         }
  777.         if(key_set_alarm==0){//检测是否按下
  778.                 delay(10);//消抖
  779.                 if(key_set_alarm==0){//再次检测是否按下
  780.                         while(!key_set_alarm);//检测是否松开
  781.                         delay(10);//延时消抖
  782.                         while(!key_set_alarm);//再次检测是否松开
  783.                         if(count==0){//时间在正常走动的时候才能设置闹钟
  784.                                 init_alarm();
  785.                                 alarm++;//说明进入闹钟设置界面
  786.                                 if(alarm==4){
  787.                                         alarm=0;//说明闹钟设置完毕
  788.                                         write_1602com(0x01);//清屏以便显示时间
  789.                                         write_1602com(0x0c);//关闭光标
  790.                                         //显示设置成功或取消的提示
  791.                                         if(isOpen){
  792.                                                 write_1602com(0x80+2);
  793.                                                 for(i=0;i<11;i++){
  794.                                                         write_1602data(tips1[i]);
  795.                                                 }
  796.                                         }else{
  797.                                                 write_1602com(0x80+1);
  798.                                                 for(i=0;i<14;i++){
  799.                                                         write_1602data(tips2[i]);
  800.                                                 }
  801.                                         }
  802.                                         //延时2ms后清屏显示时间
  803.                                         delay(2000);
  804.                                         write_1602com(0x01);
  805.                                 }else{
  806.                                         switch(alarm){
  807.                                                 case 1:
  808.                                                         write_1602com(0x80+0x40+15);
  809.                                                         break;
  810.                                                 case 2:
  811.                                                         write_1602com(0x80+0x40+9);
  812.                                                         break;
  813.                                                 case 3:
  814.                                                         write_1602com(0x80+0x40+6);
  815.                                                         break;
  816.                                         }
  817.                                         write_1602com(0x0f);
  818.                                 }
  819.                         }
  820.                 }
  821.         }
  822. }
  823. void beep(){
  824.         //检测闹钟  并且报警
  825.         if(time[0]==int_to_char(shi/10)&&time[1]==int_to_char(shi%10)&&time[3]==int_to_char(fen/10)&&time[4]==int_to_char(fen%10)){
  826.                 isRing=1;//闹钟响起,此时如果进入闹钟设置界面 改变时分,闹钟就关闭了
  827.                 bee=0;
  828.                 delay(250);
  829.                 bee=1;
  830.                 delay(250);
  831.         }else{
  832.                 isRing=0;//关闭闹钟或者一分钟后闹钟自动关闭
  833.                 bee=1;
  834.         }
  835. }
  836. void delay1(int i){
  837.         while(i--);
  838. }
  839. void ds18b20_init(){
  840.         uchar x=0;
  841.         dq = 1;    //DQ复位
  842.         delay1(8);  //稍做延时
  843.         dq = 0;    //单片机将DQ拉低
  844.         delay1(80); //精确延时 大于 480us
  845.         dq = 1;    //拉高总线
  846.         delay1(14);
  847.         x=dq;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  848.         delay1(20);
  849. }
  850. uchar ds18b20_read(){
  851.         //读一个字节
  852.         uchar i=0;
  853.         uchar dat = 0;
  854.         for (i=8;i>0;i--)
  855.         {
  856.                 dq = 0; // 给脉冲信号
  857.                 dat>>=1;
  858.                 dq = 1; // 给脉冲信号
  859.                 if(dq)
  860.                         dat|=0x80;
  861.                 delay1(4);
  862.         }
  863.         return(dat);
  864. }
  865. void ds18b20_write(char dat){
  866.         //写一个字节
  867.         uchar i=0;
  868.         for (i=8; i>0; i--)
  869.         {
  870.                 dq = 0;
  871.                 dq = dat&0x01;
  872.                 delay1(5);
  873.                 dq = 1;
  874.                 dat>>=1;
  875.         }
  876. }
  877. int ds18b20_read_temp(){
  878.         //读取温度
  879.         uchar low;
  880.         uchar high;
  881.         unsigned long tmp;
  882.         float value;
  883.         int t;//温度
  884.         ds18b20_init();
  885.         ds18b20_write(0xCC); //跳过读序列号的操作
  886.         ds18b20_write(0x44); //启动温度转换
  887.         ds18b20_init();
  888.         ds18b20_write(0xCC); //跳过读序列号的操作
  889.         ds18b20_write(0xBE); //读取温度寄存器  共九个  前两个代表温度
  890.         low=ds18b20_read();//低八位数据
  891.         high=ds18b20_read();//高八位数据

  892.         tmp=high;
  893.         tmp<<=8;
  894.         tmp=tmp|low;
  895.         //此处有正负之分
  896.         if(tmp>=63488){//ffff f000 0000 0000-->(f800)
  897.                 temp_flag=0;
  898.                 //8位全为1时,加1才进位
  899.                 if((~low)==0xff){//判断low取反加1之后是否进位
  900.                         high=(~high)+1;
  901.                         low=0;
  902.                 }else{
  903.                         high=~high;
  904.                         low=(~low)+1;
  905.                 }
  906.                 tmp=high*256+low;
  907.         }else{
  908.                 temp_flag=1;
  909.         }
  910.         value=tmp*0.0625;
  911.         t=value*10+((temp_flag==1)?+0.5:-0.5);//放大十倍输出并四舍五入
  912.         return t;
  913. }
  914. void main(){
  915.         init_1602();
  916.         init_ds1302();
  917.         while(1){
  918.                 if(isOpen){//只有开启闹钟的时候才检测
  919.                         beep();//不断检测闹钟
  920.                 }
  921.                 key_scan();
  922.                 if(count==0&&alarm==0){//没有设定时间  也没有在闹钟界面的时候时间才显示
  923.                         display();
  924.                 }
  925.         }
  926. }

复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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