找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1454|回复: 0
收起左侧

51单片机通过18b20在数码管显示温度和时间程序,按键设置闹钟

[复制链接]
ID:661526 发表于 2022-1-26 11:40 | 显示全部楼层 |阅读模式
  1. #include "reg52.h"

  2. unsigned int hour = 2, min = 2, sec = 3;       //设置时间初值
  3. unsigned int ahour = 0, amin = 0, asec = 0;    //设置闹钟初值

  4. sbit k1 = P3^1;    //修改时间
  5. sbit k2 = P3^0;   //设置闹钟
  6. sbit k3 = P3^2;        //加1
  7. sbit k4 = P3^3;        //减1

  8. sbit DSPORT=P3^7;


  9. sbit beep=P1^5;

  10. sbit LSA=P2^2;
  11. sbit LSB=P2^3;
  12. sbit LSC=P2^4;

  13. unsigned int keyvalue = 0;
  14. unsigned int settype = 0;      //0是初始状态正常显示,1是修改秒,2是修改分,3是修改时
  15. unsigned int alarmvalue = 0;   //0是初始状态,1是修改秒,2是修改分,3是修改时

  16. unsigned char Show[8] = {0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f};
  17. unsigned char code TableCC[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

  18. int b = 0;

  19. float tp=0;
  20. int temp=0;                                                        
  21. int c1=0;c2=0;

  22. void delay(unsigned char i)
  23. {
  24.         while(i--);        
  25. }               


  26. void delay_us(unsigned char t)
  27. {
  28.     while(--t);
  29. }

  30. void delay_ms(unsigned int t)   //t最大为255
  31. {
  32.     while(t--)
  33.     {
  34.         delay_us(245);
  35.         delay_us(245);
  36.     }
  37. }




  38. unsigned char Ds18b20Init()        //Ds18b20Init初始化         
  39. {
  40.         unsigned int i;
  41.         DSPORT=0;                         //将总线拉低480us~960us
  42.         i=70;                                                                                            
  43.         while(i--);//延时642us
  44.         DSPORT=1;                        //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
  45.         i=0;
  46.         while(DSPORT)        //等待DS18B20拉低总线
  47.         {
  48.                 i++;
  49.                 if(i>5000)//等待>5MS
  50.                         return 0;//初始化失败        
  51.         }
  52.         return 1;//初始化成功
  53. }



  54. void Ds18b20WriteByte(unsigned char dat)  //Ds18b20WriteByte  向18B20写入一个字节
  55. {
  56.         unsigned int i,j;
  57.         for(j=0;j<8;j++)
  58.         {
  59.                 DSPORT=0;                        //每写入一位数据之前先把总线拉低1us
  60.                 i++;
  61.                 DSPORT=dat&0x01; //然后写入一个数据,从最低位开始
  62.                 i=6;
  63.                 while(i--); //延时68us,持续时间最少60us
  64.                 DSPORT=1;        //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
  65.                 dat>>=1;
  66.         }
  67. }



  68. unsigned char Ds18b20ReadByte()        //向18B20读取一个字节
  69. {
  70.         unsigned char byte,bi;
  71.         unsigned int i,j;        
  72.         for(j=8;j>0;j--)
  73.         {
  74.                 DSPORT=0;//先将总线拉低1us
  75.                 i++;
  76.                 DSPORT=1;//然后释放总线
  77.                 i++;
  78.                 i++;//延时6us等待数据稳定
  79.                 bi=DSPORT;         //读取数据,从最低位开始读取
  80.                 /*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
  81.                 byte=(byte>>1)|(bi<<7);                                                  
  82.                 i=4;                //读取完之后等待48us再接着读取下一个数
  83.                 while(i--);
  84.         }                                
  85.         return byte;
  86. }


  87. void  Ds18b20ChangTemp()  //让18B20转换温度
  88. {
  89.         Ds18b20Init();
  90.         delay_ms(1);
  91.         Ds18b20WriteByte(0xcc);                //跳过ROM操作命令                 
  92.         Ds18b20WriteByte(0x44);            //温度转换命令

  93. }


  94. void  Ds18b20ReadTempCom()           //让18B20 读取温度
  95. {        

  96.         Ds18b20Init();
  97.         delay_ms(1);
  98.         Ds18b20WriteByte(0xcc);         //跳过ROM操作命令
  99.         Ds18b20WriteByte(0xbe);         //发送读取温度命令
  100. }


  101. int Ds18b20ReadTemp()        //读取温度返回数值
  102. {
  103.         int temp=0;
  104.         unsigned char tmh,tml;
  105.         Ds18b20ChangTemp();                                 //先写入转换命令
  106.         Ds18b20ReadTempCom();                        //然后等待转换完后发送读取温度命令
  107.         tml=Ds18b20ReadByte();                //读取温度值共16位,先读低字节
  108.         tmh=Ds18b20ReadByte();                //再读高字节
  109.         temp=tmh;
  110.         temp<<=8;
  111.         temp|=tml;
  112.         return temp;
  113. }

  114. void wendu_shuji()
  115. {
  116.         temp=Ds18b20ReadTemp();
  117.         tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
  118.         temp=tp*0.0625*100+0.5;
  119.         c1 = temp % 10000 / 1000;
  120.         c2 = temp % 1000 / 100;
  121.         Show[7]=TableCC[c1];
  122.         Show[6]=TableCC[c2];               
  123. }

  124. void Timer0_Init()                 //定时器初始化
  125. {
  126.     TMOD |= 0x01; //选择为定时器0模式,工作方式1,仅用TR0打开启动。
  127.     TH0 =(65536 - 50000)/256;         //给定时器赋初值
  128.     TL0 =(65536 - 50000)%256;
  129.            TR0=1;//打开定时器        
  130.         ET0=1;//打开定时器0中断允许
  131.         EA=1;//打开总中断
  132. }



  133. void TimeTim()           //时钟正常走
  134. {
  135.      if(settype == 0 && alarmvalue == 0)     //当不在闹钟状态也不在修改时间状态的时候时间正常走
  136.      {
  137.          if(b>=20)
  138.          {
  139.             b=0;
  140.             sec++;
  141.             if(sec == 60)
  142.             {
  143.                 sec = 0;
  144.                 min++;
  145.                 if(min == 60)
  146.                 {
  147.                     min = 0;
  148.                     hour++;
  149.                     if(hour == 24)
  150.                     {
  151.                         hour = 0;
  152.                     }
  153.                 }
  154.             }
  155.          }
  156.     }
  157. }

  158. void bsp_CheckAlarm(void)        //检查时间是否到了闹钟时间
  159. {
  160.         unsigned char a=0;
  161.     if((hour == ahour) && (min == amin) && (sec == asec))
  162.     {
  163.                 while(1)
  164.                 {
  165.                 beep=~beep;
  166.                         delay_us(100);
  167.                         if(k1 == 0)//K1按键被按下
  168.                     {
  169.                                 delay(1000);
  170.                                 if(k1 == 0)
  171.                                 {         
  172.                                         beep=0;
  173.                                         a=1;
  174.                                 }  
  175.                                 while(!k1);//等待按键释放               
  176.                     }   
  177.                          if(a == 1)
  178.                         {
  179.                                  break;
  180.                         }
  181.                 }        
  182.     }
  183. }                              
  184.         


  185. void bsp_KeyScan(void)           //扫描键盘那个键被按下
  186. {
  187.     if(k1 == 0)//K1按键被按下
  188.     {
  189.                 delay(1000);
  190.                 if(k1==0)
  191.                 {                        
  192.                 keyvalue = 1;
  193.                 }
  194.         while(!k1);//等待按键释放

  195.     }

  196.     if(k2 == 0)
  197.     {
  198.                 delay(1000);
  199.                 if(k2==0)
  200.                 {
  201.                 keyvalue = 2;
  202.              }   
  203.                  while(!k2);        
  204.     }

  205.     if(k3 == 0)
  206.     {
  207.                 delay(1000);
  208.                 if(k3==0)
  209.                 {
  210.                 keyvalue = 3;
  211.                 }
  212.         while(!k3);
  213.     }

  214.     if(k4 == 0)
  215.     {
  216.                 delay(1000);
  217.                 if(k4==0)
  218.                 {
  219.                 keyvalue = 4;
  220.                 }
  221.         while(!k4);
  222.     }
  223. }


  224. void timeadd()    //时间加1
  225. {
  226.     if(settype == 1)
  227.     {
  228.         if(sec < 59)
  229.         {
  230.             sec++;
  231.         }

  232.         else
  233.         {
  234.             sec = 0;
  235.         }
  236.     }

  237.     else if(settype == 2)
  238.     {
  239.         if(min < 59)
  240.         {
  241.             min++;
  242.         }

  243.         else
  244.         {
  245.             min = 0;
  246.         }
  247.     }

  248.     else if(settype == 3)
  249.     {
  250.         if(hour < 23)
  251.         {
  252.             hour++;
  253.         }

  254.         else
  255.         {
  256.             hour = 0;
  257.         }
  258.     }


  259.     if(alarmvalue == 1)           //设置闹钟加1
  260.     {
  261.         if(asec < 59)
  262.         {
  263.             asec++;
  264.         }

  265.         else
  266.         {
  267.             asec = 0;
  268.         }
  269.     }

  270.     else if(alarmvalue == 2)
  271.     {
  272.         if(amin < 59)
  273.         {
  274.             amin++;
  275.         }

  276.         else
  277.         {
  278.             amin = 0;
  279.         }
  280.     }

  281.     else if(alarmvalue == 3)
  282.     {
  283.         if(ahour < 23)
  284.         {
  285.             ahour++;
  286.         }

  287.         else
  288.         {
  289.             ahour = 0;
  290.         }
  291.     }
  292. }




  293. void timedec()  //时间减一
  294. {

  295.     if(settype == 1)
  296.     {
  297.         if(sec > 0)
  298.         {
  299.             sec--;
  300.         }

  301.         else
  302.         {
  303.             sec = 59;
  304.         }
  305.     }

  306.     else if(settype == 2)
  307.     {
  308.         if(min > 0)
  309.         {
  310.             min--;
  311.         }

  312.         else
  313.         {
  314.             min = 59;
  315.         }
  316.     }

  317.     else if(settype == 3)
  318.     {
  319.         if(hour > 0)
  320.         {
  321.             hour--;
  322.         }

  323.         else
  324.         {
  325.             hour = 23;
  326.         }
  327.     }


  328.     if(alarmvalue == 1)                  //设置闹钟减1
  329.     {
  330.         if(asec > 0)
  331.         {
  332.             asec--;
  333.         }

  334.         else
  335.         {
  336.             asec = 59;
  337.         }
  338.     }

  339.     else if(alarmvalue == 2)
  340.     {
  341.         if(amin > 0)
  342.         {
  343.             amin--;
  344.         }

  345.         else
  346.         {
  347.             amin = 59;
  348.         }
  349.     }

  350.     else if(alarmvalue == 3)
  351.     {
  352.         if(ahour > 0)
  353.         {
  354.             ahour--;
  355.         }

  356.         else
  357.         {
  358.             ahour = 23;
  359.         }
  360.     }
  361. }

  362. void bsp_KeyProc(unsigned char keyv)
  363. {
  364.     if(keyv == 1)
  365.     {
  366.         settype++;
  367.         if(settype == 4)
  368.         {
  369.             settype = 0;
  370.         }
  371.         keyvalue = 0;    //键值要清0!!!
  372.     }

  373.     if(keyv == 2)
  374.     {
  375.         alarmvalue++;
  376.         if(alarmvalue == 4)
  377.         {
  378.             alarmvalue = 0;
  379.         }
  380.         keyvalue = 0;
  381.     }

  382.     if(keyv == 3)
  383.     {
  384.         timeadd();
  385.         keyvalue = 0;
  386.     }

  387.     if(keyv == 4)
  388.     {
  389.         timedec();
  390.         keyvalue = 0;
  391.     }
  392. }

  393. void SetValueShow(void)
  394. {
  395.     if(alarmvalue == 0) //当不在闹钟状态时数码管显示正常的时间
  396.     {
  397.         Show[5] = TableCC[hour/10];
  398.         if(settype == 3)
  399.                Show[4] = TableCC[hour%10] | 0x80;
  400.         else
  401.                Show[4] = TableCC[hour%10];
  402.         Show[3] = TableCC[min/10];
  403.         if(settype == 2)
  404.              Show[2] = TableCC[min%10] | 0x80;
  405.         else
  406.                Show[2] = TableCC[min%10];
  407.         Show[1] = TableCC[sec/10];
  408.         if(settype == 1)
  409.         Show[0] = TableCC[sec%10] | 0x80;
  410.         else
  411.         Show[0] = TableCC[sec%10];
  412.     }

  413.     //在闹钟状态数码管显示闹钟设置的时间
  414.     else
  415.     {
  416.         Show[5] = TableCC[ahour/10];
  417.         if(alarmvalue == 3)
  418.         Show[4] = TableCC[ahour%10] | 0x80;
  419.         else
  420.         Show[4] = TableCC[ahour%10];
  421.         Show[3] = TableCC[amin/10];
  422.         if(alarmvalue == 2)
  423.         Show[2] = TableCC[amin%10] | 0x80;
  424.         else
  425.         Show[2] = TableCC[amin%10];
  426.         Show[1] = TableCC[asec/10];
  427.         if(alarmvalue == 1)
  428.         Show[0] = TableCC[asec%10] | 0x80;
  429.         else
  430.         Show[0] = TableCC[asec%10];
  431.     }
  432. }   

  433. void DigDisplay()
  434. {
  435.         int i;
  436.         for(i=0;i<8;i++)
  437.         {
  438.                 switch(i)         //位选,选择点亮的数码管,
  439.                 {
  440.                         case(0):
  441.                                 LSA=0;LSB=0;LSC=0; break;//显示第0位
  442.                         case(1):
  443.                                 LSA=1;LSB=0;LSC=0; break;//显示第1位
  444.                         case(2):
  445.                                 LSA=0;LSB=1;LSC=0; break;//显示第2位
  446.                         case(3):
  447.                                 LSA=1;LSB=1;LSC=0; break;//显示第3位
  448.                         case(4):
  449.                                 LSA=0;LSB=0;LSC=1; break;//显示第4位
  450.                         case(5):
  451.                                 LSA=1;LSB=0;LSC=1; break;//显示第5位
  452.                         case(6):
  453.                                 LSA=0;LSB=1;LSC=1; break;//显示第6位
  454.                         case(7):
  455.                                 LSA=1;LSB=1;LSC=1; break;//显示第7位
  456.                                        
  457.                 }
  458.                 P0=Show[i];//发送段码
  459.                 delay(100); //间隔一段时间扫描        
  460.                 P0=0x00;//消隐
  461.         }
  462. }




  463. void main()
  464. {
  465.         k1=1;
  466.         k2=1;   
  467.          k3=1;        
  468.         k4=1;
  469.     Timer0_Init();         //计时器的初始化
  470.     while(1)
  471.     {
  472.                 wendu_shuji();         //温度
  473.         TimeTim();              //正常时间在走
  474.         bsp_KeyScan();          //键盘扫描看哪个功能键被按下
  475.         bsp_KeyProc(keyvalue);  //根据键值进行相应的功能处理
  476.         SetValueShow();         //数码管上显示的值
  477.         DigDisplay();            //显示在数码管上
  478.         bsp_CheckAlarm();       //闹钟检查
  479.     }   
  480. }
  481. void Timer0(void) interrupt 1        //定时器的中断服务程序
  482. {
  483.     TH0 = (65536 - 50000)/256;
  484.     TL0 = (65536 - 50000)%256;
  485.     b++;
  486. }
复制代码


Keil代码下载: 最终.rar (26.26 KB, 下载次数: 16)

评分

参与人数 1黑币 +10 收起 理由
admin + 10 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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