DHT22是一款数字式温湿度传感器,相较于热敏式的传感器具有无需A/D转换器参与、无需进行线性化处理等优势。
DHT22采用的是一种单总线式的结构,由此只需一个I/O口就可模拟工作方式来检测环境的温湿度变化。
DHT22与开发板的连接及显示效果如下图所示:
DHT22连接及检测效果图
由于DHT22是以单总线进行工作,故对其输出高低电平及读取输入信号的引脚定义如下:
#define DHT22_D0_H GPIOB->BSHR = GPIO_Pin_4
#define DHT22_D0_L GPIOB->BCR = GPIO_Pin_4
#define DHT22_D0_R GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4)
因DHT22在工作时,要在输入与输出模式间切换,故所用的引脚输入和输出模式配置函数如下:
void DHT22_IO_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Speed =GPIO_Speed_10MHz ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void DHT22_IO_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed =GPIO_Speed_10MHz ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
对DHT22进行数据读取的函数为:
uint8_t DHT22_Read_Data(uint8_t *temp,uint8_t *humi)
{
uint8_t buf[5];
uint8_t i;
DHT22_Rst();
if(DHT22_Check()==0)
{
for(i=0;i<5;i++)
{
buf=DHT22_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humi=(buf[0]*256+buf[1])/10;
*temp=(buf[2]*256+buf[3])/10;
}
}else return 1;
return 0;
}
对DHT22所用引脚PB4进行初始化的函数为:
uint8_t DHT22_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
DHT22_Rst();
return DHT22_Check();
}
实现图示效果的主程序为:
int main(void)
{
uint8_t senflag;
Delay_Init();
senflag=DHT22_Init();
Delay_Us(250);
app_OLED_Init();
OLED_Init();
OLED_Clear();
OLED_ShowString(0,0,"CH32V103 TEST",16);
OLED_ShowString(0,2,"OLED & DHT22",16);
Delay_Ms(2000);
OLED_Clear();
while(1)
{
if(!senflag)
{
DHT22_Read_Data(&temperature,&humidity);
OLED_ShowString(0,0,"Temp: C",16);
OLED_ShowNum(40,0,temperature,2,16);
OLED_ShowString(0,2,"Humi: %",16);
OLED_ShowNum(40,2,humidity,2,16);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
Delay_Ms(100);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
Delay_Ms(100);
}
}
}
以此为基础我们还可以为它配上按键来设置控制参数,进而通过继电器等来控制相应的读取来调节温湿度。
本帖最后由 jennyzhaojie 于 2021-2-9 17:47 编辑