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

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

[复制链接]
攻城狮Melo 发布时间:2024-6-15 19:51
一、初始化
1.逻辑
1.主机(控制器STM32,下同)拉低电平,持续480us-960us,然后释放(拉高电平,下同)
2.等待15us-60us(在程序中给了30)//第一和第二步均为输出,但是第二部后要切换为输入模式
3.从机(DS18B20 传感器,下同)会低电平,持续时间60us-240us,//这一步是检测传感器在不在的关键一步,加上第二步释放后的时间,所以我们要在90us(30+60)-270us(30+240)内检测电平高低来判断传感器是否存在。在此时应为输入模式。
4.主机接收至少480us,所以我们检测完后还需等待时序结束,时间=480us-释放后到检测时时间

返回数值。

微信图片_20240615195059.png
代码:

1.初始化代码
  1. #include "stm32f10x.h"                  // Device header
  2. #include "main.h"    //这里面没什么(除了delay函数)

  3. #define DS18B20 GPIO_Pin_15      //如果复制使用,只需改这行Pin口和下行通道还开启有时钟
  4. #define DS18B20_PROT GPIOB      //其他代码不用更改,只需补全delay和显示函数就行
  5. #define DS18B20_LOW GPIO_ResetBits(DS18B20_PROT,DS18B20)
  6. #define DS18B20_HIGH GPIO_SetBits(DS18B20_PROT,DS18B20)

  7. void DS18B20_Init(void)  //初始化函数
  8. {
  9.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);    //开启对应通道时钟
  10.   
  11.   GPIO_InitTypeDef GPIO_InitStruct;
  12.   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  13.   GPIO_InitStruct.GPIO_Pin = DS18B20;
  14.   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  15.   GPIO_Init(DS18B20_PROT,&GPIO_InitStruct);
  16. }
复制代码

2.模式切换函数,1为写/输出模式,0为读/输入模式
  1. void DS18B20_Output_Input(u8 cmd)  //输入输出模式切换,1输出,0输入/读取
  2. {
  3.   GPIO_InitTypeDef GPIO_InitStruct;
  4.   
  5.   if(cmd)  //为1 是输出模式
  6.   {
  7.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  8.     GPIO_InitStruct.GPIO_Pin = DS18B20;
  9.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  10.    
  11.   }
  12.   else  //为0,输入模式
  13.   {
  14.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
  15.     GPIO_InitStruct.GPIO_Pin = DS18B20;
  16.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

  17.   }
  18.   GPIO_Init(DS18B20_PROT,&GPIO_InitStruct);
  19. }
复制代码

3. 初始化代码
  1. u8 DS18B20_Starup(void)  //判断DS18B20 是否存在的一个函数
  2. {
  3.   u8 data;
  4.   
  5.   DS18B20_Output_Input(1);  //为输出模式
  6.   DS18B20_LOW;        //拉低电平
  7.   Delay_us(480);    //delay函数,需要自己写,网上资料很多,保证时间准确就行
  8.   DS18B20_HIGH;    //拉高电平,也是 释放总线
  9.   Delay_us(100);
  10.   
  11.   DS18B20_Output_Input(0);  //为输入模式
  12.   data = GPIO_ReadInputDataBit(DS18B20_PROT,DS18B20);  //根据时序存在返回0,不存在是1
  13.   Delay_us(380);
  14.   
  15.   return data;
  16. }
复制代码

4.此时我们需要验证下,在main函数里进行数据显示
  1. int main(void)
  2. {
  3.   OLED_Init();
  4.   DS18B20_Init();

  5.   while (1)
  6.   {
  7.     OLED_ShowNum(2, 5, DS18B20_Starup(), 1);//用自己的方式验证,存在为0,否则为1
  8.     }
  9. }
复制代码

如果显示0,在拔下传感器的数据线后显示为1,插入后为0.则以上代码和传感器没有问题


二、写数据和读数据
1.写时序函数

