DH11温湿度传感器的stm32示例程序
时间: 2023-10-29 09:07:11 浏览: 65
dht11温湿度传感器stm32
以下是基于STM32的DH11温湿度传感器示例程序:
```c
#include "stm32f10x.h"
#include "stdio.h"
#define DH11_IO GPIO_Pin_0 // DH11数据线接在PA0引脚
#define DH11_PORT GPIOA
void delay_us(uint32_t us)
{
// 设置定时器2时钟为72MHz
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM2->PSC = 36 - 1; // 分频系数为36,计数器时钟为2MHz
TIM2->ARR = us - 1; // 计数器自动重载值为us-1
TIM2->CNT = 0; // 清零计数器
TIM2->EGR = TIM_EGR_UG; // 产生更新事件,重新加载PSC和ARR
TIM2->SR &= ~TIM_SR_UIF; // 清除更新中断标志
TIM2->CR1 |= TIM_CR1_CEN; // 启动定时器2
while ((TIM2->SR & TIM_SR_UIF) == 0); // 等待计数完成
TIM2->CR1 &= ~TIM_CR1_CEN; // 停止定时器2
}
void delay_ms(uint32_t ms)
{
while (ms--)
delay_us(1000);
}
void DH11_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = DH11_IO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DH11_PORT, &GPIO_InitStructure);
GPIO_SetBits(DH11_PORT, DH11_IO);
}
void DH11_start(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DH11_IO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DH11_PORT, &GPIO_InitStructure);
GPIO_ResetBits(DH11_PORT, DH11_IO);
delay_ms(18);
GPIO_SetBits(DH11_PORT, DH11_IO);
delay_us(30);
}
uint8_t DH11_check(void)
{
uint8_t response = 1;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DH11_IO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DH11_PORT, &GPIO_InitStructure);
delay_us(40);
if (GPIO_ReadInputDataBit(DH11_PORT, DH11_IO))
response = 0;
delay_us(80);
if (!GPIO_ReadInputDataBit(DH11_PORT, DH11_IO))
response = 0;
while (GPIO_ReadInputDataBit(DH11_PORT, DH11_IO)); // 等待DH11拉低数据线
return response;
}
uint8_t DH11_read_byte(void)
{
uint8_t i, byte = 0;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DH11_IO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DH11_PORT, &GPIO_InitStructure);
for (i = 0; i < 8; i++)
{
while (!GPIO_ReadInputDataBit(DH11_PORT, DH11_IO)); // 等待DH11拉高数据线
delay_us(30);
if (GPIO_ReadInputDataBit(DH11_PORT, DH11_IO))
byte |= (1 << (7 - i));
while (GPIO_ReadInputDataBit(DH11_PORT, DH11_IO)); // 等待DH11拉低数据线
}
return byte;
}
void DH11_read(uint8_t *temp, uint8_t *humi)
{
uint8_t i, data[5], check_sum;
DH11_start();
if (!DH11_check())
{
printf("DH11 check failed.\n");
return;
}
for (i = 0; i < 5; i++)
data[i] = DH11_read_byte();
check_sum = data[0] + data[1] + data[2] + data[3];
if (check_sum != data[4])
{
printf("DH11 data error.\n");
return;
}
*humi = data[0];
*temp = data[2];
}
int main(void)
{
uint8_t temp, humi;
DH11_init();
while (1)
{
DH11_read(&temp, &humi);
printf("Temperature: %d°C, Humidity: %d%%.\n", temp, humi);
delay_ms(1000);
}
}
```
该程序中,`delay_us`和`delay_ms`函数使用STM32的定时器2实现微秒级和毫秒级延时。`DH11_init`函数初始化DH11数据线引脚为输出模式,并将数据线拉高。`DH11_start`函数发送启动信号,即先将数据线拉低18ms,然后拉高30us。`DH11_check`函数等待DH11响应,并检查响应是否正确。`DH11_read_byte`函数读取1字节数据。`DH11_read`函数读取温度和湿度数据,并校验数据是否正确。主函数中循环读取温湿度数据,并打印到串口终端。
阅读全文