找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机DS18B20数字温度报警器Proteus仿真+代码详细注释

  [复制链接]
跳转到指定楼层
楼主
现呈上一份关于c51数字温度报警器的压缩包,转自:http://www.51hei.com/bbs/dpj-132660-1.html



单片机源程序如下:
  1. #include<reg52.h>                                                //包含reg52.h库文件
  2. #include<math.h>                                                //包含绝对值函数
  3. #define uint unsigned int                                //宏定义uint
  4. #define uchar unsigned char                                //宏定义uchar
  5. sbit lcden=P2^0;                                                //液晶使能端
  6. sbit lcdrw=P2^1;
  7. sbit lcdrs=P2^2;                                                //液晶数据命令选择端选择写数据还是写命令
  8. sbit DQ = P2^3;                         //通过DQ口读取温度值
  9. sbit s1=P1^2;                                                        //选择按键
  10. sbit s2=P1^7;                                                        //加按键
  11. sbit s3=P3^3;                                                        //减按键
  12. sbit D1=P3^4;             //高温报警灯
  13. sbit D2=P1^3;             //低温报警灯
  14. uchar temp_value,num,fig,s1num,figh,figl,t;  //设置全局无符号字符型变量
  15. char h,l;                                                                //设置全局有符号字符型变量
  16. void delay(uint z);                                                //申明延时程序
  17. void init();                                                        //申明LCD初始化程序
  18. void write_com(uchar com);                                //申明写命令程序
  19. void write_data(uchar date);                        //申明写数据程序
  20. void keyscan();                                                    //申明按键扫描程序
  21. void write_hl(uchar add,char date);            //申明设置的最高低温度值在LCD上显示程序
  22. void write_temp_value(uchar add,char date);        //申明温度值在LCD上显示程序
  23. void delay_18B20(unsigned int i);                //申明延时程序
  24. void Init_DS18B20(void);                                //申明DS18B20初始化程序
  25. unsigned char ReadOneChar(void);                //申明ds18b20读一个字节
  26. void WriteOneChar(uchar dat);                        //申明ds18b20读一个字节
  27. void ReadTemp(void);                                        //申明读取ds18b20当前温度
  28. void comp();
  29. void main()
  30. {
  31.         init();                                                                //LCD初始化
  32.         Init_DS18B20();                                                //DS18B20初始化
  33.         while(1)                                                        //大循环
  34.         { if(s1==0||s1num>=1)
  35.                 {        keyscan();                                        //按键扫描
  36.                 }
  37.         else{        ReadTemp();                                        //读取温度值
  38.                         write_temp_value(0,temp_value);        //LCD显示温度值
  39.                 }
  40.                 comp();               
  41.         }
  42. }

  43. void delay(uint z)                                                //延时程序
  44. {
  45.         uint x,y;
  46.         for(x=z;x>0;x--)
  47.         for(y=110;y>0;y--);
  48. }



  49. void init()                                                //LCD初始化程序
  50. {   lcden=0;
  51.           lcdrw=0;
  52.         write_com(0x38);                         //设置16x2 显示5x7 点阵,8 位数据接口
  53.         write_com(0x0c);                 //设置开始显示不显示光标
  54.         write_com(0x06);                         //写一个字符后地址指针加1
  55.         write_com(0x01);                         //显示清零数据指针清零
  56.         write_com(0x80);                         //将数据指针第一行第一个字处,
  57.         
  58.         write_com(0x80+9);                         //定义当前指针位置
  59.         write_data('H');                                 //写入
  60.         write_data(':');                                 //写入
  61.         write_data('+');                                 //写入
  62.         write_data('2');                                 //写入
  63.         write_data('0');                                 //写入
  64.         write_data(0xdf);                                 //写入°
  65.         write_data('C');                                 //写入C
  66.         write_com(0x80+9+0x40);                  //定义当前指针位置
  67.         write_data('L');                                 //写入
  68.         write_data(':');                                 //写入
  69.         write_data('+');                                 //写入
  70.         write_data('1');                                 //写入
  71.         write_data('0');                                 //写入
  72.         write_data(0xdf);                                 //写入°
  73.         write_data('C');                                 //写入C
  74.         h=0x14;                  //h=+20
  75.         l=0+0x0a;                                                     //l=+10
  76.         D1=1;
  77.         D2=1;
  78.         figh=0;                                                         //给正确初始值,便于上电比较
  79.         figl=1;                                                         //给正确初始值,便于上电比较
  80. }
  81. void write_com(uchar com)                //写命令程序
  82. {        lcdrs=0;                                         //设置为写入命令
  83.         P0=com;                                         //将命令赋给P0 口
  84.         delay(5);                                         //延时
  85.         lcden=1;                                         //打开LCD使能,输入一个高脉冲
  86.         delay(5);                                        //延时
  87.         lcden=0;                                         //置低完成高脉冲
  88. }
  89. void write_data(uchar date)                //写数据程序
  90. {        lcdrs=1;                                         //设置为写入数据
  91.         P0=date;                                         //将数据赋给P0 口
  92.         delay(5);                                         //延时
  93.         lcden=1;                                         //打开LCD使能,输入一个高脉冲
  94.         delay(5);                                         //延时
  95.         lcden=0;                                         //置低完成高脉冲
  96. }

  97. void write_temp_value(uchar add,char date)         //读取的温度值在LCD上显示程序
  98. {        uchar bai,shi,ge;
  99.         bai=date/100;
  100.         shi=date%100/10;                                 
  101.         ge=date%10;                                                 //分离出百,十,个位数
  102.         if((bai|shi)==0)                                 //如果百十都等于0
  103.         shi=0x70;                                                 //十赋值0x70,以便十位写入空字符,write_data(0x30+shi),参考1602字符图形码
  104.         if(bai==0)
  105.         bai=0x70;
  106.         write_com(0x80+add);                     //设置当前光标位置,准备写数据
  107.         
  108.         if(fig==0&&shi!=0x70)                         //如果温度为负且十位不等于0(如果十位等于0,shi=0x70)
  109.         { write_data('-');                                 //在百位写入负号
  110.           write_data(0x30+shi);                        //写入十位数据
  111.         }
  112.         if(fig==0&&shi==0x70)                         //如果温度为负且百十位都等于0
  113.         { write_data(0x30+0x70);                 //在百位写入一个空字符
  114.           write_data('-');                                 //在十位写入负号
  115.         }
  116.         if(fig==1)write_data(0x30+bai);  //温度正,写入百位数据
  117.         if(fig==1)write_data(0x30+shi);         //温度正,写入十位数据
  118.         write_data(0x30+ge);                         //写入个位数据
  119.         write_data(0xdf);                                 //写入°
  120.         write_data('C');                                 //写入C
  121.         
  122. }
  123. void write_hl(uchar add,char date)         //设置的高低温度值在LCD上显示程序
  124. {        uchar bai,shi,ge;
  125.         bai=date/100;
  126.         shi=date%100/10;                                 
  127.         ge=date%10;                                                 //分离出百,十,个位数
  128.         write_com(0x80+add);                     //设置当前光标位置,准备写数据
  129.         
  130.         if(t==1&&shi!=0)                             //如果温度为负且十位不等于0(如果十位等于0,shi=0x70)            负数:百位第1种情况,写-
  131.                 { write_data('-');}                         //在百位写入负号
  132.         if(t==1&&shi==0)                             //如果温度为负且百十位都等于0                                                    负数:百位第2种情况,写空
  133.                 { write_data(0x30+0x70);         //在百位写入一个空字符
  134.                     write_data('-');                         //在十位写入负号                                                                            负数:十位第1种情况,写-
  135.                 }
  136.         if(t==1&&shi!=0)                             //如果温度为负且十不等于0                                                                负数:十位第2种情况,写数                                                
  137.             {write_data(0x30+shi);}                 //在十位写入数据
  138.         if(t==0&&bai==0&&shi!=0)                 //否则温度为正,如果bai=0且shi!=0                                                  正数:百位第1种情况,写+
  139.                 {write_data('+');}                         //在百位写入+
  140.         if(t==0&&bai==0&&shi==0)                 //否则温度为正,如果bai=0且shi=0                                                           正数:百位第2种情况,写空
  141.                 {write_data(0x30+0x70);}         //在百位写入一个空字符
  142.         if(t==0&&bai!=0)        
  143.                 {write_data(0x30+bai);}      //否则百位为正不等于0,写入百位数                                                           正数:百位第3种情况,写数
  144.         if(t==0&&bai==0&&shi==0&&ge!=0)         //如果百十等于0,个不等于0                                                                           正数:十位第1种情况,写+
  145.                 {write_data('+');}                         //在十位写入+
  146.         if(t==0&&bai==0&&shi==0&&ge==0)         //如果百十个都等于0
  147.             {write_data(' ');}                     //在十位写入空字符                                                                                           正数:十位第2种情况,写空
  148.         if(t==0&&shi!=0)        
  149.                 {write_data(0x30+shi);}             //在十位写入数                                                                                                   正数:十位第3种情况,写数                    
  150.         write_data(0x30+ge);                         //写入个位数据
  151. }

  152. /***********ds18b20子程序*************************/

  153. /***********ds18b20延迟子函数(晶振12MHz )*******/

  154. void delay_18B20(unsigned int i)
  155. {
  156.         while(i--);
  157. }

  158. /**********ds18b20初始化函数**********************/

  159. void Init_DS18B20(void)
  160. {
  161.          unsigned char x=0;
  162.          DQ = 1;          //DQ复位
  163.          delay_18B20(8);  //稍做延时
  164.          DQ = 0;          //单片机将DQ拉低
  165.          delay_18B20(80); //精确延时 大于 480us
  166.          DQ = 1;          //拉高总线
  167.          delay_18B20(14);
  168.          x=DQ;            //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  169.          delay_18B20(20);
  170. }

  171. /***********ds18b20读一个字节**************/  

  172. unsigned char ReadOneChar(void)
  173. {
  174.         uchar i=0;
  175.         uchar dat = 0;
  176.         for (i=8;i>0;i--)
  177.          {
  178.                   DQ = 0; // 给脉冲信号
  179.                   dat>>=1;
  180.                   DQ = 1; // 给脉冲信号
  181.                   if(DQ)
  182.                   dat|=0x80;
  183.                   delay_18B20(4);
  184.          }
  185.          return(dat);
  186. }

  187. /*************ds18b20写一个字节****************/  

  188. void WriteOneChar(uchar dat)
  189. {
  190.          unsigned char i=0;
  191.          for (i=8; i>0; i--)
  192.          {
  193.                   DQ = 0;
  194.                  DQ = dat&0x01;
  195.             delay_18B20(5);
  196.                  DQ = 1;
  197.             dat>>=1;
  198. }
  199. }

  200. /**************读取ds18b20当前温度************/

  201. void ReadTemp(void)
  202. {
  203.         unsigned char a=0;
  204.         unsigned char b=0;
  205.         unsigned char t=0;

  206.         Init_DS18B20();
  207.         WriteOneChar(0xCC);            // 跳过读序号列号的操作
  208.         WriteOneChar(0x44);         // 启动温度转换

  209.         delay_18B20(100);       // this message is very important

  210.         Init_DS18B20();
  211.         WriteOneChar(0xCC);         //跳过读序号列号的操作
  212.         WriteOneChar(0xBE);         //读取温度寄存器等(共可读9个寄存器) 前两个就是温度

  213.         delay_18B20(100);

  214.         a=ReadOneChar();            //读取温度值低位
  215.         b=ReadOneChar();                   //读取温度值高位
  216. //        a=0xff;                                        //测试无法读取-16度的问题
  217. //        b=0xfe;
  218.         temp_value=b<<4;                  //temp_value=b左移动4位  ,                         转换成10进制
  219.         temp_value+=(a&0xf0)>>4;  //temp_value=temp_value+((a&0xf0)>>4) 转换成10进制
  220.         fig=0x01;                                  //设置fig=1温度正
  221.         if(temp_value>0x7f)                  //如果temp_value大于0x7f,即为负数区,参考DS18B20datasheet
  222.         {fig=0;                                          //设置fig=0温度负,以便判断显示
  223.          a=~a+1;                                  //将读取的温度转换成10进制数
  224.          b=~b;
  225.          temp_value=b<<4;                  //temp_value=b左移动4位  ,                         转换成10进制
  226.          temp_value+=(a&0xf0)>>4; //temp_value=temp_value+((a&0xf0)>>4) 转换成10进制
  227.         }            
  228. }

  229. void keyscan()                                                 //按键扫描
  230. {        if(s1==0)                                                 //如果s1按下,执行下面程序
  231.         {   delay(5);                                         //        延时一会
  232.                 if(s1==0)                                         //如果s1确实按下,执行下面程序
  233.                 {        s1num++;                                 //s1num自加1
  234.                         while(!s1);                                 //如果s1松开,执行下面程序,否则一直停在这
  235.                         if(s1num==1)                         //如果s1只按一次,执行下面
  236.                         {
  237.                                 write_com(0x80+13);       //设置当前指针位置
  238.                                 write_com(0x0f);                  //写入光标闪烁命令
  239.                         }
  240.                         if(s1num==2)                                  //如果s1按2次,执行下面
  241.                         {
  242.                                 write_com(0x80+0x40+13);  //设置当前指针位置,光标闪
  243.                         }
  244.                         if(s1num==3)                                  //如果s1按3次,执行下面
  245.                         {        s1num=0;                                  //s1num清0
  246.                                 write_com(0x0c);              //写入光标不闪烁命令
  247.                         }
  248.                 }
  249.         }
  250.         
  251.         if(s2==0)                                                          //如果s2按下,执行下面程序
  252.         {        delay(5);                                                  //延时
  253.                 if(s2==0);                                                  //如果s2按下,执行下面程序
  254.                 {               
  255.                                 while(!s2);                                  //如果s2松开,执行下面程序,否则一直停在这
  256.                                 if(s1num==1)                          //如果光标在h的位置闪烁,执行下面程序
  257.                                 {        h++;                                  //h加1
  258.                                         if(h==127)                            //=127清0
  259.                                         h=0;                                 
  260.                                         figh=0;                                  //设置figh=0,符号为正
  261.                                         t=figh;                                  //赋值给t,以便液晶显示
  262.                                         if(h<=-1)                          //如果h为负数
  263.                                         {figh=1;                          //设置figh=0
  264.                                          t=figh;                          //赋值给t,以便液晶显示
  265.                                          h=abs(h);                          //h取绝对值
  266.                                          write_hl(11,h);          //h写入LCD
  267.                                          h=0-h;                                  //把h变回原来的负数
  268.                                         }
  269.                                         else{write_hl(11,h);} //否则h写入LCD
  270.                                         write_com(0x80+13);          //光标在温度值位置闪烁
  271.                                 }
  272.                                 if(s1num==2)                          //如果光标在l的位置闪烁,执行下面程序
  273.                                 {        l++;                                 
  274.                                         if(l==127)                           
  275.                                         l=0;
  276.                                         figl=0;
  277.                                         t=figl;
  278.                                         if(l<=-1)
  279.                                         {figl=1;
  280.                                          t=figl;
  281.                                          l=abs(l);
  282.                                          write_hl(0x40+11,l);         
  283.                                          l=0-l;
  284.                                         }
  285.                                         else{write_hl(0x40+11,l);}         
  286.                                         write_com(0x80+0x40+13);        
  287.                                 }
  288.                 }
  289.         }
  290.         if(s3==0)                                                          //如果s3按下,执行下面程序
  291.         {        delay(5);                                                  //延时
  292.                 if(s3==0);
  293.                 {
  294.                                 while(!s3);                                  //s3松开后,执行下面程序
  295.                                 if(s1num==1)                          //如果光标在h的位置闪烁,执行下面程序
  296.                                 {        h--;                                  //h自减1
  297.                                         if(h==-55)                          //如果h=-55清0
  298.                                         h=0;
  299.                                         figh=0;                                  //设置figh=0,温度值为正
  300.                                         t=figh;                                  //赋值给t,以便液晶显示
  301.                                         if(h<=-1)                          //如果h温度值为负数
  302.                                         {figh=1;                          //设置figh=1
  303.                                          t=figh;                          //赋值给t,以便液晶显示
  304.                                          h=abs(h);                          //h取绝对值
  305.                                          write_hl(11,h);          //h写入LCD
  306.                                          h=0-h;                                  //把h变回原来的负数
  307.                                         }
  308.                                         else{write_hl(11,h);} //否则h写入LCD         
  309.                                         write_com(0x80+13);          //光标在温度值位置闪烁
  310.                                 }                 
  311.                                 if(s1num==2)
  312.                                 {        l--;
  313.                                         if(l==-55)
  314.                                         h=0;
  315.                                         figl=0;
  316.                                         t=figl;
  317.                                         if(l<=-1)
  318.                                         {figl=1;
  319.                                          t=figl;
  320.                                          l=abs(l);
  321.                                          write_hl(0x40+11,l);         
  322.                                          l=0-l;
  323.                                         }
  324.                                         else{write_hl(0x40+11,l);}         
  325.                                         write_com(0x80+0x40+13);
  326.                                 }
  327.                 }
  328.         }               
  329. }        
  330. void comp()                                                                //温度值报警程序
  331. {if(fig==1&&temp_value>=h)                                //如果读取温度值为正
  332. D1=0;
  333. if(fig==1&&temp_value<=h)                                //如果读取温度值为正
  334. D1=1;
  335.          if(fig==0)                                                        //如果读取温度值为负
  336.          {  if(figh==0)                                                //如果设置最高值温度值为正
  337.                  D1=1;  
  338.                  if(figh==1)                                                //如果设置最高值温度值为负
  339.                   {h=abs(h);
  340.                    if(temp_value<=h)
  341.                    D1=0;
  342.                    if(temp_value>=h)
  343.                    D1=1;
  344.                    h=-h;         
  345.                   }
  346.          }
  347. if(fig==1&&temp_value<=l)
  348. D2=0;
  349. if(fig==1&&temp_value>=l)
  350. D2=1;            
  351. if(fig==0)
  352.                 {         if(figl==0)
  353.                          D2=0;
  354.                          if(figl==1)
  355.                          {l=abs(l);
  356.                           if(temp_value>=l)
  357.                           D2=0;
  358.                           if(temp_value<=l)
  359.                           D2=1;
  360.                           l=-l;
  361.                          }
  362.                 }               
  363. }                     
