找回密码
 立即注册

QQ登录

只需一步,快速开始

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

DS18B20温度传感器程序

[复制链接]
跳转到指定楼层
楼主
ID:912927 发表于 2021-4-27 11:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include<reg52.h>                    //包含头文件
  2. #include<math.h>
  3. #define ui unsigned int
  4. #define uc unsigned char           //宏定义


  5. sbit DQ =P3^7;                             //定义DS18B20总线I/O


  6. sbit LEDR=P1^2;
  7. sbit LEDG=P1^1;
  8. sbit LEDB=P1^0;      


  9. bit bdata fuhao;                        //符号
  10. uc qian,bai,shi,ge;                        //读取温度值的千、百、十和个位(例如实际温度是123.4摄氏度,在程序里处理数据时会放大10倍,就是小数点右移一位,方便处理,就是处理的是1234)
  11. uc code led[]                =        {0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x47,0xDF,0xD7};           //数码管对应的数字的段码
  12. uc code led_dian[]        =        {0x7f,0x64,0xbd,0xf5,0xe6,0xf3,0xfb,0x67,0xff,0xf7};           //有小数点的数字段码表
  13. uc m;
  14. uc NUM_R=0,NUM_G=0,NUM_B=0;
  15. uc DIS;
  16. ui zan=25;
  17. //============================================================================================
  18. //====================================DS18B20=================================================
  19. //============================================================================================


  20. /*****延时子程序*****/
  21. void Delay(int num)
  22. {
  23.         while(num--) ;           //num减占用系统资源,用于延时
  24. }
  25. /*****初始化DS18B20*****/
  26. void Init_DS18B20()
  27. {
  28.         DQ = 1;         //DQ复位,就是拉高电平
  29.         Delay(8);    //稍做延时
  30.         DQ = 0;         //单片机将DQ拉低
  31.         Delay(80);   //精确延时,大于480us
  32.         DQ = 1;         //拉高总线
  33.         Delay(40);                //延时
  34. }
  35. /*****读一个字节*****/
  36. uc ReadOneChar()
  37. {
  38.         uc i=0;
  39.         uc dat = 0;                                 //定义变量用于循环和读取数据
  40.         for (i=8;i>0;i--)                 //循环8次
  41.         {
  42.                 DQ = 0;     //拉低
  43.                 dat>>=1;        //数据右移一位
  44.                 DQ = 1;     //拉高
  45.                 if(DQ)                //判断是否是高电平
  46.                 dat|=0x80;        //是高电平的话,就让dat的最好为为1
  47.                 Delay(4);        //延时
  48.         }
  49.         return(dat);        //返回读取到的数据
  50. }
  51. /*****写一个字节*****/
  52. void WriteOneChar(uc dat)
  53. {
  54.         uc i=0;                                        //定义变量用于循环
  55.         for (i=8; i>0; i--)                //循环八次
  56.         {
  57.                 DQ = 0;                                //低电平
  58.                 DQ = dat&0x01;                //最低位是0的话,DQ就等于0;最低位是1的话,DQ就等于1
  59.                 Delay(5);                        //延时
  60.                 DQ = 1;                                //拉高
  61.                 dat>>=1;                        //右移一位
  62.         }
  63. }
  64. /*****读取温度*****/
  65. ui ReadTemperature()
  66. {
  67.   ui a=0,b=0,t=0;                 
  68.   float tt=0;                         //定义读取温度变量
  69.   Init_DS18B20();                 //初始化18B20
  70.   WriteOneChar(0xCC);  //跳过读序号列号的操作
  71.   WriteOneChar(0x44);  //启动温度转换
  72.   Init_DS18B20();           //初始化18B20
  73.   WriteOneChar(0xCC);  //跳过读序号列号的操作
  74.   WriteOneChar(0xBE);  //读取温度寄存器
  75.   a=ReadOneChar();     //读低8位
  76.   b=ReadOneChar();    //读高8位
  77.   t=b;                                   //高八位的数据提取到t
  78.   t<<=8;                           //高八位数据左移八位
  79.   t=t|a;                           //高位和低八位数据组成一个数据
  80.   if(t&0xf800)                   //判断是否是负温度
  81.   {
  82.         t=~t+1;                           //将负温度值取反加一得到实际温度值
  83.         fuhao=1;                   //符号位为负
  84.   }
  85.   else                                   //如果是正温度
  86.   fuhao=0;                           //符号位为正
  87.   tt=t*0.0625;                   //乘以0.0625得到实际温度
  88.   t=tt*10+0.5;     //放大10倍输出并四舍五入
  89.   return(t);           //返回温度数据
  90. }


  91. /*****读取温度*****/
  92. void check_wendu()
  93. {
  94.         ui f;
  95. //        TR0=0;
  96. //        zan=f;
  97.         f=ReadTemperature();                          //获取温度值并减去DS18B20的温漂误差
  98. //        TR0=1;
  99. //        if(abs(f-zan)>50) f=zan;
  100.         qian=f/1000;                                                                //计算得到实际的百位数字
  101.         bai=(f%1000)/100;                                                     //计算得到实际的十位数字
  102.         shi=((f%1000)%100)/10;                                            //计算得到实际的个位数字
  103.         ge=((f%1000)%100)%10;                                                      //计算得到实际的小数位
  104. }
  105. /*****显示开机初始化等待画面*****/
  106. void Disp_init()
  107. {
  108.         P0 = 0x7f;      //显示----
  109.         P2 = 0x7f;
  110.         Delay(100);
  111.         P2 = 0xdf;
  112.         Delay(100);   
  113.         P2 = 0xf7;
  114.         Delay(100);
  115.         P2 = 0xfd;
  116.         Delay(100);
  117.         P2 = 0xff;         //关闭显示
  118. }
  119. /*****显示温度子程序*****/
  120. void Disp_Temperature()     //显示温度
  121. {
  122.                         if(qian==0)                  //千位等于0
  123.                         {
  124.                                 if(fuhao==1)  //是负温度
  125.                                 P0=0x7f;      //显示-
  126.                                 else                  //是正温度
  127.                                 P0=0xff;          //不显示
  128.                         }
  129.                         else if(qian!=0)          //千位不等于0
  130.                         P0 =~led[qian];          //显示千位数据
  131.                         P2 = 0xfd;                  //打开第一位位选
  132.                         Delay(10);
  133.                         P2 = 0xff;                  //关闭位选


  134.                         if((bai==0)&&(qian==0))//百位千位都是0
  135.                         P0=0xff;    //不显示
  136.                         else if((bai!=0)||(qian!=0))//千位或者百位不等于0
  137.                         P0=~led[bai];                        //正常显示百位数据
  138.                         P2=0xf7;                 //打开第二位
  139.                         Delay(10);
  140.                         P2 = 0xff;                  //关闭位选


  141.                         P0=~led_dian[shi];    //显示十位数据
  142.                         P2=0xdf;                          //打开第三位
  143.                         Delay(10);
  144.                         P2 = 0xff;                  //关闭位选


  145.                         P0=~led[ge];                     //显示个位数据
  146.                         P2=0x7f;                          //打开第四位
  147.                         Delay(10);
  148.                         P2 = 0xff;                  //关闭位选


  149. }
  150. /*****主函数*****/
  151. void main()
  152. {
  153.         uc z;                        //定义变量用于for循环
  154.         for(z=0;z<100;z++)        //循环100次读取温度并显示开机画面,防止开机显示85
  155.         {
  156.                 Disp_init();        //开机初始化显示
  157.                 ReadTemperature();
  158.         }
  159.         while(1)                //进入while循环
  160.         {
  161.                 check_wendu();        //读取温度
  162. //                Delay(20000);
  163.                 if(fuhao==0)
  164.                 {
  165.                         if((qian*100+bai*10+shi)>=0&&(qian*100+bai*10+shi)<10)                  {NUM_R=0;        NUM_G=2;        NUM_B=8;}         //温度在0-10度之间,颜色:青色偏蓝,状态:寒冷
  166.                         else if((qian*100+bai*10+shi)>=10&&(qian*100+bai*10+shi)<20) {NUM_R=0;        NUM_G=3;        NUM_B=5;}         //温度在10-20度之间,颜色:青色,状态:冷
  167.                         else if((qian*100+bai*10+shi)>=20&&(qian*100+bai*10+shi)<30) {NUM_R=0;        NUM_G=5;        NUM_B=0;}         //温度在20-30度之间,颜色:绿色,状态:舒适
  168.                         else if((qian*100+bai*10+shi)>=30&&(qian*100+bai*10+shi)<35) {NUM_R=7;        NUM_G=2;        NUM_B=0;}         //温度在30-35度之间,颜色:黄色,状态:热
  169.                         else if((qian*100+bai*10+shi)>=35) {NUM_R=10;        NUM_G=0;        NUM_B=0;}                                                         //温度在35度以上,颜色:红色,状态:炎热




  170. //                        if((qian*100+bai*10+shi)>=24&&(qian*100+bai*10+shi)<25)                  {NUM_R=0;        NUM_G=2;        NUM_B=8;}         //温度在0-10度之间,颜色:青色偏蓝,状态:寒冷
  171. //                        else if((qian*100+bai*10+shi)>=25&&(qian*100+bai*10+shi)<26) {NUM_R=0;        NUM_G=3;        NUM_B=5;}         //温度在10-20度之间,颜色:青色,状态:冷
  172. //                        else if((qian*100+bai*10+shi)>=26&&(qian*100+bai*10+shi)<27) {NUM_R=0;        NUM_G=5;        NUM_B=0;}         //温度在20-30度之间,颜色:绿色,状态:舒适
  173. //                        else if((qian*100+bai*10+shi)>=27&&(qian*100+bai*10+shi)<28) {NUM_R=7;        NUM_G=2;        NUM_B=0;}         //温度在30-35度之间,颜色:黄色,状态:热
  174. //                        else if((qian*100+bai*10+shi)>=28) {NUM_R=10;        NUM_G=0;        NUM_B=0;}                                                         //温度在35度以上,颜色:红色,状态:炎热
  175. //                        else if((qian*100+bai*10+shi)<24) {NUM_R=0;NUM_G=0;NUM_B=10;}
  176.                 }
  177.                 else                                                                                                                                                                                                 //温度为负值,零下,颜色:蓝色,状态:冰冻
  178.                 {
  179.                         NUM_R=0;NUM_G=0;NUM_B=10;
  180.                 }


  181.                 for(z=0;z<10;z++)        //显示10次
  182.                 {
  183.                         Disp_Temperature();        //调用显示函数
  184.                         m++;
  185.                         if(m<NUM_R) LEDR=0;
  186.                         else LEDR=1;
  187.                         if(m<NUM_G) LEDG=0;
  188.                         else LEDG=1;
  189.                         if(m<NUM_B) LEDB=0;
  190.                         else LEDB=1;
  191.                         if(m>=10) m=0;
  192.                 }
  193.         }
  194. }
复制代码


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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