基于DS18B20的多点温度测试系统

[复制链接]
2380|27
 楼主| jerow 发表于 2020-3-30 21:54 | 显示全部楼层 |阅读模式
一、简介:
748505e81fa069b23c.png
图示有字的一面,注意GND和VCC不要接反。工作电压3.0v~5.5V,采集温度-55度到正125度,可编程温度9-12位,精度分别是0.5度,0.25度,0.125度0.0625度,默认都是12位,12位转换时间是750ms,9位是93.75ms,电压负压特性(不会因电源接反发热烧坏)。



 楼主| jerow 发表于 2020-3-30 21:54 | 显示全部楼层
二、电路连接:
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xlbmd5dWVmZW5nMjEy,size_16,color_FFFFFF,t_70.jpg
接一个上拉电阻。


 楼主| jerow 发表于 2020-3-30 21:55 | 显示全部楼层
三、通信方式:
单总线通信:
单总线是一种具有一个总线主机和一个或若干个从机的系统。严格按照器件的时间要求进行复位,写命令,读写数据等。整个过程在一条线上进行。


 楼主| jerow 发表于 2020-3-30 21:56 | 显示全部楼层
四、DS18B20的内部结构:
630365e81fa7f74d2b.png
64位光刻ROM,温度传感器,非易失性的温度报警触发器TH和TL,配置寄存器。出厂前ROM的排列是:开始8位产品类型标号(28H),接着48位是DS18B20全球唯一序列号,最后8位是前面56位的循环冗余校验码。
DS18B20存储器:
176455e81fa8f6386b.png
Byte0和Byte1分别存储温度寄存器的低字节和高字节,这两个字节是只读的。我们一般只操作这两个字节。
114145e81faa0280ef.png


 楼主| jerow 发表于 2020-3-30 21:57 | 显示全部楼层
五、DS18B20的指令:
命令有两种,一种ROM的指令,一种暂存器的指令。
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xlbmd5dWVmZW5nMjEy,size_16,color_FFFFFF,t_70.jpg

 楼主| jerow 发表于 2020-3-30 21:57 | 显示全部楼层
六、操作时序:
分为4个步骤:
1.复位:单片机发一个低电平给DS18B20,DS18B20返回一个低电平给单片机,完成唤醒握手。
2.发送ROM命令
3.发送暂存器指令
4.发送数据或接受数据
 楼主| jerow 发表于 2020-3-30 21:58 | 显示全部楼层
