温湿度模块DHT22详解二:编程篇 您所在的位置:网站首页 dht11模块程序设计 温湿度模块DHT22详解二:编程篇

温湿度模块DHT22详解二:编程篇

2023-09-20 11:27| 来源: 网络整理| 查看: 265

前一篇的DHT22基础篇差不多是一年前写的了,这一年间发生挺多事情,编程篇拖到现在,废话不多说进入正题。

从前面的基础篇也很详细讲了如何去驱动DHT22的步骤(需了解请移步至:https://blog.csdn.net/k1ang/article/details/98789397),这里我们就将这些步骤进行代码化。

1、起始信号:

void DHT22_Start(void) { Set_IO_Output(); //设置IO为输出模式 DHT_DQ_OUT_L(); //输出低电平1ms SysTick_Delay_Ms(1); DHT_DQ_OUT_H(); //释放总线,即输出高电平30us SysTick_Delay_Us(30); }

2、应答信号:

应答信号并不是单纯的按照时序编写,中间增加了应答超时判断,详细见以下代码:

uint8_t DHT22_Ack(void) { uint8_t cnt = 0; Set_IO_Input();//设置IO为输入模式 if (DHT_DQ_IN() == Bit_RESET) //检测是否有低电平 { while((!DHT_DQ_IN()) && (cnt 85) //大于85us则应答超时 { return ACK_OVER_TIME;//响应超时 } else //应答正常 { cnt = 0; } /*低电平应答正常后到高电平 */ while(DHT_DQ_IN() && (cnt 85) //响应超时 { return ACK_OVER_TIME; } else { cnt = 0; return ACK_SUCCESS; } } else { return ACK_ERROR;//应答错误,起始信号后没有应答信号返回 } }

3、温湿度数据读取:

应答信号过后,DHT22会连续输出40位数据,这40位数据可分为5个字节数据,5个字节数据分别表示湿度高8位、湿度低8位、温度高8位、温度低8位和校验位。校验位等于湿度高8位+湿度低8位+温度高8位+温度低8位,由于校验位也是8位的,4个8位数据加起来基本会溢出了,如果代码是根据校验结果来更新数显温湿度,如果溢出就会导致数据不更新。为了避免这种情况,可以先将4个温湿度数据相加后强制转换为8位,再和DHT22返回的校验位比较,如果相等则表示数据无误,可以更新显示,详细代码如下:

uint8_t Read_DHT22_Data(DHT22_Data_TypeDef *Data) { DHT22_Start();//发送起始信号 if(DHT22_Ack() == ACK_SUCCESS) //接收应答成功 { Data->RH_int = DHT22_Read_Byte(); //读湿度数据高8位 Data->RH_deci = DHT22_Read_Byte(); //读湿度数据低8位 Data->Temp_int = DHT22_Read_Byte(); //读温度数据高8位 Data->Temp_deci = DHT22_Read_Byte(); //读温度数据低8位 Data->check_sum = DHT22_Read_Byte(); //读校验位 } Set_IO_Output();//设置IO为输出模式 GPIO_SetBits(DHT_DQ_Port,DHT_DQ_Pin);//释放总线 Data->sum = (uint8_t)(Data->RH_deci + Data->RH_int + Data->Temp_deci + Data->Temp_int);//将温湿度高低8位累加,并强制转换为uint8_t类型 if(Data->check_sum == Data->sum)//校验正确 { Data->RH = (float)((256 * Data->RH_int + Data->RH_deci) / 10);//转换为湿度数据,除以10是因为传感器出来的值是实际的10倍 Data->Temp = (float)((256 * Data->Temp_int + Data->Temp_deci) / 10);//转换为温度数据 return SUCCESS; //校验通过 } else return ERROR;//校验不过 }

4、读一个字节函数

在第3步用到一个读字节函数,下面从代码分析如果根据“0”和“1”时序读取,详细代码如下:

uint8_t DHT22_Read_Byte(void) { uint8_t i; uint8_t DHT22_Byte = 0; for(i = 0; i < 8; i++) { while(DHT_DQ_IN() == Bit_RESET);//等待低电平结束 SysTick_Delay_Us(40); //等待40us,再判断IO口电平状态 if(DHT_DQ_IN() == Bit_SET)// 40 us后仍为高电平则表示数据“1” { /* 等待数据1的高电平结束 */ while(DHT_DQ_IN() == Bit_SET); DHT22_Byte |= (uint8_t)(0x01


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有