×
单片机 > 单片机程序设计 > 详情

18B20温度传感器详解

发布时间:2020-06-05 发布时间:
|

数据传感器DS18B20

 编写原因:.....暂略

特性:

1.      单独的单线接口,只需1个接口引脚即可通信;

2.      不需要外部元件;

3.      可用数据线供电;

4.      不需备份电源;

5.      测量范围从-55°C  ~  +125°C, 增量为0.0625°C;

6.      以12位数字值方式读出温度;

7.      在1s内把温度变换为数字;

 


知识点:

1.      每个18B20包括唯一的64位长的序号放在ROM中;

开始8位产品类型编码| 接着48位每个器件唯一序号| 最后8位:前56位的CRC

2.      18B20最小单位刻度是0.0625°C, (这里后面解释)

  

DS18B20的控制流程

根据DS18B20的通信协议,DS18B20只能作为从机,而单片机系统作为主机,片机控制DS18B20完成一次温度转换必须经过3个步骤:

1.     初始化;

2.      发送ROM指令;

3.      发送18B20功能指令。

@以上3个流程还有顺序不能颠倒且缺一不可,每次只要发送任何一条ROM指令,这个流程必须从第1再开始才能发送另外的ROM指令;

一,初始化




  1. /*  

  2. *******************************************************************************  

  3. **  

  4. **                             GPIO_DQ_Out_Mode(void)  

  5. **  

  6. **  

  7. **  功能描述:设置DQ引脚为开漏输出模式  

  8. **  

  9. **  参  数  :无  

  10. **  

  11. **  返回值  :无  

  12. **  

  13. *******************************************************************************  

  14. */  

  15. void GPIO_DQ_Out_Mode(void)  

  16. {  

  17.     GPIO_InitTypeDef GPIO_InitStructure ;  

  18.       

  19.     GPIO_InitStructure.GPIO_Pin = DQ_GPIO_Pin ;  

  20.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;  

  21.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ; //开漏输出  

  22.     GPIO_Init(DQ_GPIO ,&GPIO_InitStructure) ;  

  23. }  

  24.   

  25. /*  

  26. *******************************************************************************  

  27. **  

  28. **                                GPIO_DQ_Input_Mode(void)  

  29. **  

  30. **  

  31. **  功能描述:设置DQ引脚为浮空输入模式  

  32. **  

  33. **  参  数  :无  

  34. **  

  35. **  返回值  :无  

  36. **  

  37. *******************************************************************************  

  38. */  

  39. void GPIO_DQ_Input_Mode(void)  

  40. {  

  41.     GPIO_InitTypeDef GPIO_InitStructure ;  

  42.       

  43.     GPIO_InitStructure.GPIO_Pin = DQ_GPIO_Pin ;  

  44.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;  

  45.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ; //浮空输入  

  46.     GPIO_Init(DQ_GPIO ,&GPIO_InitStructure) ;  

  47. }  

  48.   

  49. /*  

  50. *******************************************************************************  

  51. **                                  Tx_ResetPulse(void)  

  52. **  

  53. **  

  54. **  功能描述:发送复位脉冲  

  55. **  

  56. **  参  数  :无  

  57. **  

  58. **  返回值  :无  

  59. **  

  60. *******************************************************************************  

  61. */  

  62. void Tx_ResetPulse(void)  

  63. {  

  64.    GPIO_DQ_Out_Mode() ;  

  65.       

  66.     DQ_Write_0() ;  //复位脉冲  

  67.     Delay_10us(50) ; //至少保持480us  

  68.     DQ_Write_1() ;  //加速上升沿速度  

  69.     Delay_10us(1) ;  

  70. }  

  71. /*  

  72. *******************************************************************************  

  73. **  

  74. **                              Rx_PresencePulse(void)  

  75. **  

  76. **  

  77. **  功能描述:接受应答信号  

  78. **  

  79. **  参  数  :无  

  80. **  

  81. **  返回值  :无  

  82. **  

  83. *******************************************************************************  

  84. */  

  85. void Rx_PresencePulse(void)  

  86. {  

  87.     GPIO_DQ_Input_Mode() ;  

  88.     while( DQ_ReadBit()) ;  //等待DS18b20应答  

  89.     while( DQ_ReadBit() == 0) ; //DS18b20将总线拉低60~240us ,然后总线由上拉电阻拉高  

  90.     Delay_10us(30) ;  

  91.     GPIO_DQ_Out_Mode() ;    //接受完成,主机重新控制总线  

  92. }  

  93. /*  

  94. *******************************************************************************  

  95. **                                 DS18B20_Init(void)  

  96. **  

  97. **  

  98. **  功能描述:初始化DS18b20  

  99. **  

  100. **  参    数:无  

  101. **   

  102. **  返回值  :无  

  103. **  

  104. *******************************************************************************  

  105. */  

  106. void DS18B20_Init(void)  

  107. {  

  108.     Tx_ResetPulse();  

  109.     Rx_PresencePulse();   

  110. }  



Tx_ResetPulse:函数:主机总线发送复位脉冲

PresencePulse函数:主机读取18B20返回的存在脉冲(电平持续60-240us)