单个温度测试代码:
  1. #include<All.h>
  2. uchar xdata DS18B20_Buffer[2]=0;//保存温度的数据
  3. void Delay500us()                //@24.000MHz
  4. {
  5.         unsigned char i, j;
  6.         i = 16;
  7.         j = 147;
  8.         do
  9.         {
  10.                 while (--j);
  11.         } while (--i);
  12. }
  13. void Delay80us()                //@24.000MHz
  14. {
  15.         unsigned char i, j;
  16.         _nop_();
  17.         _nop_();
  18.         i = 3;
  19.         j = 123;
  20.         do
  21.         {
  22.                 while (--j);
  23.         } while (--i);
  24. }
  25. void Delay60us()                //@24.000MHz
  26. {
  27.         unsigned char i, j;
  28.         _nop_();
  29.         i = 2;
  30.         j = 220;
  31.         do
  32.         {
  33.                 while (--j);
  34.         } while (--i);
  35. }
  36. void Delay10us()                //@24.000MHz
  37. {
  38.         unsigned char i;
  39.         i = 78;
  40.         while (--i);
  41. }
  42. void Delay2us()                //@24.000MHz
  43. {
  44.         unsigned char i;
  45.         i = 14;
  46.         while (--i);
  47. }
  48. /*********************************
  49. * @函数名:DS18B20_Reset
  50. * @描   述:复位
  51. * @说   明:
  52. * @参   数:无
  53. * @返回值:无
  54. *********************************/
  55. void DS18B20_Reset()
  56. {
  57.     DS18B20_DQ=0;//总线拉低
  58.         Delay500us();//保持500us
  59.         DS18B20_DQ=1;//短暂拉高
  60.         Delay80us();//80us

  61.         //等待拉低
  62.         Delay500us();//返回一个106us的低电平
  63.         DS18B20_DQ=1;
  64.         _nop_();//短暂拉高
  65.         _nop_();
  66. }
  67. /*********************************
  68. * @函数名:DS18B20_Write_Com
  69. * @描   述:写寄存器指令
  70. * @说   明:
  71. * @参   数:dat 要写入的数据
  72. * @返回值:无
  73. *********************************/
  74. void DS18B20_Write_Com(uchar com)
  75. {
  76.         uchar idata i;
  77.         for(i=0;i<8;i++)
  78.         {
  79.       DS18B20_DQ=0;
  80.            Delay10us();//先拉低15us
  81.                 _nop_();
  82.                 DS18B20_DQ=(bit)(com&0x01);//先发低位
  83.                 com>>=1;//移位
  84.                 Delay60us();//继续拉低15us
  85.                 DS18B20_DQ=1;//短暂拉高
  86.                 Delay2us();
  87.         }
  88. }
  89. /*********************************
  90. * @函数名:DS18B20_Read_Data
  91. * @描   述:读数据
  92. * @说   明:
  93. * @参   数:无
  94. * @返回值:dat  读出的数据
  95. *********************************/
  96. uchar DS18B20_Read_Data()
  97. {
  98.         uchar idata i,value;
  99.         for(i=0;i<8;i++)
  100.         {
  101.          DS18B20_DQ=0;
  102.                 Delay10us();
  103.                 value>>=1;
  104.          DS18B20_DQ=1;
  105.                 //Ds18B20会返回值。,无论是0还是1,都延迟15us
  106.          Delay2us();
  107.         //        Delay15us();//先拉低15us
  108.                 if(DS18B20_DQ)//是1
  109.                         value|=0x80;//最低位
  110.                 Delay60us();
  111.         }
  112. return value;
  113. }
  114. /*********************************
  115. * @函数名:DS18B20_Handle
  116. * @描   述:温度处理
  117. * @说   明:1. 复位 2.发送ROM命令 3.发送暂存器指令 读RAM 4.数据
  118. * @参   数:无
  119. * @返回值:无
  120. *********************************/
  121. void DS18B20_Handle()
  122. {
  123.         uchar xdata value_High,value_Low;
  124.         float num;//保存小数
  125.     DS18B20_Reset();//复位
  126.         DS18B20_Write_Com(0xcc);//发送指令CCH,跳过ROM操作
  127.         //DS18B20_Write_Com(0x33);//读64位ROM
  128.         DS18B20_Write_Com(0x44);//发送指令44H,启动温度转换
  129.         Delay10us();
  130.         DS18B20_Reset();//复位
  131.         DS18B20_Write_Com(0xcc);//发送指令CCH,跳过ROM操作
  132.         DS18B20_Write_Com(0xbe);//发送指令BEH,读取9字节RAM数据的前两个数据
  133.         Delay10us();
  134.         value_Low=DS18B20_Read_Data();//先读低字节Byte0
  135.         value_High=DS18B20_Read_Data();//高字节Byte1
  136.        
  137.         value_High<<=4;//整数的高3位
  138.         value_High+=(value_Low&0xf0)>>4;//整数的低4位
  139.         DS18B20_Buffer[0]=value_High;//整数
  140.         num=(value_Low&0x0f)*0.0625;//小数
  141.         DS18B20_Buffer[1]=(uchar)(num*100);//小数
  142. }
 楼主| jerow 发表于 2020-3-30 22:00 | 显示全部楼层
多点测试:(两个)
步骤:
1.先读出每个传感器的唯一ROM序列;
  1. /*********************************
  2. * @函数名:DS18B20_Read_64Rom
  3. * @描   述:读64位的ROM 唯一标识
  4. * @说   明:
  5. * @参   数:*buffer 读出的8个字节的数据
  6. * @返回值:无
  7. *********************************/
  8. void DS18B20_Read_64Rom(uchar *buffer)
  9. {
  10.           uchar i;
  11.     DS18B20_Reset();//复位
  12.         DS18B20_Write_Com(0x33);//读64位ROM
  13.         for(i=0;i<8;i++) //读取64个字节
  14.          buffer[i]=DS18B20_Read_Data();
  15. }