DS18B20对时序要求非常高,所以delay函数一定要精准

代码
  1. void DS18B20_Write_Byte(u8 data)  //写数据
  2. {
  3.   for(u8 i=0;i<8;i++)
  4.   {
  5.     DS18B20_Output_Input(1);
  6.     DS18B20_LOW;
  7.     Delay_us(2);  //拉低2us进入书写时序
  8.     (data&0x01) ? DS18B20_HIGH:DS18B20_LOW;//从低位往高位写移位7次后将是最高位
  9.     Delay_us(45);  //延时45us
  10.     DS18B20_HIGH;  //释放总线
  11.    
  12.     data >>=1;   
  13.   }
  14. }
复制代码

微信图片_20240615195056.png

2.读函数


代码:
  1. u8  DS18B20_Read_Byte(void)  //读程序
  2. {
  3.   u8 data=0;
  4.   for(u8 i=0;i<8;i++)
  5.   {
  6.     data >>=1;
  7.     DS18B20_Output_Input(1);  //写时序,拉低2us后释放
  8.     DS18B20_LOW;
  9.     Delay_us(2);  //拉低2us进入读时序
  10.     DS18B20_HIGH;
  11.    
  12.     DS18B20_Output_Input(0);    //进入读时序
  13.     if((GPIO_ReadInputDataBit(DS18B20_PROT,DS18B20)) == SET)
  14.     {   
  15.       data |= 0x80;
  16.     }
  17.     Delay_us(45);
  18.   }
  19.   return data;
  20. }
复制代码

三 、读取温度
逻辑:1.初始化
跳过匹配命令(0XCC)
温度转换命令(0X44)
delay750ms        //注意时间单位毫秒
初始化
跳过匹配命令(0XCC)
温度读取命令(0XBE)
先读取的低8位
再读取的高8位
数据转换,二进制转换成10进制

代码:最后的代码*10,为方便显示小数
  1. void DS18B20_Read_Temp(u16 *data)
  2. {
  3.   u8 LSB=0,HSB=0;u16 Temp=0;  //LSB 低位的8位数据
  4.   
  5.   DS18B20_Starup();
  6.   DS18B20_Write_Byte(0xCC);  //跳过匹配步骤
  7.   DS18B20_Write_Byte(0x44);  //温度转换,12位时间为750ms,注意时间单位
  8.   Delay_ms(750);
  9.   DS18B20_Starup();
  10.   DS18B20_Write_Byte(0xCC);  
  11.   DS18B20_Write_Byte(0xBE);  //进行数据读写
  12.   
  13.   LSB = DS18B20_Read_Byte();  //先读取的低8位
  14.   HSB = DS18B20_Read_Byte();  //再读取的高8位

  15.   Temp = (HSB<<8) | LSB;
  16.   
  17.   if((Temp&0xF800)==0xF800)  //S=1为真否则位0
  18.   {
  19.     *data = (((~Temp + 0x01)*-0.0625))*10;//为负温度
  20.   
  21.   }
  22.   else
  23.   {
  24.     *data = (Temp*0.0625)*10;    //正温度
  25.   }  
  26. }
复制代码

四 ,显示数据
在main里进行显示,需要取地址操作

代码:
  1. u16 Temp=0;  //u16 类型值

  2. int main(void)
  3. {  
  4.   OLED_Init();
  5.   DS18B20_Init();

  6.   while (1)
  7.   {
  8.     DS18B20_Read_Temp(&Temp);  //取值
  9.     OLED_ShowSignedNum(2, 1, (Temp/10), 2);  //整数位
  10.     OLED_ShowString(2, 4, ".");
  11.     OLED_ShowNum(2, 5, (Temp%10), 1);//小数位一位
  12.     }
  13. }
复制代码


转载自:钜锋智联
如有侵权请联系删除



收藏 评论0 发布时间:2024-6-15 19:51

举报

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