找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机LCD1602显示的温度控制系统设计 包括时间显示 校时、设置最值温度报警功能

[复制链接]
跳转到指定楼层
#
1、将DS18B20温度传感器的温度读出来,并在LCD1602上显示出来。
2、在LCD上分别切换显示,软件设计时钟(时、分、秒),和当前温度值,和温度上下控制值。并可以通过按键进行修改设置,温度高于上限,或下线都由蜂鸣器发出报警声。 T-LCD - 副本.rar (225.17 KB, 下载次数: 108)

3、实现校时、校分、校秒功能。
附件里附带所有程序、工程以及仿真图,仿真图为T-LCD2,程序工程为T-LCD,主程序是main.c
实验原理图:

单片机效果图:
模式0为显示温度 时间 模式123分别为调个位、十位、十分位 按对应的按键就能实现调最高或最低 模式45显示最高、最低温度

程序部分:
570行主程序+100温度传感器+70行1602显示 实现单片机温度时间显示 精确到十分位 并且有校时、设置最值温度报警功能 精确到十分位

具体的代码功能在附件程序里都有标注
  1. #include<reg52.h>  //调用52单片机库
  2. #include"1602.h"   //调用LCD1602库
  3. #include"ds18b20.h"   //调用ds18b20温度传感器
  4. #define uint unsigned int
  5. #define uchar unsigned char
  6. uchar hour,min,sec,count,hour1,hour2,  //定义小时 分钟 秒 对应的十位个位 以及 count计数
  7. sec1,sec2,min1,min2;

  8. sbit speaker=P2^1;                  //定义蜂鸣器
  9. sbit key1=P1^0;                          //最低温度设置
  10. sbit key2=P1^1;              //最高温度设置
  11. sbit key3=P1^2;       //连接切换模式的备用开关 P33和P12口短接 用于切换模式和退出报警中断


  12. sbit keyh=P1^5;  //校时
  13. sbit keym=P1^6;  //校分
  14. sbit keys=P1^7;  //校秒
  15. //定义时间按键

  16. uint  tem;                                  //定义采集温度
  17. int htem,htem2,time,time2,x,y,z,dot,dot2,maxtem,mintem;                          //定义温度十位数、个位数、小数,以及其三种模式的标记值
  18. int cnt1=1,cnt2=1,cnt3=1,cnt4=1,cnt5=1,cnt6=1,cnt7=1;                  //定义计数变量
  19. int i;
  20. uchar mode=0;                          //定义模式变量
  21. uchar code t3[]={"  H/L=0/1:     C"};    //显示调最值温度的十位
  22. uchar code t4[]={"O/D:           C"};    //显示调最值温度的个位/小数位字模
  23. uchar code table2[]={  
  24. '0','1','2','3','4','5','6','7','8','9',':'};   //显示时间的字模
  25. uchar code t5[]={"Max         . CD"};         //显示最高温度的字模
  26. uchar code t6[]={"Min         . CD"};         //显示最低温度的字模


  27. //延时函数
  28. void delay1(uint i)
  29. {
  30.         while(i--);        
  31. }



  32. //显示函数1  初始显示
  33. void display(uint dat,uchar add)
  34. {
  35. uchar bai,shi ,ge;
  36. bai=dat/100;
  37. shi=dat%100/10;
  38. ge=dat%10;                                                                                   
  39. writelcd_cmd(add);
  40. writelcd_dat(bai+0x30);
  41. writelcd_dat(shi+0x30);
  42. writelcd_cmd(add+3);
  43. writelcd_dat(ge+0x30);
  44. }

  45. void lcd_min()   //定义最小温度显示
  46. {
  47.         uchar l;
  48.         
  49. writelcd_cmd(0x38);   //初始化屏那迤粱
  50. delay(5);
  51. writelcd_cmd(0x38);
  52. delay(5);
  53. writelcd_cmd(0x38);
  54. writelcd_cmd(0x08);
  55. writelcd_cmd(0x01);
  56. writelcd_cmd(0x06);
  57. writelcd_cmd(0x0c);
  58. writelcd_cmd(0x80);
  59.         
  60.                 writelcd_cmd(0xc0);
  61.                                                 for(l=0;l<16;l++)                  //依次读取t6并显示
  62.                                                 {
  63.                                         writelcd_dat(t6[l]);
  64.                                                 }
  65.                                                 
  66.                                                 display(mintem,0xca);
  67.                                                 delay1(5000000000);   //延时显示
  68. }

  69. void lcd_max()  //定义最大温度显示
  70. {
  71.         uchar k;
  72.         writelcd_cmd(0x38);   //初始化屏幕清屏
  73. delay(5);
  74. writelcd_cmd(0x38);
  75. delay(5);
  76. writelcd_cmd(0x38);
  77. writelcd_cmd(0x08);
  78. writelcd_cmd(0x01);
  79. writelcd_cmd(0x06);
  80. writelcd_cmd(0x0c);
  81. writelcd_cmd(0x80);
  82.         writelcd_cmd(0xc0);
  83.                                                 for(k=0;k<16;k++)                  //依次读取t5并显示
  84.                                                 {
  85.                                         writelcd_dat(t5[k]);
  86.                                                 }
  87.                                                 display(maxtem,0xca);
  88.                                                 delay1(5000000000);
  89. }

  90. void write_Char(unsigned char a,unsigned char b,unsigned char dat) //显示时间程序母程序 定位
  91. {      
  92. if (b == 0)   
  93.     {      
  94.     writelcd_cmd(0x80 + a);      
  95.     }      
  96. else   
  97.     {      
  98.     writelcd_cmd(0xC0 + a);      
  99.     }         
  100. writelcd_dat(dat);   
  101. }   

  102. void display4(uchar hour1,uchar hour2,uchar min1,uchar min2,uchar sec1,uchar sec2)    //显示时间子程序  取值
  103. {     

  104.    
  105.     write_Char(4,0,table2[hour1]);                    //显示小时
  106.     write_Char(5,0,table2[hour2]);  
  107.     write_Char(6,0,table2[0x0a]);                   //显示冒号
  108.     write_Char(7,0,table2[min1]);                    //分钟
  109.     write_Char(8,0,table2[min2]);  
  110.     write_Char(9,0,table2[0x0a]);                    //显示冒号
  111.     write_Char(10,0,table2[sec1]);                    //秒
  112.     write_Char(11,0,table2[sec2]);
  113.         
  114.   
  115. }  


  116. //显示函数2  调最值温度低十位 在LCD上排显示
  117. void display2(uint dat,uchar add)
  118. {
  119. uchar bai,shi ;
  120. bai=dat/100;
  121. shi=dat%100/10;
  122. //ge=dat%10;                                                                                   
  123. writelcd_cmd(add);
  124. writelcd_dat(shi+0x30);
  125. writelcd_dat(bai+0x30);
  126. writelcd_cmd(add+3);
  127. //writelcd_dat(ge+0x30);
  128. }


  129. //显示函数3  调最值温度的个位/小数 在LCD下排显示
  130. void display3(uint dat,uchar add)
  131. {
  132. uchar ge;
  133. //bai=dat/100;
  134. //shi=dat%100/10;
  135. ge=dat%10;                                                                                   
  136. writelcd_cmd(add);
  137. //writelcd_dat(shi+0x30);
  138. //writelcd_dat(bai+0x30);
  139. //writelcd_cmd(add+3);
  140. writelcd_dat(ge+0x30);
  141. }


  142. //按键扫描函数
  143. void keyscan()
  144. {  uchar i,j;  //定义i/j
  145.    writelcd_cmd(0x80);  //显示函数表示以此显示t3字模里面的字符
  146.    for(i=0;i<16;i++)
  147.    {writelcd_dat(t3[i]);}
  148.    writelcd_cmd(0xc0);
  149.    for(j=0;j<16;j++)   //显示函数表示以此显示t4字模里面的字符
  150.    {writelcd_dat(t4[j]);}
  151.   
  152.    while(mode!=0)  //当mode不为0时
  153.    {
  154. display2(htem,0x8b);  //显示调十位        
  155. display3(time,0xca);   //显示调个位小数位
  156.                  
  157.    while(mode!=0)
  158.    {
  159.            switch(mode)  //切换模式case语句循环 5个模式 5个循环 6个变量 初始模式为0 切换后对应地方的光标闪烁
  160.            {
  161.                         
  162.            case 1:writelcd_cmd(0xc0+10);writelcd_cmd(0x0f);break;  //调个位
  163.            case 2:writelcd_cmd(0x80+11);writelcd_cmd(0x0f);break;  //调十位
  164.                  case 3:writelcd_cmd(0xc0+10);writelcd_cmd(0x0f);break;  //调小数位                                 
  165.                  case 4:lcd_max();break;                                  //显示最大温度
  166.                  case 5:lcd_min();break;  //显示最小温度
  167.            default:mode=0;break;
  168.            }
  169.                  
  170.           if(key2==0&&mode==1)  //模式为1 key2为0时 调最高位的个位
  171.           {
  172.                         delay(50);  //按键消抖
  173.             y=0;display3(y,0x80);writelcd_cmd(0xca+11);   //max one 在左上角显示0 表示调最高温度
  174.                   
  175.                   if(key2==0)
  176.                 {  
  177.                         delay(10);  //十个循环 对应0-9数字
  178.                    cnt1++;  //计数+1
  179.                    while(key2==0);
  180.                    switch(cnt1%11)  //按键到10以后清零
  181.                    {
  182.                         case 1:time=0;display3(time,0xca);writelcd_cmd(0xca+11);break;                           //在0xca的地方显示个位值 光标闪烁
  183.                   case 2:time=1;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  184.             case 3:time=2;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  185.             case 4:time=3;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  186.                         case 5:time=4;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  187.                         case 6:time=5;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  188.                         case 7:time=6;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  189.                         case 8:time=7;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  190.                         case 9:time=8;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  191.                         case 10:time=9;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  192.                         
  193.                         default:break;        
  194.                    }        
  195.                 }
  196.           }
  197.                 if(key1==0&&mode==1)  //类似 最低个位
  198.           {
  199.                         delay(50);
  200.             y=1;display3(y,0x80);writelcd_cmd(0xca+11);  //min one 在左上角显示1 表示调最低温度
  201.                   
  202.                   if(key1==0)
  203.                 {  
  204.                         delay(10);
  205.                    cnt4++;
  206.                    while(key1==0);
  207.                    switch(cnt4%11)
  208.                    {
  209.                         case 1:time2=0;display3(time2,0xca);writelcd_cmd(0xca+11);break;         
  210.                   case 2:time2=1;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  211.             case 3:time2=2;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  212.             case 4:time2=3;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  213.                         case 5:time2=4;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  214.                         case 6:time2=5;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  215.                         case 7:time2=6;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  216.                         case 8:time2=7;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  217.                         case 9:time2=8;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  218.                         case 10:time2=9;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  219.                         
  220.                         default:break;        
  221.                    }        
  222.                 }
  223.           }
  224.           if(key2==0&&mode==2)  //最高十位
  225.           {
  226.           delay(10);
  227.                         x=00;display2(x,0x80);writelcd_cmd(0x80+11);  //max ten 在左上角显示00 表示调最高
  228.           if(key2==0)
  229.                   {
  230.                    cnt2++;
  231.                    while(key2==0);
  232.                    switch(cnt2%11)
  233.                    {
  234.                                 
  235.                     case 1:htem=00;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  236.                     case 2:htem=10;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  237.                     case 3:htem=20;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  238.                           case 4:htem=30;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  239.                     case 5:htem=40;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  240.                     case 6:htem=50;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  241.                     case 7:htem=60;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  242.                     case 8:htem=70;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  243.                     case 9:htem=80;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  244.                     case 10:htem=90;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  245.                                  
  246.         
  247.                                 
  248.                     default:break;
  249.                    }
  250.                   }
  251.                         

  252.           }
  253.                 if(key1==0&&mode==2)
  254.           {
  255.           delay(10);
  256.                         x=10;display2(x,0x80);writelcd_cmd(0x80+11); //min ten 在左上角显示10表示 调最低
  257.           if(key1==0)
  258.                   {
  259.                    cnt3++;
  260.                    while(key1==0);
  261.                    switch(cnt3%11)
  262.                    {
  263.                                 
  264.                     case 1:htem2=00;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  265.                     case 2:htem2=10;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  266.                     case 3:htem2=20;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  267.                           case 4:htem2=30;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  268.                     case 5:htem2=40;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  269.                     case 6:htem2=50;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  270.                     case 7:htem2=60;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                 
  271.                     case 8:htem2=70;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  272.                     case 9:htem2=80;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                 
  273.                     case 10:htem2=90;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                 
  274.                         
  275.                                 
  276.                     default:break;
  277.                    }
  278.                   }
  279.                         

  280.           }
  281.                 if(key2==0&&mode==3)  //最高小数
  282.           {
  283.                         delay(50);
  284.                           z=00;display2(z,0x80);writelcd_cmd(0xca+11); //max dot
  285.                   
  286.                   if(key2==0)
  287.                 {  
  288.                         delay(10);
  289.                    cnt5++;
  290.                    while(key2==0);
  291.                    switch(cnt5%11)
  292.                    {
  293.                         case 1:dot=0;display3(dot,0xca);writelcd_cmd(0xca+11);break;         
  294.                   case 2:dot=1;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  295.             case 3:dot=2;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  296.             case 4:dot=3;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  297.                         case 5:dot=4;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  298.                         case 6:dot=5;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  299.                         case 7:dot=6;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  300.                         case 8:dot=7;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  301.                         case 9:dot=8;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  302.                         case 10:dot=9;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  303.                         
  304.                         default:break;        
  305.                    }        
  306.                 }
  307.           }
  308.                 if(key1==0&&mode==3)  //最低小数
  309.           {
  310.                         delay(50);
  311.                            z=10;display2(z,0x80);writelcd_cmd(0xca+11);   //min dot
  312.                   
  313.                   if(key1==0)
  314.                 {  
  315.                         delay(10);
  316.                    cnt6++;
  317.                    while(key1==0);
  318.                    switch(cnt6%11)
  319.                    {
  320.                         case 1:dot2=0;display3(dot2,0xca);writelcd_cmd(0xca+11);break;         
  321.                   case 2:dot2=1;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  322.             case 3:dot2=2;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  323.             case 4:dot2=3;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  324.                         case 5:dot2=4;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  325.                         case 6:dot2=5;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  326.                         case 7:dot2=6;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  327.                         case 8:dot2=7;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  328.                         case 9:dot2=8;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  329.                         case 10:dot2=9;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  330.                         
  331.                         default:break;        
  332.                    }        
  333.                 }
  334.           }
  335.                
  336.                 if(mode==4)  //模式4 显示最大温度
  337.           {
  338.                         maxtem=htem*10+time*10+dot;
  339.                         lcd_max();                        
  340.           }
  341.                
  342.                 if(mode==5)  //最低温度
  343.           {
  344.                         mintem=htem2*10+time2*10+dot2;
  345.                         lcd_min();                    
  346.           }
  347.                
  348.    }
  349.   }
  350.   lcd_init();  //模式为0时执行LCD初始化函数
  351. }




  352. //中断初始化函数
  353. void init()
  354. {
  355.   lcd_init();                   //lcd初始化
  356.    speaker=1;  //蜂鸣器口默认高电平
  357.    mode=0;  //模式默认0
  358.    htem=80;  //最高温度默认80
  359.    time=0;
  360.         htem2=10;  //最低温度默认10
  361.         time2=0;
  362.         dot=0;
  363.         dot2=0;
  364.         EA=1;                                //总中断开启
  365.    EX1=1;                                //外部中断1允许
  366.    ET1=1;                                //定时器1允许
  367.    TMOD=0X01;                        //定时中断1,模式1
  368.    IT1=1;                                //中断1 下降沿触发
  369.    TH1=0Xee;                        //定时中断1 0.5us
  370.    TL1=0X00;
  371.          TR1=0;  //定时中断1默认关闭
  372.         
  373.           count=0;    //时间计数默认为0
  374.     hour=00;    //小时00
  375.     min=00;    //分钟00
  376.     sec=00;    //秒00
  377.      
  378.     TH0=(65536-50000)/256;    //内部中断T0初始化
  379.     TL0=(65536-50000)%256;   
  380.     TR0=1;    //内部中断T0开启
  381.     ET0=1;  
  382.         
  383. }



  384. //主函数
  385. void main()
  386. {  
  387.   P1=0xe7;     //初始P1口,P14,P13为低电平 使S1 S5 S9 S14 S15 S16变为接地的普通开关 S9与P33短接 用于切换模式和退出报警中断
  388.          init();                  //中断初始化
  389.         
  390.         

  391.         while(1)
  392.         {  
  393.                 if(mode!=0)                  //当模式不为0
  394.                 {keyscan();}                  //执行按键扫描 以及调温度的程序

  395.              else if(mode==0)                  //模式为0时
  396.                 {
  397.                                 delay(100);
  398.                     tmpchange();                  //在ds18b20取数据
  399.                         tem=tmp();                         //温度值获取 为整数 且小数位实际上是个位 如35.5摄氏度对应的值是355
  400.                         
  401.         if(keyh==0)                 //当S14闭合时 实现小时加一  
  402.         {  
  403.             delay(5);  
  404.             if(keyh==0)  
  405.             {     
  406.                 if(hour!=23)    hour++;                    //hour=23后清零
  407.                 else            hour=0;  
  408.             }  
  409.             while(!keyh);                       //检测松手      
  410.               
  411.         }  
  412.   
  413.         if(keym==0)              //实现分钟加一  
  414.         {  
  415.             delay(5);  
  416.             if(keym==0)  
  417.             {     
  418.                 if(min!=59)                    //59后清零
  419.                 {  
  420.                     min++;  
  421.                 }  
  422.                 else   
  423.                 {  
  424.                     min=0;  
  425.                 }  
  426.             }  
  427.             while(!keym);       //松手检测  
  428.               
  429.         }  
  430.   
  431.         if(keys==0)             //实现秒加一  
  432.         {  
  433.             delay(5);  
  434.             if(keys==0)  
  435.             {     
  436.                 if(sec!=59)                    //59后清零
  437.                 {  
  438.                     sec++;  
  439.                 }  
  440.                 else   
  441.                 {  
  442.                     sec=0;  
  443.                 }  
  444.             }  
  445.             while(!keys);  
  446.             
  447.         }  
  448.   
  449.         hour1=hour/10;                    //小时十位
  450.         hour2=hour%10;                    //小时个位
  451.         min1=min/10;                    //分钟十位
  452.         min2=min%10;                    //分钟个位
  453.         sec1=sec/10;                    //秒十位
  454.         sec2=sec%10;                    //秒个位
  455.   
  456.               
  457.                 maxtem=htem*10+time*10+dot;
  458.                 mintem=htem2*10+time2*10+dot2;
  459.                     

  460.                         if(tem>=maxtem)                //高于最高
  461.                         {
  462.                           TR1=1;                                //T1中断开启
  463.                                                                     
  464.                         }
  465.                         else if(tem<=mintem)                //低于最低
  466.                         {
  467.                           TR1=1;                                //T1中断开启
  468.                                                                      
  469.                         }
  470.                         else                                     //处于中间
  471.                         {
  472.                         TR1=0;                                        //T1中断关闭
  473.                                            //报警灯灭
  474.                         }
  475.                         
  476.                         delay(10);
  477.                     display(tem,0xca);                  //一直显示温度
  478.                           display4(hour1,hour2,min1,min2,sec1,sec2);  //一直显示时钟  

  479.                     delay(100);
  480.                         
  481.                         
  482. ……………………

  483. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

评分

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

查看全部评分

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

使用道具 举报

楼主
ID:440028 发表于 2022-1-11 14:54 | 只看该作者
lidianxiaofang.c(48): warning C206: 'writelcd_cmd': missing function-prototype
程序编译没有通过
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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