当前位置:   article > 正文

通过stm32读取DS18B20并在显示屏上显示温度值(附源码)_ds18b20 stm32

ds18b20 stm32

目录

一、前言

二、传感器概述

2.1 传感器简介

2.2 引脚说明

 2.3 读时序

2.4 写时序

2.5 DS18B20的特性

2.6 相关电气特性

三、接线说明

四、程序编写

4.1 DS18B20.C

4.2 DS18B20.H

4.3 读取DS8B20温度值并显示在OLED显示屏上

4.4 main函数代码

五、最终效果


 

 

一、前言

使用stm32f103c8t6的芯片,在OLED显示屏上显示DS18B20的温度值。

二、传感器概述

2.1 传感器简介

DS18B20 数字温度计提供 9 位温度读数,指示器件的温度信息经过单线接口送入 DS18B20 或从 DS18B20 送出, 因此从中央处理器到 DS18B20 仅需连接一条线。 读、写和完成温度变换所需的电源可以由数据线本身提供而不需要外部电源。
19f3201199724f5a8207c070200f1651.png

2.2 引脚说明

ca7374ee744049caa8cfe616e7c51713.png

 

 2.3 读时序

0211fd1044fb4fc2b9025def91870933.png

2.4 写时序

4abd49952bb14bdfa51d6af7a763521c.png

2.5 DS18B20的特性

1.独特的单线接口 ,只需 1 个接口引脚即可通信。
2.每个设备的内部ROM上都烧写了一个独一无二的64位序列号。
3无需外部元件。
4.能够采用数据线供电,供电范围为3.0V至5.5V。
5.温度可测量范围为:-55℃至+125℃(-67℉至+257℉)。
6.温度范围超过-10℃至85℃之外时测温分辨率0.5℃。
7.以 9 位数字值方式读出温度。
8.在 1 秒( 典型值 )内把温度变换为数字。
9.用户可定义的 非易失性的温度告警设置。
10.告警搜索命令识别和寻址温度在编定的极限之外的器件(温度告警情况)。
11.应用范围包括恒温控制 工业系统 消费类产品 温度计或任何热敏系统。

 

2.6 相关电气特性

 
cd53b3a5ff2147b5a7dd59ce1232bf73.png

 

三、接线说明

88c411978db94731b96c9cf00956f82b.png

本文使用的是stm32f103c8的芯片,VCC接3.3V,信号线接PB12 引脚。

 

四、程序编写

