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

基于STM32CubeMX DHT11温湿度传感器经验分享

[复制链接]
攻城狮Melo 发布时间:2023-7-1 18:18
1.DHT11简介
DHT11是一款温湿度一体化的数字传感器,该传感器包括一个电阻式测湿元件和一个NTC测温元件,并与一个高性能8位单片机连接。通过单片机微处理器简单的电路连接就能够实时的采集湿度和温度。DHT11与STM32之间能采用简单的单总线进行通讯,仅需一个IO口。传感器内部温度和湿度数据40个bit的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。
DHT11采用单总线数据格式,即单个数据引脚端口完成输入输出双向传输。其数据包由5个字节(40Bit)组成。数据分小数和整数部分,一次完整的数据传输为40bit,高位先出。数据格式如下图示

微信图片_20230701181746.png

根据以上数据,即可算出温度和湿度的值,计算方法如下:
湿度 = byte4.byte3
温度 = byte2.byte1
校验 = byte4 + byte3 + byte2 + byte1

DHT11和单片机的一次通讯最大为3ms左右,建议主机连续读取时间间隔不要小于100ms,下面是DHT11的三种时序:

⏩ 数据发送时序
首先主机发送开始信号,即拉低数据线保持t1(至少18ms)时间,接着拉高数据线t2(20 ~ 40us)时间;然后读取DHT11的响应,正常的话DHT11会拉低数据线并保持t3(40 ~ 50us)时间作为响应信号,接着DHT11拉高数据线并保持t4(40 ~ 50us)时间后,开始传输数据

微信图片_20230701181742.png

⏩ DHT11输出0时序

微信图片_20230701181739.png

⏩ DHT11输出1时序

微信图片_20230701181736.png


2.硬件设计

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


3.软件设计
3.1 STM32CubeMX设置

➡️ RCC设置外接HSE,时钟设置为72M

➡️ PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平

➡️ USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位

➡️ PG11设置为GPIO推挽输出模式、上拉、高速

➡️ 激活TIM7,预分频因子设为72-1,向上计数,自动重载值为65535;因此计数器CNT_CLK = 1MHz,计数器周期为1us

微信图片_20230701181727.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. }
复制代码

➡️ 创建DHT11温湿度传感器驱动文件DHT11.c 和相关头文件DHT11.h
  1. void DHT11_IO_IN(void){  //IO口方向设置为输入
  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 DHT11_IO_OUT(void){  //IO口方向设置为输出
  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 DHT11_Rst(void){                 
  15.   DHT11_IO_OUT();         //设置为输出
  16.   DHT11_DQ_OUT_LOW;         //拉低
  17.   HAL_Delay(20);            //至少18ms
  18.   DHT11_DQ_OUT_HIGH;         //拉高
  19.   delay_us(30);             //至少20~40us
  20. }

  21. uint8_t DHT11_Check(void){   
  22.   uint8_t retry=0;
  23.   DHT11_IO_IN();      
  24.   while (DHT11_DQ_IN&&retry<100){ //拉低40~80us
  25.     retry++;
  26.     delay_us(1);
  27.   };         
  28.   if(retry>=100)return 1;
  29.   else retry=0;
  30.   while (!DHT11_DQ_IN&&retry<100){ //拉高40~80us
  31.     retry++;
  32.     delay_us(1);
  33.   };
  34.   if(retry>=100)return 1;            
  35.   return 0;        //检测到DHT11返回0
  36. }

  37. uint8_t DHT11_Read_Bit(void){
  38.   uint8_t retry=0;
  39.   while(DHT11_DQ_IN&&retry<100){//等待变为低电平
  40.     retry++;
  41.     delay_us(1);
  42.   }
  43.   retry=0;
  44.   while(!DHT11_DQ_IN&&retry<100){//等待变为高电平
  45.     retry++;
  46.     delay_us(1);
  47.   }
  48.   delay_us(40);        //等待40us
  49.   if(DHT11_DQ_IN)return 1;
  50.   else return 0;                  
  51. }

  52. uint8_t DHT11_Read_Byte(void){        
  53.   uint8_t i,dat;
  54.   dat=0;
  55.   for (i=0;i<8;i++){
  56.     dat<<=1;
  57.     dat|=DHT11_Read_Bit();
  58.   }                                                    
  59.   return dat;
  60. }

  61. uint8_t DHT11_Read_Data(uint16_t *temp,uint16_t *humi){        
  62.   uint8_t buf[5];
  63.   uint8_t i;
  64.   DHT11_Rst();
  65.   if(DHT11_Check()==0){
  66.     for(i=0;i<5;i++){
  67.       buf[i]=DHT11_Read_Byte();
  68.     }
  69.     if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){
  70.       *humi=(buf[0]<<8) + buf[1];
  71.       *temp=(buf[2]<<8) + buf[3];
  72.     }
  73.   }else return 1;
  74.   return 0;            
  75. }
  76.            
  77. uint8_t DHT11_Init(void){
  78.   //PG11的初始化已经在cubemx中完成,可以忽略此段初始化代码
  79.   GPIO_InitTypeDef GPIO_Initure;       
  80.   __HAL_RCC_GPIOG_CLK_ENABLE();                       
  81.   GPIO_Initure.Pin=GPIO_PIN_11;           
  82.   GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  
  83.   GPIO_Initure.Pull=GPIO_PULLUP;         
  84.   GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;
  85.   HAL_GPIO_Init(GPIOG,&GPIO_Initure);   
  86.   DHT11_Rst();
  87.   return DHT11_Check();
  88. }
复制代码

➡️ 在main.c文件下编写DHT11测试代码
  1. int main(void){
  2.   /* USER CODE BEGIN 1 */
  3.   uint16_t temperature;
  4.   uint16_t humidity;
  5.   /* USER CODE END 1 */
  6.   HAL_Init();
  7.   SystemClock_Config();
  8.   MX_GPIO_Init();
  9.   MX_TIM7_Init();
  10.   MX_USART1_UART_Init();
  11.   /* USER CODE BEGIN 2 */
  12.   while(DHT11_Init()){
  13.     printf("DHT11 Checked failed!!!\r\n");
  14.     HAL_Delay(500);
  15.   }
  16.   printf("DHT11 Checked Sucess!!!\r\n");
  17.   /* USER CODE END 2 */
  18.   while (1){
  19.     DHT11_Read_Data(&temperature,&humidity);
  20.     printf("DHT11 Temperature = %d.%d degree\r\n",temperature>>8,temperature&0xff);
  21.     printf("DHT11 Humidity = %d.%d%%\r\n",humidity>>8,humidity&0xff);               
  22.     HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);
  23.     HAL_Delay(500);
  24.   }
  25. }
复制代码

4.下载验证
编译无误下载到开发板后,可以看到D1指示灯不断闪烁,串口不断打印出当前温湿度值。串口输出如下信息:
DHT11 Checked Sucess!!!
DHT11 Temperature = 28.20 degree
DHT11 Humidity = 30.21%
转载自: 嵌入式攻城狮
如有侵权请联系删除


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

举报

0个回答

所属标签

相似分享

官网相关资源

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