你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32CubeMX的DS18B20温度传感器经验分享

[复制链接]
攻城狮Melo 发布时间:2023-7-1 18:38
1.DS18B20简介
DS18B20是由DALLAS半导体公司推出的一种单总线接口的温度传感器,与传统的热敏电阻等测温元件相比,它是一种新型的体积小、用电压宽、与微处理器接口简单的数字化温度传感器。DS18B20的内部结构如下图示

微信图片_20230701183641.png

ROM中的64位序列号是出厂前就被光刻好的,可以看做是DS18B20的地址序列号。64位光刻ROM的排列是:8位产品类型标号+48位DS18B20序列号+8位循环冗余校验码。光刻ROM 的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20

DS18B20的内部存储器(9个字节)包括一个高速暂存器RAM和一个EEPROM,EEPROM里存放高温和低温触发器和配置寄存器,存储器详细组成见下图:

微信图片_20230701183638.png

配置寄存器是配置不同的位数来确定温度和数字的转化,其结构下图示:低五位都是1,TM是测试模式位(设置工作模式或测试模式,默认为0即工作模式),R1和R0用来设置精度,可设9~12位精度,对应的温度分辨率为0.5, 0.25, 0.125, 0.0625℃

微信图片_20230701183635.png

所有的单总线器件都要求采样严格的信号时序,以保证设局的完整性。DS18B20的时序有:初始化时序、写(0和1)时序、读(0和1)时序。DS18B20发送所有的命令和数据都是字节的低位在前,下面介绍这几个信号的时序:
⏩ 初始化时序
内置闪存模块可以在通用地址空间直接寻址,任何32位数据的读操作都能访问闪存模块的内容并得到相应的数据。

微信图片_20230701183632.png

⏩ 写时序
写时序包括写0和写1时序。所有写时序至少需要60us,并且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。写1时序,主机输出低电平,延时2us,然后释放总线,延时60us;写0时序,主机输出低电平,延时60us,然后释放总线,延时2us。写时序图如下

微信图片_20230701183629.png

⏩ 读时序
单总线器件仅在主机发出读时序时,才向主机传输数据,所以在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us,主机在读时序器件必须释放总线,并且在时序起始后的15us之内采样总线状态。典型的读时序过程为,主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us

微信图片_20230701183626.png

DS18B20的典型温度读取过程:复位 --> 发SKIP ROM命令(0XCC) --> 发开始转换命令(0X44) --> 延时 --> 复位 --> 发SKIP ROM命令(0XCC) --> 发读存储器命令(0XBE) --> 连续读出两个字节数据(即温度) --> 结束

2.硬件设计
D1指示灯用来提示系统运行状态,DS18B20温度传感器用来检测环境温度,串口1用来打印温度值
指示灯D1
USART1串口
DS18B20
TIM7(提供us延时)

微信图片_20230701183622.png

3.软件设计
3.1 STM32CubeMX设置
➡️ RCC设置外接HSE,时钟设置为72M
➡️ PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平
➡️ USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位
➡️ PG11设置为GPIO推挽输出模式、上拉、高速
➡️ 激活TIM7,预分频因子设为72-1,向上计数,自动重载值为65535;因此计数器CNT_CLK = 1MHz,计数器周期为1us

微信图片_20230701183619.png

➡️输入工程名,选择路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码

3.2 MDK-ARM软件编程
➡️ 在tim.c文件下实现微秒延时(us)函数
  1. void delay_us(uint16_t us){
  2.   uint16_t differ = 0xffff-us-5;
  3.   //设定TIM7计数器起始值                               
  4.   __HAL_TIM_SET_COUNTER(&htim7,differ);       
  5.   //启动定时器
  6.   HAL_TIM_Base_Start(&htim7);                       
  7.        
  8.   while(differ < 0xffff-5){   //判断
  9.     //查询计数器的计数值
  10.     differ = __HAL_TIM_GET_COUNTER(&htim7);               
  11.   }
  12.   HAL_TIM_Base_Stop(&htim7);
  13. }
复制代码