4.1 DS18B20.C

  1. #include "ds18b20.h"
  2. #include "stm32f10x.h"
  3. /**************************************************************************************
  4. * 描 述 : 配置DS18B20用到的I/O口
  5. * 入 参 : 无
  6. * 返回值 : 无
  7. **************************************************************************************/
  8. static void DS18B20_GPIO_Config(void)
  9. {
  10. GPIO_InitTypeDef GPIO_InitStructure;
  11. RCC_APB2PeriphClockCmd(DS18B20_CLK, ENABLE);
  12. GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
  13. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  15. GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
  16. GPIO_SetBits(DS18B20_PORT, DS18B20_PIN); //DS18B20数据引脚初始化配置为高电平输出
  17. }
  18. /**************************************************************************************
  19. * 描 述 : 配置使DS18B20-DATA引脚变为输入模式
  20. * 入 参 : 无
  21. * 返回值 : 无
  22. **************************************************************************************/
  23. static void DS18B20_Mode_IPU(void)
  24. {
  25. GPIO_InitTypeDef GPIO_InitStructure;
  26. GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
  27. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
  28. GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
  29. }
  30. /**************************************************************************************
  31. * 描 述 : 配置使DS18B20-DATA引脚变为输出模式
  32. * 入 参 : 无
  33. * 返回值 : 无
  34. **************************************************************************************/
  35. static void DS18B20_Mode_Out_PP(void)
  36. {
  37. GPIO_InitTypeDef GPIO_InitStructure;
  38. GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
  39. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  40. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  41. GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
  42. }
  43. /**************************************************************************************
  44. * 描 述 : 主机给从机发送复位脉冲
  45. * 入 参 : 无
  46. * 返回值 : 无
  47. **************************************************************************************/
  48. static void DS18B20_Rst(void)
  49. {
  50. DS18B20_Mode_Out_PP(); //主机设置为推挽输出
  51. DS18B20_DATA_OUT(LOW); //主机至少产生480us的低电平复位信号
  52. Delay_us(750);
  53. DS18B20_DATA_OUT(HIGH); //主机在产生复位信号后,需将总线拉高
  54. Delay_us(15); //从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
  55. }
  56. /**************************************************************************************
  57. * 描 述 : 检测从机给主机返回的存在脉冲
  58. * 入 参 : 无
  59. * 返回值 : 0:成功 1:失败
  60. **************************************************************************************/
  61. static u8 DS18B20_Presence(void)
  62. {
  63. u8 pulse_time = 0;
  64. DS18B20_Mode_IPU(); //主机设置为上拉输入
  65. /* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号
  66. * 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
  67. */
  68. while( DS18B20_DATA_IN() && pulse_time<100 )
  69. {
  70. pulse_time++;
  71. Delay_us(1);
  72. }
  73. if( pulse_time >=100 ) //经过100us后,存在脉冲都还没有到来
  74. return 1; //读取失败
  75. else //经过100us后,存在脉冲到来
  76. pulse_time = 0; //清零计时变量
  77. while( !DS18B20_DATA_IN() && pulse_time<240 ) // 存在脉冲到来,且存在的时间不能超过240us
  78. {
  79. pulse_time++;
  80. Delay_us(1);
  81. }
  82. if( pulse_time >=240 ) // 存在脉冲到来,且存在的时间超过了240us
  83. return 1; //读取失败
  84. else
  85. return 0;
  86. }
  87. /**************************************************************************************
  88. * 描 述 : 从DS18B20读取一个bit
  89. * 入 参 : 无
  90. * 返回值 : u8
  91. **************************************************************************************/
  92. static u8 DS18B20_Read_Bit(void)
  93. {
  94. u8 dat;
  95. /*0和读1的时间至少要大于60us */
  96. DS18B20_Mode_Out_PP();
  97. /* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */
  98. DS18B20_DATA_OUT(LOW);
  99. Delay_us(10);
  100. /* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */
  101. DS18B20_Mode_IPU();
  102. if( DS18B20_DATA_IN() == SET )
  103. dat = 1;
  104. else
  105. dat = 0;
  106. /* 这个延时参数请参考时序图 */
  107. Delay_us(45);
  108. return dat;
  109. }
  110. /**************************************************************************************
  111. * 描 述 : 从DS18B20读一个字节,低位先行
  112. * 入 参 : 无
  113. * 返回值 : u8
  114. **************************************************************************************/
  115. u8 DS18B20_Read_Byte(void)
  116. {
  117. u8 i, j, dat = 0;
  118. for(i=0; i<8; i++)
  119. {
  120. j = DS18B20_Read_Bit(); //从DS18B20读取一个bit
  121. dat = (dat) | (j<<i);
  122. }
  123. return dat;
  124. }
  125. /**************************************************************************************
  126. * 描 述 : 写一个字节到DS18B20,低位先行
  127. * 入 参 : u8
  128. * 返回值 : 无
  129. **************************************************************************************/
  130. void DS18B20_Write_Byte(u8 dat)
  131. {
  132. u8 i, testb;
  133. DS18B20_Mode_Out_PP();
  134. for( i=0; i<8; i++ )
  135. {
  136. testb = dat&0x01;
  137. dat = dat>>1;
  138. /*0和写1的时间至少要大于60us */
  139. if (testb)
  140. {
  141. DS18B20_DATA_OUT(LOW);
  142. Delay_us(8); //1us < 这个延时 < 15us
  143. DS18B20_DATA_OUT(HIGH);
  144. Delay_us(58); //58us+8us>60us
  145. }
  146. else
  147. {
  148. DS18B20_DATA_OUT(LOW);
  149. /* 60us < Tx 0 < 120us */
  150. Delay_us(70);
  151. DS18B20_DATA_OUT(HIGH);
  152. /* 1us < Trec(恢复时间) < 无穷大*/
  153. Delay_us(2);
  154. }
  155. }
  156. }
  157. /**************************************************************************************
  158. * 描 述 : 起始DS18B20
  159. * 入 参 : 无
  160. * 返回值 : 无
  161. **************************************************************************************/
  162. void DS18B20_Start(void)
  163. {
  164. DS18B20_Rst(); //主机给从机发送复位脉冲
  165. DS18B20_Presence(); //检测从机给主机返回的存在脉冲
  166. DS18B20_Write_Byte(0XCC); // 跳过 ROM
  167. DS18B20_Write_Byte(0X44); // 开始转换
  168. }
  169. /**************************************************************************************
  170. * 描 述 : DS18B20初始化函数
  171. * 入 参 : 无
  172. * 返回值 : u8
  173. **************************************************************************************/
  174. u8 DS18B20_Init(void)
  175. {
  176. DS18B20_GPIO_Config();
  177. DS18B20_Rst();
  178. return DS18B20_Presence();
  179. }
  180. /**************************************************************************************
  181. * 描 述 : 从DS18B20读取温度值
  182. * 入 参 : 无
  183. * 返回值 : float
  184. **************************************************************************************/
  185. float DS18B20_Get_Temp(void)
  186. {
  187. u8 tpmsb, tplsb;
  188. short s_tem;
  189. float f_tem;
  190. DS18B20_Rst();
  191. DS18B20_Presence();
  192. DS18B20_Write_Byte(0XCC); /* 跳过 ROM */
  193. DS18B20_Write_Byte(0X44); /* 开始转换 */
  194. DS18B20_Rst();
  195. DS18B20_Presence();
  196. DS18B20_Write_Byte(0XCC); /* 跳过 ROM */
  197. DS18B20_Write_Byte(0XBE); /* 读温度值 */
  198. tplsb = DS18B20_Read_Byte();
  199. tpmsb = DS18B20_Read_Byte();
  200. s_tem = tpmsb<<8;
  201. s_tem = s_tem | tplsb;
  202. if( s_tem < 0 ) /* 负温度 */
  203. f_tem = (~s_tem+1) * 0.0625;
  204. else
  205. f_tem = (s_tem * 0.0625);
  206. //这样做的目的将小数点后第一位也转换为可显示数字
  207. //同时进行一个四舍五入操作。
  208. return f_tem;
  209. }
  210. /*************************************END OF FILE******************************/

