stm32f103hal库dht11
时间: 2024-12-30 10:26:37 浏览: 10
### STM32F103 HAL库驱动DHT11温湿度传感器
#### 初始化配置
为了使STM32F103C8T6能够通过HAL库读取来自DHT11的数据,初始化阶段至关重要。这涉及到设置GPIO引脚作为输入/输出以及配置必要的延时函数来处理微秒级的时间间隔。
```c
// 定义用于通信的GPIO端口和引脚
#define DHT11_PORT GPIOA
#define DHT11_PIN GPIO_PIN_8
void DHT11_Init(void){
__HAL_RCC_GPIOA_CLK_ENABLE(); // 启用GPIOA时钟
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 配置PA8为推挽输出模式
GPIO_InitStruct.Pin = DHT11_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStruct);
}
```
#### 数据传输协议实现
根据DHT11的工作原理,在主机发送启动信号之后,会等待从机返回应答脉冲序列。这段代码展示了如何检测这个过程中的高低电平变化并验证其合法性。
```c
uint8_t dht11_check(void){
uint8_t retry=0;
// 设置为输入状态前先清除之前的输出状态
HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_RESET);
// 切换到浮空输入模式以接收外部设备反馈
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = DHT11_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStruct);
// 等待高电平超过最大容忍次数则认为失败
while (HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)&&retry<100){
retry++;
DHT11_delay_us(1);
}
if(retry>=100)return 1;
// 清零重试计数器准备下一轮测试
retry=0;
// 接下来应该看到的是持续一段时间的低电平
while (!HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN)&&retry<100){
retry++;
DHT11_delay_us(1);
}
return (retry >= 100)? 1 : 0 ;
}
```
#### 微秒级别延迟函数定义
由于标准HAL库提供的`HAL_Delay()`仅支持毫秒级别的精度,因此需要自定义一个可以精确控制更短时间周期的方法:
```c
#include "stm32f1xx_hal.h"
static void DHT11_delay_us(uint16_t us){
uint32_t ticks_start = HAL_GetTick();
uint32_t current_ticks;
do {
current_ticks = HAL_GetTick();
}while((current_ticks - ticks_start)*1000/us <= 1);
}
```
上述方法利用了系统滴答定时器来进行简单的循环等待操作,从而达到所需的微妙级延时效果[^2]。
阅读全文