➡️ 创建按键驱动文件ds18b20.c 和相关头文件ds18b20.h
  1. void DS18B20_IO_IN(void){
  2.   GPIO_InitTypeDef GPIO_InitStructure;
  3.   GPIO_InitStructure.Pin = GPIO_PIN_11;
  4.   GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
  5.   HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);
  6. }

  7. void DS18B20_IO_OUT(void){
  8.   GPIO_InitTypeDef GPIO_InitStructure;
  9.   GPIO_InitStructure.Pin = GPIO_PIN_11;
  10.   GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  11.   GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  12.   HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);
  13. }

  14. void DS18B20_Rst(void){
  15.   DS18B20_IO_OUT();
  16.   DS18B20_DQ_OUT_LOW;
  17.   delay_us(750);
  18.   DS18B20_DQ_OUT_HIGH;
  19.   delay_us(15);
  20. }
  21.        
  22. uint8_t DS18B20_Check(void){
  23.   uint8_t retry = 0;
  24.   DS18B20_IO_IN();
  25.   while(DS18B20_DQ_IN && retry < 200){
  26.     retry++;
  27.     delay_us(1);
  28.   }
  29.        
  30.   if(retry >= 200)
  31.     return 1;
  32.   else
  33.     retry = 0;
  34.        
  35.   while(!DS18B20_DQ_IN && retry < 240){
  36.     retry++;
  37.     delay_us(1);
  38.   }
  39.        
  40.   if(retry >= 240)
  41.     return 1;
  42.        
  43.   return 0;
  44. }

  45. uint8_t DS18B20_Read_Bit(void){
  46.   uint8_t data;
  47.   DS18B20_IO_OUT();
  48.   DS18B20_DQ_OUT_LOW;
  49.   delay_us(2);
  50.   DS18B20_DQ_OUT_HIGH;
  51.   DS18B20_IO_IN();
  52.   delay_us(12);
  53.        
  54.   if(DS18B20_DQ_IN)
  55.     data = 1;
  56.   else
  57.     data = 0;
  58.        
  59.   delay_us(50);
  60.   return data;
  61. }

  62. uint8_t DS18B20_Read_Byte(void){
  63.   uint8_t i,j,data;
  64.   data = 0;
  65.   for(i=1;i<=8;i++){
  66.     j = DS18B20_Read_Bit();
  67.     data = (j<<7)|(data>>1);
  68.   }
  69.   return data;
  70. }

  71. void DS18B20_Write_Byte(uint8_t data){
  72.   uint8_t j;
  73.   uint8_t testb;
  74.   DS18B20_IO_OUT();
  75.   for(j=1;j<=8;j++){
  76.     testb=data&0x01;
  77.     data=data>>1;
  78.     if(testb){
  79.       DS18B20_DQ_OUT_LOW;
  80.       delay_us(2);
  81.       DS18B20_DQ_OUT_HIGH;
  82.       delay_us(60);
  83.     }else{
  84.       DS18B20_DQ_OUT_LOW;
  85.       delay_us(60);
  86.       DS18B20_DQ_OUT_HIGH;
  87.       delay_us(2);
  88.     }
  89.   }
  90. }

  91. void DS18B20_Start(void){
  92.   DS18B20_Rst();
  93.   DS18B20_Check();
  94.   DS18B20_Write_Byte(0xcc);
  95.   DS18B20_Write_Byte(0x44);
  96. }

  97. uint8_t DS18B20_Init(void){
  98.   GPIO_InitTypeDef GPIO_InitStructure;
  99.   GPIO_InitStructure.Pin = GPIO_PIN_11;
  100.   GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  101.   GPIO_InitStructure.Pull = GPIO_PULLUP;
  102.   GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  103.   HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);
  104.        
  105.   DS18B20_Rst();
  106.   return DS18B20_Check();
  107. }

  108. short DS18B20_Get_Temperature(void){
  109.   uint8_t temp;
  110.   uint8_t TL,TH;
  111.   short temperature;
  112.        
  113.   DS18B20_Start();
  114.   DS18B20_Rst();
  115.   DS18B20_Check();
  116.   DS18B20_Write_Byte(0xcc);
  117.   DS18B20_Write_Byte(0xbe);
  118.   TL = DS18B20_Read_Byte();
  119.   TH = DS18B20_Read_Byte();
  120.        
  121.   if(TH>7){
  122.     TH = ~TH;
  123.     TL = ~TL;
  124.     temp = 0;
  125.   }else
  126.     temp = 1;
  127.        
  128.   temperature = TH;
  129.   temperature <<= 8;
  130.   temperature += TL;
  131.   temperature = (float)temperature*0.625;
  132.   if(temperature)
  133.     return temperature;
  134.   else
  135.     return -temperature;
  136. }
复制代码

➡️ 在main.c文件下编写ds18b20测试代码
  1. int main(void){
  2.   float temperature;
  3.   HAL_Init();
  4.   SystemClock_Config();
  5.   MX_GPIO_Init();
  6.   MX_TIM7_Init();
  7.   MX_USART1_UART_Init();
  8.   /* USER CODE BEGIN 2 */
  9.   while(DS18B20_Init()){
  10.     printf("DS18B20 checked failed!!!\r\n");
  11.     HAL_Delay(500);
  12.   }
  13.   printf("DS18B20 checked success!!!\r\n");
  14.   /* USER CODE END 2 */
  15.   while (1){
  16.     temperature = DS18B20_Get_Temperature();
  17.     if(temperature < 0)
  18.       printf("temperature = -%.2f degree\r\n",temperature/10);
  19.     else
  20.       printf("temperature = %.2f degree\r\n",temperature/10);
  21.                
  22.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);
  23.     HAL_Delay(200);
  24.   }
  25. }
复制代码

4.下载验证
编译无误下载到开发板后,可以看到D1指示灯不断闪烁,串口不断打印出当前温度值


微信图片_20230701183615.png

转载自: 嵌入式攻城狮
如有侵权请联系删除


收藏 评论0 发布时间:2023-7-1 18:38

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版