191225e81fb4d336e9.png
2.用两个数组存读出来的序列号:
20200330140458714.jpg
3.写入ROm序列号,并启动转换温度:
  1. /*********************************
  2. * @函数名:DS18B20_Write_Rom
  3. * @描   述:写64ROM
  4. * @说   明:发送匹配ROM命令 0x55再写入8字节的ROM
  5. * @参   数:*buffer 要发送的存放ROM的数组
  6. * @返回值:无
  7. *********************************/
  8. void DS18B20_Write_Rom(uchar *buffer)
  9. {
  10.         uchar i;
  11.    DS18B20_Write_Com(0x55); //ROM匹配
  12.         for(i = 0;i < 8;i++)
  13.         DS18B20_Write_Com(buffer[i]); //写入8个字节的ROM
  14. }
  15. /*********************************
  16. * @函数名:DS18B20_Handle
  17. * @描   述:温度处理
  18. * @说   明:1. 复位 2.发送ROM命令 3.发送暂存器指令 读RAM 4.数据
  19. * @参   数:无
  20. * @返回值:无
  21. *********************************/
  22. void DS18B20_Handle(uchar *buffer)
  23. {
  24.         uchar xdata value_High,value_Low;
  25.         float num;//保存小数
  26.     DS18B20_Reset();//复位
  27.         //DS18B20_Write_Com(0xcc);//发送指令CCH,跳过ROM操作
  28.         //DS18B20_Write_Com(0x33);//读64位ROM
  29.     DS18B20_Write_Rom(buffer); //匹配ROM 并写入64ROM
  30.         DS18B20_Write_Com(0x44);//发送指令44H,启动温度转换
  31.         Delay10us();
  32.         DS18B20_Reset();//复位
  33.          DS18B20_Write_Rom(buffer); //匹配ROM 并写入64ROM
  34.         DS18B20_Write_Com(0xbe);//发送指令BEH,读取9字节RAM数据的前两个数据
  35.         Delay10us();
  36.         value_Low=DS18B20_Read_Data();//先读低字节Byte0
  37.         value_High=DS18B20_Read_Data();//高字节Byte1
  38.        
  39.         value_High<<=4;//整数的高3位
  40.         value_High+=(value_Low&0xf0)>>4;//整数的低4位
  41.         DS18B20_Buffer[0]=value_High;//整数
  42.         num=(value_Low&0x0f)*0.0625;//小数
  43.         DS18B20_Buffer[1]=(uchar)(num*100);//小数
  44. }


 楼主| jerow 发表于 2020-3-30 22:02 | 显示全部楼层
其他的都和单个测试是一样的。
测试结果:
129365e81fbaf575ef.png
另外附上主函数:
  1. /*********************************
  2. * @函数名:main
  3. * @描   述:main函数,程序入口
  4. * @说   明:
  5. * @参   数:无
  6. * @返回值:无
  7. *********************************/
  8. void main()
  9. {
  10.         //uchar a[8];//存放读出来的ROM
  11.         Uart1_Init();//串口初始化
  12.         Send_String("多点温度测试:\n");
  13.   while(1)
  14.         {
  15.             DS18B20_Handle(DS18B20_Rom1);
  16.                 printf("温度1:%bd.%bd",DS18B20_Buffer[0],DS18B20_Buffer[1]);//串口打印温度
  17.         putchar_End();//换行
  18. //                DS18B20_Read_64Rom(a);
  19. //                Send_String(a);
  20.             Delay1000ms();
  21.                 DS18B20_Handle(DS18B20_Rom2);
  22.                 printf("温度2:%bd.%bd",DS18B20_Buffer[0],DS18B20_Buffer[1]);//串口打印温度
  23.                 Delay1000ms();
  24.                  putchar_End();//换行
  25.         }
  26. }

paotangsan 发表于 2020-4-7 14:12 | 显示全部楼层
非常感谢楼主分享
renzheshengui 发表于 2020-4-7 14:12 | 显示全部楼层
非常感谢楼主分享
wakayi 发表于 2020-4-7 14:12 | 显示全部楼层
非常感谢楼主分享
wowu 发表于 2020-4-7 14:12 | 显示全部楼层
非常感谢楼主分享
xiaoqizi 发表于 2020-4-7 14:12 | 显示全部楼层
非常感谢楼主分享
iot123 发表于 2020-12-17 17:14 | 显示全部楼层
请问楼主的程序是在什么硬件和软件环境下运行的?
ktdm1314 发表于 2022-3-16 13:50 | 显示全部楼层
value值?
从哪来的?
billzhang331 发表于 2022-3-18 12:05 来自手机 | 显示全部楼层
本帖最后由 billzhang331 于 2022-3-18 12:07 编辑

有个问题,如果多个18B20接入同一网络,如何识别?
如果需要接入前单个读出ID,再修改主站程序,是否太麻烦?客户更换备品备件时操作步骤太多了
天意无罪 发表于 2022-3-19 18:10 | 显示全部楼层
这年头还有用DS1302来测温得吗?现在主要都是硅基传感器测温了.
sparrow054 发表于 2022-4-1 15:15 | 显示全部楼层
不知道一致性和可靠性怎么样
zps136631 发表于 2022-4-2 16:20 | 显示全部楼层
多谢分享!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

72

主题

520

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部