莱芜建设银行网站,wordpress会自动换行,牧羊人wordpress主题,建湖人才网最新招聘stm32读取DHT11温湿度传感器 一.序言二.DHT11响应数据格式三.DHT11通讯过程3.1 产生起始信号3.2 读取数据03.3 读取数据1DHT11停止信号 四.代码实例4.1读取DHT11源文件4.2 读取DHT11头文件 五.结语5.1 总结整体思路5.2 对读者的期望 一.序言
我们知道DHT11是单总线协议#x… stm32读取DHT11温湿度传感器 一.序言二.DHT11响应数据格式三.DHT11通讯过程3.1 产生起始信号3.2 读取数据03.3 读取数据1DHT11停止信号 四.代码实例4.1读取DHT11源文件4.2 读取DHT11头文件 五.结语5.1 总结整体思路5.2 对读者的期望 一.序言
我们知道DHT11是单总线协议只有一根数据线。 且内部有个上拉电路下图。那么数据线默认就是高电平那接下来就可以讲解主机如何和DHT11通讯的 二.DHT11响应数据格式
读取DHT11的芯片手册可以知道DHT11一次完成的数据输出是40bit高位先出。 格式8bit湿度整数数据8bit湿度小数数据 8bi温度整数数据8bit温度小数数据8bit校验和 那是如何校验的的 如果数据传输正确则 校验和数据 “ 8bit湿度整数数据8bit湿度小数数据 8bi温度整数数据8bit温度小数数据” 所得结果的末8位。 这样我们读取温湿度传感器数据后可以通过校验和校验数据 如果正确则将数据读取如果不正确则重新读取。
三.DHT11通讯过程
注意的是这里我们通过总线上高电平的时间来判断是数据 ‘0’,还是数据 ‘1’ 这里先给一个总的通讯过程
3.1 产生起始信号
起始信号由高拉低产生一个下降沿。在保持低电平18ms以上 再释放总线因为内部是上拉电路所以释放后总线上高电平。 等待DHT11响应,如果DHT11响应则会拉低数据线80us作为一个响应信号。 然后释放总线。延时20-40us以后就可以读取DHT11的响应数据。
3.2 读取数据0
DHT11将总线拉低50us,表示数据开始传输。DHT11开始发送数据信息。 如果是数据 ‘0’ 数据线将会被拉高26-28us。这一位数据传输结束。 下一位数据传输开始继续拉低50us表示数据开始传输… 直到一次完整的数据40bit传输完成。
3.3 读取数据1
DHT11将总线拉低50us,表示数据开始传输。DHT11开始发送数据信息。 如果是数据 ‘1’则会把总线拉高70us。这一位数据传输结束。
DHT11停止信号
因为一次完整的数据是40bi当最后一bit数据传送完毕后DHT11拉低总线 50us,随后总线由上拉电阻拉高进入空闲状态。可以参考第一个通讯总图
四.代码实例
4.1读取DHT11源文件
#include DHT11.hGPIO_InitTypeDef GPIO_InitStructure; //后面会改变输入输出状态static void GPIO_SETOUT(void);
static void GPIO_SETIN(void);
static u8 DHT11_Check(void);/**********************************************
函数名static void DHT11_Rst(void)
参数说明无
返回值无
函数作用主机发送开始信号
***********************************************/
static void DHT11_Rst(void)
{
GPIO_SETOUT(); //配置成输出模式
GPIO_ResetBits(DHT11_IO,DHT11_PIN); //拉低数据线
delay_ms(20); //拉低至少18ms
GPIO_SetBits(DHT11_IO,DHT11_PIN); //拉高数据线
delay_us(30); //主机拉高20~40us
}/**********************************************
函数名u8 DHT11_Init(void)
参数说明无
返回值u8 ,返回1代表初始化成功0则失败
函数作用配置IO口并发送开始信号
***********************************************/
u8 DHT11_Init(void){//IO口配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//换IO口需要修改
GPIO_InitStructure.GPIO_Pin DHT11_PIN;
GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; //推挽输出如果需要考虑到IC的电流驱动能力时要接上拉电5K
GPIO_InitStructure.GPIO_Speed GPIO_Speed_10MHz;
GPIO_Init(DHT11_IO,GPIO_InitStructure);
DHT11_Rst();//发送开始信号
return DHT11_Check();//检测DHT11的响应
}/**********************************************
函数名static void GPIO_SETOUT(void)
参数说明无
返回值无
函数作用配置IO口为推挽输出模式
***********************************************/
static void GPIO_SETOUT(void)
{
GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; //推挽输出如果需要考虑到IC的电流驱动能力时要接上拉电阻5K
GPIO_Init(DHT11_IO,GPIO_InitStructure);}/**********************************************
函数名static void GPIO_SETIN(void)
参数说明无
返回值无
函数作用配置IO口为浮空输入模式
***********************************************/
static void GPIO_SETIN(void)
{
GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN_FLOATING; //浮空输入模式
GPIO_Init(DHT11_IO,GPIO_InitStructure);
}/**********************************************
函数名static u8 DHT11_Check(void)
参数说明无
返回值检测到回应--返回1否则0
函数作用检测DHT11的响应信号
***********************************************/
static u8 DHT11_Check(void)
{
u8 retry0;
GPIO_SETIN(); //设置为输入模式 while (!GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN) retry100)//DHT11会拉低80us{
retry;
delay_us(1);}
if(retry 100) //超时未响应/未收到开始信号退出检测return 0;
else retry 0;
while (GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN) retry100)//DHT11拉低后会再次拉高80us{retry;delay_us(1);}
if(retry100) //超时DHT11工作出错退出检测return 0;return 1; //设备正常响应可以正常工作
}/**********************************************
函数名static u8 DHT11_Read_Bit(void)
参数说明无
返回值返回从DHT11上读取的一个Bit数据
函数作用从DHT11上读取一个Bit数据
***********************************************/
static u8 DHT11_Read_Bit(void)
{
u8 retry 0;
//DHT11的Bit开始信号为50us低电平
while(GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN) retry100)//等待变为低电平(等待Bit开始信号)
{retry;delay_us(1);
}
retry 0;
while(!GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN) retry100)//等待变高电平代表数据开始传输
{retry;delay_us(1);
}
delay_us(30);//等待30us
//0信号为26-28us1信号则为70us,所以说超过30us去读取引脚状态就可以知道传输的值了
if(GPIO_ReadInputDataBit(DHT11_IO,DHT11_PIN)) return 1;
else return 0;
}/***********************************************************************
函数名static u8 DHT11_Read_Byte(void)
参数说明无
返回值返回从DHT11上读取的一个byte数据
函数作用从DHT11上读取一个byte数据
************************************************************************/
static u8 DHT11_Read_Byte(void)
{
u8 i,dat;
dat0;
for (i0;i8;i) {dat1; dat|DHT11_Read_Bit();} return dat;
}/**************************************************************************
函数名u8 DHT11_Read_Data(u8 *temp,u8 *humi)
参数说明temp:用于存放温度值(范围:0~50°)humi:用于存放湿度值(范围:20%~90%)
返回值1成功读取数据0读取数据出错
函数作用从DHT11上读取温湿度数据这里省略小数值
***************************************************************************/
u8 DHT11_Read_Data(u8 *temp,u8 *humi)
{
u8 buf[5];
u8 i;
DHT11_Rst();
if(DHT11_Check()1) //设备响应正常
{for(i0;i5;i)//读取40位数据{buf[i]DHT11_Read_Byte();}if((buf[0]buf[1]buf[2]buf[3])buf[4])//进行校验{*humibuf[0];*tempbuf[2];}
}else return 0; //设备未成功响应返回0return 1; //读取数据成功返回1
}
4.2 读取DHT11头文件
#ifndef __DHT11_H
#define __DHT11_H
#include stm32f10x.h
#include delay.h/* 设置GPIO脚默认为PB1 */
#define DHT11_IO GPIOB
#define DHT11_PIN GPIO_Pin_1/* 初始化函数如果DHT11存在响应则返回1否则0 */
u8 DHT11_Init(void);
/* 从DHT11读取数据没有小数部分 */
u8 DHT11_Read_Data(u8 *temp,u8 *humi);#endif
五.结语
5.1 总结整体思路
首先总结一下。我们思路是通过DHT11的芯片手册来了解DHT11的工作原理。 包括内部电路数据响应格式工作时序等。最后根据这些来编写代码。
5.2 对读者的期望
我想通过讲解读取DHT11的例子让读者知道怎么读取芯片手册如何剖析工作时序。以及如何编写代码最后期望的是通过这个例子让读者能够去举一反三能够通过芯片手册去自己分析工作时序编写代码。这对个人能力的提升是非常有帮助的以后无论遇到什么模块能够自己独立完成。 最后感谢大家的阅读