【STM32】温湿度传感器的使用

  

 阅读原理图,温湿度模块通过D2连线接到STM32 PB8引脚上。

 

 

 阅读温湿度传感器说明书,主从机基于微秒级完成通信,要实现微秒级通信需要使用一个定时器。故而启用TIM6。

获取到以上两点信息后,使用CubeMX生成代码。

配置PB8为GPIO_Input ;配置PA9,PA10 为 UART_TX与UART_RX。

 

 在PB8中加上用户标签DHT。

 定时器启用,并设置预分频系数,向上计数,最大计数周期。

 

 UART串口设置波特率。

完成后生成代码。

 dht.c 任务处理文件。

#include "gpio.h"
#include <stdio.h>

void delay_us(uint16_t wait)
{
	//TIM6的一个时钟周期是1us
	
	//设置TIM6的计数器的值为1
	TIM6->CNT = 0;
	//LL_TIM_SetCounter(TIM6, 0);
	//LL_TIM_GetCounter(TIM6);
	
	//计数1次是1us,计数wait次就是waitus
	while(TIM6->CNT < wait);	
}

//等待高、低电平结束
//level:高/低电平
//timeout:超时时间(us)
//返回值:等待的时间(us)
uint32_t wait_level(GPIO_PinState level, uint32_t timeout)
{
  uint32_t wait = 0;
  while (HAL_GPIO_ReadPin(DHT_GPIO_Port, DHT_Pin) == level)
  {
    delay_us(1);
    wait++;
    if (wait >= timeout)
    {
      break; //超时退出
    }
  }
  
  return wait;
}

//读取温湿度
void dht_read(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  
  //将数据引脚设置为输出模式
  GPIO_InitStruct.Pin = DHT_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(DHT_GPIO_Port, &GPIO_InitStruct);
  
  //发送起始信号(输出低电平并持续18ms以上)
  HAL_GPIO_WritePin(DHT_GPIO_Port, DHT_Pin, GPIO_PIN_RESET);
  HAL_Delay(19);
  
  //将数据引脚设置为输入模式,电平由外部上拉电阻拉高
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  HAL_GPIO_Init(DHT_GPIO_Port, &GPIO_InitStruct);
  
  //主机发送开始信号结束后,延时等待20-40us后,读取DHT1X的响应信号
  delay_us(40);
  
  //判断DHT传感器是否发出响应信号(低电平)
  if (HAL_GPIO_ReadPin(DHT_GPIO_Port, DHT_Pin) == GPIO_PIN_SET)
  {
    //如果传感器没有响应,打印错误信息并终止读取
    printf("DHT sensor no response\r\n");
    return;
  }
  
  //如果传感器响应,等待响应信号结束
  //等待低电平结束
  wait_level(GPIO_PIN_RESET, 80);
  //等待高电平结束
  wait_level(GPIO_PIN_SET, 100);
  
  //保存收到的40bit数据
  uint8_t data[5];
  
  uint8_t j;
  for (j = 0; j < 5; j++)
  {
    //读取一个字节
    uint8_t i;
    for (i = 0; i < 8; i++)
    {
      //开始接收数据
      //统计低电平持续时间
      uint32_t low_time = wait_level(GPIO_PIN_RESET, 70);
      //统计高电平持续时间
      uint32_t high_time = wait_level(GPIO_PIN_SET, 100);
      if (low_time > high_time)
      {
        //收到bit0
        data[j] &= (~(0x80 >> i)); //将第i个有效位清0
      }
      else
      {
        //收到bit1
        data[j] |= (0x80 >> i); //将第i个有效位置1
      }
    }
  }
  
  //当最后一bit数据传送完毕后,DHT1X拉低总线50us
  wait_level(GPIO_PIN_RESET, 50);
  
  //计算校验和
  //数据传送正确时校验和数据等于
  //“8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据”
  //所得结果的末8位。
  uint8_t chksum = data[0] + data[1] + data[2] + data[3];
  if (chksum != data[4])
  {
    //校验和错误打印出错信息
    printf("checksum error\r\n");
    return;
  }
  
  //打印温湿度信息
  printf("Humidity: %d.%d, ", data[0], data[1]);
  printf("Temprature: %d.%d\r\n", data[2], data[3]);
}


 

 主函数里调用一下dht.c里面写好的函数即可,延迟一下降低读的频率,避免刷新的太快。

连上板子运行即可。

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值