二.写时序




  1. /*  

  2. *******************************************************************************  

  3. **  

  4. **                      Write_OneByte_ToDS18b20(unsigned char data)  

  5. **  

  6. **  

  7. **  功能描述:写一个字节到DS18b20  

  8. **  

  9. **  参  数  :无  

  10. **  

  11. **  返回值  :无  

  12. **  

  13. *******************************************************************************  

  14. */  

  15. void Write_OneByte_ToDS18b20(unsigned char data)  

  16. {  

  17.     unsigned char i ;  

  18.     GPIO_DQ_Out_Mode() ;  

  19.     for(i=0 ;i<8 ;i++)  

  20.     {  

  21.         if(data&0x01)    //低位在前  

  22.         {  

  23.             //写1  

  24.             DQ_Write_0() ; //写时间空隙总是从总线的低电平开始  

  25.             Delay_10us(1) ;  //15us内拉高  

  26.             DQ_Write_1() ;  

  27.             Delay_10us(8) ; //整个写1时隙不低于60us  

  28.         }  

  29.         else  

  30.         {  

  31.             //写0  

  32.             DQ_Write_0() ;  

  33.             Delay_10us(11) ; //保持在60us到120us之间  

  34.             DQ_Write_1() ;  

  35.             Delay_10us(1) ;  

  36.         }  

  37.         data >>= 1 ;  

  38.     }  

  39. }  

写1 还是写0 由15-60us 的电平区分,所以 DQ_write_0函数后延时长是写0, DQ_write_1函数后延时长是写1;


且是从低位开始写, 所以写完后 data>>=1 ;


三.读时序





  1. /*  

  2. *******************************************************************************  

  3. **  

  4. **                       Read_OneByte_FromDS18b20(void)  

  5. **  

  6. **  

  7. **     功能描述:从DS18b20读一个字节  

  8. **  

  9. **     参  数  :无  

  10. **  

  11. **     返回值  :读出的数据  

  12. **  

  13. *******************************************************************************  

  14. */  

  15. unsigned charRead_OneByte_FromDS18b20(void)  

  16. {  

  17.    unsigned char i ,data = 0 ;  

  18.      

  19.    for(i=0 ;i<8 ;i++)  

  20.     {  

  21.        GPIO_DQ_Out_Mode() ;  

  22.        data >>= 1 ;  

  23.        DQ_Write_0() ;  

  24.        Delay_10us(1) ;  

  25.        GPIO_DQ_Input_Mode() ;  

  26.        Delay_10us(1) ;  

  27.        if(DQ_ReadBit())  

  28.        {  

  29.            data |= 0x80 ;  

  30.        }  

  31.        Delay_10us(7) ;   //等待这一位数据完成传输  

  32.     }  

  33.    GPIO_DQ_Out_Mode() ;  

  34.    return data ;  

  35. }  


四.读取温度值和计算


18B20用12位存储温度值,最高位是符号位,下图是其温度存储方式,负温度S=1,正温度S=0;

如:0550H 是+85°C       0191H:+25.0625°C   FC90H是-55°C




  1. /*  

  2. ***************************************************************************************************  

  3. **  

  4. **        Read_Temperature(unsigned char *sign , unsigned char *interger , unsigned int *decimal)  

  5. **  

  6. **  

  7. **  功能描述:读取温度信息  

  8. **  

  9. **  参    数:*sign - 保存符号(零上或零下)  

  10. **            *integer - 保存整数部分  

  11. **            *decimal - 保存小数部分  

  12. **  

  13. **  返回值  :无  

  14. **  

  15. ***************************************************************************************************  

  16. */  

  17. void Read_Temperature(unsigned char *sign , unsigned char *interger , unsigned int *decimal)  

  18. {  

  19.     unsigned char a=0;  

  20.     unsigned char b=0;    

  21.     unsigned int tmp ;  

  22.       

  23.     DS18B20_Init();  

  24.     Write_OneByte_ToDS18b20(ROM_Read_Cmd);  

  25.     

  26.     DS18B20_Init();  

  27.     Write_OneByte_ToDS18b20(ROM_Skip_Cmd);//跳过读序列号操作  

  28.     Write_OneByte_ToDS18b20(Convert_T); //启动温度转换  

  29.     Delay_ms(780);//等待DS18b20转换完成  

  30.       

  31.     DS18B20_Init();  

  32.     Write_OneByte_ToDS18b20(ROM_Skip_Cmd);  

  33.     Write_OneByte_ToDS18b20(Read_Scratchpad); //读取寄存器内容  

  34.       

  35.     a= Read_OneByte_FromDS18b20();     //温度低8位  

  36.     b= Read_OneByte_FromDS18b20();     //温度高8位  

  37.       

  38.     Tx_ResetPulse();  //中断数据读取  

  39.     tmp = (b<<8) | a ;  

  40.     if(b & 0xF0)  

  41.     {  

  42.             *sign = 1 ;              //符号部分  

  43.             tmp = ~tmp+1 ;      //二进制数求补 再换成十进制数得到被测温度值  

  44.     }  

  45.     else   

  46.     {  

  47.             *sign = 0 ;  

  48.     }  

  49.     *interger = (tmp>>4) & 0x00FF;  //整数部分  

  50.     *decimal = (tmp & 0x000F) * 625 ; //小数部分 实际上是乘以0.0625最小步进 同时把小数变成非小数显示  

  51. }  


1.因为上面说过每次只要发送了ROM命令 ,再发其他命令必须重新初始化;


2.将存储器中的二进制数求补后再转换成十进制;





『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Keil(MDK-ARM)系列教程(七)_菜单