找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于DS18B20的温度传感器设计 有程序详细解释

[复制链接]
跳转到指定楼层
楼主
基于DS18B20的温度传感器设计,有程序详细解释,适合初学者。


  1. /*******************************************************************
  2.                                                 基于DS18B20的温度传感器设计
  3.                                                 版本号:    V1.0;2016.9.19
  4.                                                 温度传感器:DS18B20
  5.                                                 显示方式:   LCD1602
  6. ********************************************************************/
  7. #include<reg52.h>
  8. #include <intrins.h>
  9. #define uchar unsigned char
  10. #define uint unsigned int

  11. sbit DQ=P1^6;//ds18b20与单片机连接口
  12. sbit RS=P1^0;
  13. sbit RW=P1^1;
  14. sbit EN=P1^2;
  15. sbit BEEP = P1^7;

  16. uchar code str1[]={" Temperature is   "};
  17. uchar code str2[]={"     designer:    "};
  18. uchar code str3[]={"     xzf586"       };
  19. uchar data disdata[5];
  20. uchar p=0;
  21. uint tvalue;//温度值
  22. uchar tflag;//温度正负标志

  23. /*******************************************************************
  24.                                                 lcd1602程序
  25. 1:延时
  26. 2:读数据(因为没有忙检测,本程序没有)
  27. 3:忙检测(本程序没有)
  28. 4: 写指令
  29. 5:写数据
  30. 6: 初始化
  31. ********************************************************************/

  32. void delay1ms(uint ms)//延时1毫秒
  33. {
  34.         uint i,j;
  35.         for(i=0;i<ms;i++)
  36.         for(j=0;j<114;j++);
  37. }

  38. void wr_com(uchar com)//写指令//
  39. {
  40.         delay1ms(1);
  41.         RS=0;
  42.         RW=0;
  43.         EN=0;
  44.         P0=com;
  45.         delay1ms(1);
  46.         EN=1;
  47.         delay1ms(1);
  48.         EN=0;
  49. }
  50. void wr_dat(uchar dat)//写数据//
  51. {
  52.         delay1ms(1);
  53.         RS=1;
  54.         RW=0;
  55.         EN=0;
  56.         P0=dat;
  57.         delay1ms(1);
  58.         EN=1;
  59.         delay1ms(1);
  60.         EN=0;
  61. }
  62. void lcd_init()//初始化设置//
  63. {
  64.         wr_com(0x38);delay1ms(5);
  65.         wr_com(0x08);delay1ms(5);
  66.         wr_com(0x01);delay1ms(5);
  67.         wr_com(0x06);delay1ms(5);
  68.         wr_com(0x0c);delay1ms(5);
  69. }


  70. /***************************************************
  71.                                                 报警程序
  72. ****************************************************/
  73. void baojing(void)
  74. {
  75.       unsigned int j;
  76.           BEEP=0;
  77.       for (j = 49; j > 0; j--)//响30ms
  78.        {
  79.          BEEP = ~BEEP; //输出频率800Hz
  80.          delay1ms(10); //延时310us
  81.          }
  82.              BEEP=0;
  83.    }

  84. void display(uchar *p)//显示//
  85. {
  86.         while(*p!='\0')
  87.         {
  88.                 wr_dat(*p);
  89.                 p++;
  90.                 delay1ms(1);
  91.         }
  92. }                                                                        
  93. void init_play()//初始化显示
  94. {
  95.         lcd_init();
  96.         wr_com(0x80);
  97.         display(str2);
  98.         wr_com(0xc0);
  99.         display(str3);
  100.         delay1ms(3000);
  101.         lcd_init();
  102.         wr_com(0x80);
  103.         display(str1);
  104. }


  105. /*******************************************************************
  106.                                                 ds18b20程序
  107. 1:延时
  108. 2:复位
  109. 3:读数据
  110. 4: 写数据
  111. 5:读取温度值并转换(正负)
  112. ********************************************************************/

  113. void delay_18B20(uint i)//延时1微秒
  114. {
  115.    while(i--);
  116. }

  117. void ds1820rst()/*ds1820复位*/
  118. {

  119.         DQ = 1;          //DQ复位
  120.         delay_18B20(4); //延时
  121.         DQ = 0;          //DQ拉低
  122.         delay_18B20(100); //精确延时大于480us
  123.         DQ = 1;          //拉高
  124.         delay_18B20(40);
  125. }

  126. uchar ds1820rd()/*读数据*/
  127. {
  128.         uchar i=0;
  129.         uchar dat = 0;
  130.         for (i=8;i>0;i--)
  131.         {  
  132.                 DQ = 0; //给脉冲信号
  133.             dat>>=1;   //相当于0输入最高位
  134.             DQ = 1; //给脉冲信号
  135.             if(DQ)
  136.             dat|=0x80; //  等价于dat=dat|0x80,dat和0x80做“或”的运算,意思是最高位置1,其它位保持不变,即1输入最高位
  137.             delay_18B20(10);
  138.         }
  139.    return(dat);
  140. }

  141. void ds1820wr(uchar wdata)/*写数据*/
  142. {
  143.         uchar i=0;
  144.         for (i=8; i>0; i--)
  145.         {
  146.                 DQ = 0;
  147.                 DQ = wdata&0x01; //前7位置0,最后一位保持不变,输出
  148.                 delay_18B20(10);
  149.                 DQ = 1;
  150.                 wdata>>=1;                 //倒数第二位到最后一位,继续上面过程,输出
  151.         }
  152. }


  153. /*******************************************************************
  154.                                                 ds18b20温度值规则
  155. 1:b=0000 0111 1101 0000=64+32+16+8+4+1=125度 最大
  156. 2:b=0000 0001 1101 0001=16+8+4+1+2^(-4)=29.0625度
  157. 3:b=0000 0000 0000 0000=0度
  158. 4: b=1111 1111 1111 1000转换 前五位=1,说明负值,其绝对值为取反加1,即0000 0000 0111+1=0000 0000 1000=2^(-1)=0.5
  159. 5:b=1111 1100 1001 0000转换 绝对值为取反加1,即0011 0110 1111+1=0011 0111 0000=-55 最小
  160. 6:15~11是符号位,都为1就是零下;都0就是零上,后10~0 这11位,是温度的实际数据,这个数据乘0.0625就得到温度了(正温度算法)
  161. ********************************************************************/
  162. read_temp()/*读取温度值并转换*/
  163. {
  164.         uint a,b;
  165.         ds1820rst();           //复位
  166.         ds1820wr(0xcc);//*跳过读序列号*/
  167.         ds1820wr(0x44);//*启动温度转换*/
  168.         ds1820rst();   
  169.         ds1820wr(0xcc);//*跳过读序列号*/
  170.         ds1820wr(0xbe);//*读取温度*/
  171.         a=ds1820rd();  //第一次读的低八位,例如125度,则 a=0000 0000 1101 0000
  172.         b=ds1820rd();  //第二次读的高八位,例如125度,则 b=0000 0000 0000 0111
  173.         tvalue=b;                //下面三句是将这两次读的合起来
  174.         tvalue<<=8;                 //若是125,则tvalue<<=8,即tvalue=0000 0111 0000 0000
  175.         tvalue=tvalue|a; //tvalue|a=0000 0111 0000 0000 | 0000 0000 1101 0000=0000 0111 1101 0000
  176. if(tvalue<0x08ff)         //若tvalue是正的,则tvalue<0000 0111 1111 1111,前五位符号都是0
  177.                 tflag=0;
  178.         else
  179.         {
  180.                 tvalue=~tvalue+1;  //负值,取反加1
  181.                 tflag=1;
  182.         }                                                                                                         
  183.         tvalue=tvalue*(0.0625)*10;//温度值扩大10倍,精确到1位小数,注意到负温度已经转换了,因此可以这样算
  184.         return(tvalue);
  185. }
  186. /*******************************************************************/
  187. void ds1820disp()//温度值显示
  188. {
  189.         uchar flagdat;
  190.         disdata[0]=tvalue/1000+0x30;//百位数,0的ASCII码是0x30,以此类推
  191.         disdata[1]=tvalue%1000/100+0x30;//十位数
  192.         disdata[2]=tvalue%100/10+0x30;//个位数
  193.         disdata[3]=tvalue%10+0x30;//小数位
  194.         if(tflag==0)
  195.                 //flagdat=0x20;//正温度不显示符号,空格的ASCII码是0x20
  196.                 flagdat=0x2b;//正温度显示正号,正号的ASCII码是0x2b
  197.         else
  198.         flagdat=0x2d;//负温度显示负号:-

  199.         if(disdata[0]==0x30)  //注意0的ASCII码是0x30,空格的ASCII码是0x20
  200.         {
  201.                 disdata[0]=0x20;//如果百位为0,不显示
  202.                 if(disdata[1]==0x30)
  203.                 {
  204.                         disdata[1]=0x20;//如果百位为0,十位为0也不显示
  205.                 }
  206.         }
  207.         wr_com(0xc0+4);         //LCD第二行,空4格
  208.         wr_dat(flagdat);//显示符号位
  209.         wr_com(0xc1+4);
  210.         wr_dat(disdata[0]);//显示百位
  211.         wr_com(0xc2+4);
  212.         wr_dat(disdata[1]);//显示十位
  213.         wr_com(0xc3+4);
  214.         wr_dat(disdata[2]);//显示个位
  215.         wr_com(0xc4+4);
  216.         wr_dat(0x2e);//显示小数点
  217.         wr_com(0xc5+4);
  218.         wr_dat(disdata[3]);//显示小数位
  219.         wr_com(0xc6+4);
  220.     wr_dat(0x43);           //C的ASCII码是0x43
  221. }
  222. //********************主程序***********************************//
  223. void main()
  224. {         
  225.         BEEP=0;
  226.         init_play();//初始化显示
  227.         while(1)
  228.         {         
  229.                 read_temp();//读取温度
  230.                 ds1820disp();//显示
  231.                 if(read_temp()>950||read_temp()<860)         //报警温度 86~95之间,因为前面乘以10
  232.                 {  
  233.                         baojing() ;
  234.                 }
  235.                 delay1ms(1)        ;
  236.         }
  237. }
复制代码

0.png (184.46 KB, 下载次数: 77)

0.png

基于DS18B20的温度传感器设计.rar

28.61 KB, 下载次数: 22, 下载积分: 黑币 -5

程序

评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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