找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机+18B20温度1602显示的控制源码

[复制链接]
跳转到指定楼层
楼主
本单片机采用STC89C52RC芯片,用LCD1602显示温度上限设定值,下限设定值,
以及在线温度实时显示,用18B20温度传感器检测温度,同时用按键设置温度
上下限,以及设定切换,用timer0中断设置1秒闪烁指示灯显示运行状态。  

制作出来的实物图如下:


单片机源程序如下:
  1. /******************************************************************
  2. 本单片机采用STC89C52RC芯片,用LCD1602显示温度上限设定值,下限设定值,
  3.   以及在线温度实时显示,用18B20温度传感器检测温度,同时用按键设置温度
  4.   上下限,以及设定切换,用timer0中断设置1秒闪烁指示灯显示运行状态。
  5. *******************************************************************/

  6. #include<REG52.h>
  7. #include <intrins.h>
  8. unsigned char times;

  9. #define uchar unsigned char//宏定义
  10. #define uint unsigned int


  11. sbit RS = P3^5;   //定义lcd1602通讯端口
  12. sbit RW = P3^6;
  13. sbit EN = P3^4;
  14. sbit DQ= P2^2;          //18B20总线端口
  15. sbit led1=P1^1;          //系统运行指示,
  16. uint temp1;  
  17. uchar bai,shi,ge; //测量温度显示位置
  18. uchar qian1,bai1,shi1,ge1;//上下限温度显示位置
  19. bit flag; //标志位
  20. sbit ds=P2^2;//18B20传感器 I/O口
  21. sbit beep=P1^0;//温度报警
  22. uint temp;
  23. sbit led4=P1^4;//温度上下限设定指示
  24. sbit led3=P1^2;//工作指示

  25. sbit key1=P3^0;// 温度上线限设定转换按钮
  26. sbit key2=P3^1;//温度设定加
  27. sbit key3=P3^2;//温度设定减
  28. uchar num,num_shang=0,num_xia=0,numled,flag_qiehuan; //变量初始化,定义

  29. /*====================================
  30. 函数        : delay(uint z)
  31. 参数        :z 延时毫秒设定,取值范围0-65535
  32. 返回值        :无
  33. 描述        :12T/Fosc11.0592M毫秒级延时
  34. ====================================*/
  35. void delay(xms)                                   //毫秒延时函数
  36. {
  37.         uint i,j;
  38.         for(i=xms;i>0;i--)
  39.                 for(j=100;j>0;j--);
  40. }
  41. void delayus(uint t)        //us延时函数
  42. {
  43.          while(t--);
  44. }
  45. void init()                                                   //初始化函数
  46. {
  47.         TMOD=0x01;                                                   //设置定时器0位工作方式(00000001)
  48.         TH0=(65536-22500)/256;                           //装初值
  49.         TL0=(65536-22500)%256;                           
  50.         EA=1;                                                             //开总中断
  51.         ET0=1;                                                           //开定时器0中断
  52.         TR0=1;
  53. }

  54. void ds_reset()           //复位函数
  55. {
  56.         ds=1;
  57.         delayus(5);     //         延时
  58.         ds=0;
  59.         delayus(80);
  60.         ds=1;
  61.         delayus(14);
  62.         if(ds==0)
  63.                 flag=1;
  64.         else
  65.                 flag=0;                                //flag作为标志位,等1表示18b20存在
  66.         delayus(20);
  67. }
  68. bit ds_read_bit(void)                        //读一位数据函数
  69. {
  70.         bit dat;
  71.         ds=0;
  72.         _nop_();                                   //延时机器周期
  73.         _nop_();
  74.         ds=1;                                                //释放总线
  75.         _nop_();
  76.         dat=ds;
  77.         delayus(10);               //延时100us
  78.         return dat;
  79. }
  80. uchar ds_read_byte()                   //读一个字节函数
  81. {
  82.         uchar i,j,k;
  83.         for(i=0;i<8;i++)                  //一个字节8位组成,循环八次
  84.         {
  85.                 j=ds_read_bit();
  86.                 k=(j<<7)|(k>>1);                //读出的数据最低位在最前面
  87.         }
  88.         return k;
  89. }
  90. void ds_write_byte(uchar dat)      //写一个字节的函数
  91. {
  92.         uchar i;
  93.         for(i=0;i<8;i++)                        //循环八位将一个字节由低到高写入
  94.         {
  95.                 ds=0;
  96.                 _nop_();
  97.                 ds=dat&0x01;                        //保留dat的最低位
  98.                 delayus(6);
  99.                 ds=1;                 //释放总线
  100.                 dat=dat>>1;
  101.         }
  102.         delayus(6);
  103. }
  104. uint read_temp()                //读取温度函数
  105. {
  106.         uchar a,b;
  107.         ds_reset();
  108.         ds_write_byte(0xcc);//                18B20忽略指令
  109.         ds_write_byte(0xbe); //读暂存器指令
  110.         a=ds_read_byte();           //读低八位
  111.         b=ds_read_byte();                        //读高八位
  112.         temp=b;
  113.         temp=temp<<8;
  114.         temp=temp|a;
  115.         temp=temp*0.0625;                //得到实际温度值
  116.         return temp;
  117. }

  118. /*************************************/
  119. void keyscan()
  120. {
  121.         if(key1==0)//按键1处理,切换设置上下限
  122.         {         
  123.                         delay(5);         //去抖
  124.                      if(key1==0)
  125.                    {
  126.                
  127.                      flag_qiehuan=!flag_qiehuan;//温度上下限按键取反
  128.                         
  129.                                                                                           
  130.                          led4=flag_qiehuan;//温度设置切换按键状态指示
  131.                         
  132.                          while(!key1);//松手检测
  133.                      }
  134.                 }               
  135.                         

  136.                                 
  137.                     
  138.                
  139.         if((key2==0)&&(flag_qiehuan==0))//温度加按钮,k2长按
  140.         {        
  141.                     delay(30);
  142.                 if((key2==0)&&(flag_qiehuan==0))
  143.                           {                        
  144.                                 if(num_xia!=40)//上限值40
  145.                                  num_xia++;         //
  146.                           }
  147.                         
  148.         }
  149.         else if((key2==0)&&(flag_qiehuan==0))//K2短按
  150.         {
  151.                 delay(3);
  152.                 if((key2==0)&&(flag_qiehuan==0))
  153.                          {
  154.                                 if(num_xia!=40)// 上限值40
  155.                                  num_xia++;
  156.                                 while(!key2);//松手检测                 
  157.                          }
  158.                
  159.         }
  160.         if((key3==0)&&(flag_qiehuan==0))//         温度减按键
  161.         {
  162.                 delay(30);
  163.                 if((key3==0)&&(flag_qiehuan==0))
  164.                           {
  165.                         if(num_xia!=0)//下限值0
  166.                                 
  167.                                   num_xia--;
  168.                         
  169.                           }        
  170.         }
  171.         else if((key3==0)&&(flag_qiehuan==0))                                                                                //K3短按
  172.         {
  173.                 delay(3);
  174.                 if((key3==0)&&(flag_qiehuan==0))
  175.                 {
  176.                         if(num_xia!=0)//下限值0
  177.                           num_xia--;
  178.                         while(!key3);//松手检测                 
  179.                 }        
  180.         }
  181.         if((key2==0)&&(flag_qiehuan==1))                                         
  182.         {
  183.                 delay(30);
  184.                 if((key2==0)&&(flag_qiehuan==1))
  185.                 {
  186.                         if(num_shang!=40)//上限值40
  187.                         num_shang++;
  188.                 }        
  189.         }
  190.         else if((key2==0)&&(flag_qiehuan==1))                                 
  191.         {
  192.                 delay(3);
  193.                 if((key2==0)&&(flag_qiehuan==1))
  194.                 {
  195.                         if(num_shang!=40)//上限值40
  196.                         num_shang++;
  197.                         while(!key2);//松手检测                 
  198.                 }
  199.         }
  200.         if((key3==0)&&(flag_qiehuan==1))
  201.         {
  202.                 delay(30);
  203.                 if((key3==0)&&(flag_qiehuan==1))
  204.                 {
  205.                         if(num_shang!=0)//
  206.                         num_shang--;// 下限值0
  207.                 }
  208.         }        
  209.         else if((key3==0)&&(flag_qiehuan==1))
  210.         {
  211.                 delay(3);
  212.                 if((key3==0)&&(flag_qiehuan==1))
  213.                 {
  214.                         if(num_shang!=0) //下限值0
  215.                         num_shang--;
  216.                         while(!key3);//        松手检测         
  217.                 }
  218.         }        
  219.                   
  220. }
  221. void deal()//         温度报警设定
  222. {
  223.         if((temp>=num_xia)||(temp<=num_shang))        //大于下限或低于上限不报警
  224.         {
  225.                 beep=0;
  226.         }
  227.         if((temp<num_xia)&&(temp>num_shang)) //低于下限或高于上限报警
  228.         {
  229.                 beep=1;
  230.         }        
  231. }                                       
  232. /****************************************/
  233. void display_set_alm()                                        //显示子函数,报警数据分离,显示在液晶面板上
  234. {                                                                                

  235.         qian1=num_shang/10;                                   
  236.         bai1=num_shang%10;
  237.         shi1=num_xia/10;
  238.         ge1=num_xia%10;
  239. }
  240. /************************************/

  241.          
  242.   void delay_DS18B20(  time)//18B20延时5us函数
  243. {
  244.         uint i,j;
  245.         for(i=0;i<time;i++)
  246.                 for(j=0;j<1;j++);
  247. }
  248. void delay_ms(uchar time)//延时1ms函数
  249. {
  250.   unsigned int i,j;
  251.   for(i=0;i<time;i++)
  252.           for(j=0;j<110;j++);
  253. }
  254. uchar Init_DS18B20(void)//18B20初始化
  255. {
  256.         uchar Presence;
  257.         DQ=1;                                //数据端置高电平
  258.         delay_DS18B20(10);         //延时

  259.         DQ=0;                                 //数据端置低电平
  260.         delay_DS18B20(29);

  261.         DQ=1;
  262.         delay_DS18B20(3);

  263.         Presence=DQ;
  264.         delay_DS18B20(23);
  265.         return (Presence);

  266. }

  267. uchar Read_bit_DS18B20(void)
  268. {
  269.         DQ=1;
  270.         delay_DS18B20(1);//DS18B20读位
  271.         DQ=0;
  272.         DQ=1;
  273.         return (DQ);
  274. }

  275. void Write_bit_DS18B20(uchar date)//DS18B20写位
  276. {
  277.         DQ=0;
  278.         if(date==1)
  279.                 DQ=1;
  280.         delay_DS18B20(1);
  281.         DQ=1;
  282.         delay_DS18B20(1);
  283. }

  284. uchar Read_Byte_DS18B20(void)//DS18B20读字节
  285. {
  286.         uchar i,date=0;
  287.         for(i=0;i<8;i++)
  288.         {
  289.                 if(Read_bit_DS18B20())
  290.                 {
  291.                         date=date|(0x01<<i); //00000001   00000010
  292.                 }
  293.         }

  294.         return (date);
  295. }

  296. void Write_Byte_DS18B20(uchar date)//DS18B20写字节
  297. {
  298.         uchar i;
  299.         for(i=0;i<8;i++)
  300.         {
  301.                 Write_bit_DS18B20(date&0x01);
  302.                 date=date>>1;        
  303.         }
  304. }

  305. uint Gettemp(void)//读取温度,并将二进制数据转换成温度值
  306. {
  307.         uchar a,b;
  308.         uint temp;
  309.         float t;
  310.         Init_DS18B20();
  311.         Write_Byte_DS18B20(0xcc);//跳过        ROM
  312.     Write_Byte_DS18B20(0x44);//开始转换温度
  313.         delay_DS18B20(30);

  314.         Init_DS18B20();
  315.         Write_Byte_DS18B20(0xcc);//跳过        ROM
  316.     Write_Byte_DS18B20(0xbe);//读取数据

  317.         a=Read_Byte_DS18B20();//读温度值的低位
  318.         b=Read_Byte_DS18B20();//读温度值的高位

  319.         temp=b;
  320.         temp=temp<<8;
  321.         temp=temp|a;

  322.         t=temp*0.0625;                 //计算温度值
  323.         temp=t*10+0.5;                 

  324.         return (temp);                // 返回

  325. }
  326. void LCD_Write_Com(uchar com)//         lcd写命令
  327. {  
  328. delay_ms(5);
  329. RS=0;
  330. RW=0;
  331. EN=1;
  332. P0=com;
  333. EN=0;
  334. }
  335. void LCD_Write_Data(uchar Data) //写入数据函数
  336. {
  337. delay_ms(5);
  338. RS=1;
  339. RW=0;
  340. EN=1;
  341. P0= Data;
  342. EN=0;
  343. }
  344. void gotoxy(uchar x,uchar y)         //确定显示位置
  345. {
  346.         if (x == 1)
  347.          {     
  348.                  LCD_Write_Com(0x80 + y-1);     //表示第一行
  349.          }
  350.         else
  351.          {      
  352.                  LCD_Write_Com(0xC0 + y-1);      //表示第二行
  353.          }        
  354. }
  355. void LCD_Write_String(uchar *s) // 写入字符串函数
  356. {     
  357.          while (*s)
  358.          {     
  359.          LCD_Write_Data( *s);     
  360.          s ++;     
  361.          }
  362. }
  363. void LCD_Init(void)  //初始化函数
  364. {
  365.    LCD_Write_Com(0x38);    /*显示模式设置*/
  366.    delay_ms(1);
  367.    LCD_Write_Com(0x38);
  368.    delay_ms(1);
  369.    LCD_Write_Com(0x38);
  370.    delay_ms(1);
  371.    LCD_Write_Com(0x38);  
  372.    LCD_Write_Com(0x08);    /*显示关闭*/
  373.    LCD_Write_Com(0x01);    /*显示清屏*/
  374.    LCD_Write_Com(0x06);    /*显示光标移动设置*/
  375.    delay_ms(1);
  376.    LCD_Write_Com(0x0C);    /*显示开及光标设置*/
  377. }
  378. void main(void)
  379. {
  380.             
  381.           init();                                //定时器初始化函数调用
  382.         
  383.         {
  384.          ds_reset();
  385.          ds_write_byte(0xcc); //18B20忽略指令
  386.          ds_write_byte(0x44);//18B20温度转换指令
  387.          keyscan();//按键扫描
  388.          deal();        //测量温度处理
  389.                
  390.         }
  391.          
  392.         LCD_Init();
  393.         gotoxy(1,1);
  394.     LCD_Write_String("ALM H   L"); //第一行第一列开始写
  395.         gotoxy(2,1);
  396.         LCD_Write_String("DS18B20:");//第二行第三列开始写
  397.         while(1)
  398.         {         
  399.                         
  400.                 temp1=Gettemp();
  401.                 bai=temp1/100;
  402.                 shi=temp1%100/10;
  403.                 ge=temp1%10;
  404.         gotoxy(2,9);
  405.                 LCD_Write_Data(bai+0x30);        //加0x30的原因是在ASCII码中0的地址是0x30
  406.                 LCD_Write_Data(shi+0x30);
  407.                 LCD_Write_Data('.');
  408.                 LCD_Write_Data(ge+0x30);
  409.                         
  410.          gotoxy(1,6);
  411.                 LCD_Write_Data(qian1+0x30);
  412.                 LCD_Write_Data(bai1+0x30);
  413.                 gotoxy(1,10);
  414.                 LCD_Write_Data(shi1+0x30);
  415.                 LCD_Write_Data(ge1+0x30);
  416.                         
  417.                         keyscan() ;
  418.                 display_set_alm();
  419.            }

  420. }
  421. /***************************************************/
  422. void T0_time() interrupt 1//中断1
  423. {
  424.         TH0=(65536-22500)/256;                           //装初值
  425.         TL0=(65536-22500)%256;
  426.         numled++;
  427.         if(numled==50)
  428.         {
  429.           numled=0;
  430.           led3=~led3;         //定时1s灯闪烁
  431.         }
  432. }
复制代码
此附件由于多人回帖说代码有错误,已经被管理员删除,无法下载
51单片机-1602 18B20温度显示控制.rar (5.96 MB, 下载次数: 48)
此附件由于多人回帖说代码有错误,已经被管理员删除,无法下载

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:474538 发表于 2019-12-29 08:36 | 只看该作者
程序运行不了,定义的一些led也没用上,下面图片是个最基本的错误,主函数里面也有错误

%3X~3@S3BSRW]GW3D3[2UYN.png (66.56 KB, 下载次数: 53)

%3X~3@S3BSRW]GW3D3[2UYN.png
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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