复制代码

所有资料51hei提供下载:
http://www.51hei.com/bbs/dpj-132660-1.html


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:453846 发表于 2018-12-24 20:51 | 只看该作者
谢谢分享
回复

使用道具 举报

板凳
ID:457979 发表于 2018-12-29 13:37 | 只看该作者
请问一下要将温度的小数位也显示,并且使用2个DS18B20芯片,在程序上应该怎样修改
回复

使用道具 举报

地板
ID:549781 发表于 2019-5-28 23:25 来自手机 | 只看该作者
怎么把led灯超过上下限的亮换成蜂鸣器的声
回复

使用道具 举报

5#
ID:555560 发表于 2019-6-5 15:07 | 只看该作者
谢谢大佬分享,额。。。仿真的时候蜂鸣器不会响怎么解决啊
回复

使用道具 举报

6#
ID:573405 发表于 2019-6-27 14:30 | 只看该作者
感谢分享
回复

使用道具 举报

7#
ID:628356 发表于 2019-10-26 17:07 | 只看该作者
不错谢谢
回复

使用道具 举报

8#
ID:641486 发表于 2019-12-27 20:09 | 只看该作者
不错感谢
回复

使用道具 举报

9#
ID:313619 发表于 2019-12-27 21:44 | 只看该作者
膜拜大佬,应该向大佬学习&#128591;
回复

使用道具 举报

10#
ID:313619 发表于 2019-12-27 21:45 | 只看该作者
膜拜大佬&#128591;学习
回复

使用道具 举报

11#
ID:313619 发表于 2019-12-27 21:45 | 只看该作者
膜拜大佬,应该向大佬&#128591;
回复

使用道具 举报

12#
ID:678509 发表于 2020-1-3 07:46 | 只看该作者
学渣党的福音
回复

使用道具 举报

13#
ID:681391 发表于 2020-1-5 08:23 | 只看该作者
谢谢分享
回复

使用道具 举报

14#
ID:680260 发表于 2020-1-6 14:23 | 只看该作者
谢谢分享
回复

使用道具 举报

15#
ID:388764 发表于 2020-1-10 20:11 | 只看该作者
我的资料  截图都不带改的
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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