4.2 DS18B20.H

  1. #ifndef __DS18B20_H
  2. #define __DS18B20_H
  3. #include "stm32f10x.h"
  4. #include "delay.h"
  5. #define HIGH 1
  6. #define LOW 0
  7. #define DS18B20_CLK RCC_APB2Periph_GPIOB
  8. #define DS18B20_PIN GPIO_Pin_12
  9. #define DS18B20_PORT GPIOB
  10. //带参宏,可以像内联函数一样使用,输出高电平或低电平
  11. #define DS18B20_DATA_OUT(a) if (a) \
  12. GPIO_SetBits(GPIOB,GPIO_Pin_12);\
  13. else \
  14. GPIO_ResetBits(GPIOB,GPIO_Pin_12)
  15. //读取引脚的电平
  16. #define DS18B20_DATA_IN() GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)
  17. typedef struct
  18. {
  19. u8 humi_int; //湿度的整数部分
  20. u8 humi_deci; //湿度的小数部分
  21. u8 temp_int; //温度的整数部分
  22. u8 temp_deci; //温度的小数部分
  23. u8 check_sum; //校验和
  24. }DS18B20_Data_TypeDef;
  25. u8 DS18B20_Init(void);
  26. float DS18B20_Get_Temp(void);
  27. #endif /* __DS18B20_H */

4.3 读取DS8B20温度值并显示在OLED显示屏上

  1. void TEMP_Value_Conversion()
  2. {
  3. temp_data=DS18B20_Get_Temp();
  4. temp_data1=temp_data;
  5. sprintf((char*)ucbuf,"%4.2f",temp_data1);
  6. OLED_ShowString(72,48,(uint8_t*)ucbuf,16,1);
  7. OLED_ShowChinese(0,48,0,16,1);
  8. OLED_ShowChinese(16,48,1,16,1);
  9. OLED_ShowChinese(32,48,2,16,1);
  10. OLED_ShowChinese(48,48,3,16,1);
  11. OLED_ShowChar(64,48,':',16,1);
  12. OLED_ShowChinese(112,48,4,16,1);
  13. }

4.4 main函数代码

  1. main (void)
  2. {
  3. /* 配置系统时钟为72M */
  4. SystemInit();
  5. DS18B20_Init();
  6. OLED_Init();
  7. OLED_ColorTurn(0);//0正常显示,1 反色显示
  8. OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
  9. OLED_ShowChinese(48,16,3,16,1);
  10. while(1)
  11. {
  12. OLED_Refresh();
  13. TEMP_Value_Conversion();
  14. Delay_ms(500);
  15. }
  16. }

其中OLED的配置程序及接线参考之前的文章https://blog.csdn.net/qq_50749196/article/details/131022176

 

五、最终效果

我这里使用的是贴片式DS18B20温度传感器(图片上方蓝色线头),OLED显示的温度保留小数点后两位数字。

a9d065f8e1884a408f9ebc5f132458b0.jpeg

 

完整程序已上传,有需要者自行下载:

链接:https://pan.baidu.com/s/1KbtNQGjrHjWSbZUC1efnSA?pwd=ydlz 
提取码:ydlz

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/669802
推荐阅读
相关标签
  

闽ICP备14008679号