【STM32】DHT11温湿度模块传感器详解&代码
·
一、DHT11产品介绍
DHT11是数字温湿度传感器,测量范围:湿度20%-95%,温度0-50℃,广泛应用于加湿器、温湿度计、空调、汽车等领域。
二、典型应用电路
如上图DATA引脚用于MCU与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右(超时时间的判断)。一次完整的数据传输为40bit,高位先出(MSB最高有效位有线传输)
数据传送正确时校验和数据等于:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据,所得结果的末8位。
如:
湿度:60.5% 60 05
温度:26.7℃ 26 07
60+5+26+7=98
98&0xFF=98=1001 1000
三、DHT11温湿度模块的通信过程
四、示例代码
显示室内温度和湿度
效果图:
1、DHT11初始化
void dht11_init(void)
{
//打开端口G的硬件时钟,就是供电
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //9号引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; //开漏
GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速,速度越高,响应越快,但是功耗会更高
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不使能上下拉电阻
GPIO_Init(GPIOG,&GPIO_InitStructure);
//只要有输出模式,肯定会有初始电平的状态,看连接设备的说明书
PGout(9)=1;
}
2、
int32_t dht11_read(uint8_t *buf)
{
uint32_t t=0;
int32_t i=0,j=0;
uint8_t d=0;
uint8_t *p=buf;
uint8_t check_sum=0;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //9号引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; //开漏
GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速,速度越高,响应越快,但是功耗会更高
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不使能上下拉电阻
GPIO_Init(GPIOG,&GPIO_InitStructure);
PGout(9)=0;
delay_ms(18);
PGout(9)=1;
delay_us(30);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //9号引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //输入模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; //开漏
GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速,速度越高,响应越快,但是功耗会更高
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不使能上下拉电阻
GPIO_Init(GPIOG,&GPIO_InitStructure);
//等待低电平出现
t=0;
while(PGin(9))
{
t++;
delay_us(1);
if(t >= 4000)
return -1;
}
//用超时检测的方法测量低电平的合法性
t=0;
while(PGin(9)==0)
{
t++;
delay_us(1);
if(t >= 100)
return -2;
}
//用超时检测的方法测量高电平的合法性
t=0;
while(PGin(9))
{
t++;
delay_us(1);
if(t >= 100)
return -3;
}
for(j=0; j<5; j++)
{
//接收一个字节的数据
for(d=0,i=7; i>=0; i--)
{
//用超时检测的方法测量低电平的合法性
t=0;
while(PGin(9)==0)
{
t++;
delay_us(1);
if(t >= 100)
return -4;
}
//延时40us (延时时间在28us ~ 70us)
delay_us(40);
if(PGin(9))
{
d|=1<<i; //将d变量对应的bit置1
//等待高电平持续完毕
t=0;
while(PGin(9))
{
t++;
delay_us(1);
if(t >= 100)
return -5;
}
}
}
p[j]=d;
}
//延时50us,可以忽略通讯结束的低电平
delay_us(50);
//计算校验和,检查接收到的数据是否准确
check_sum = (p[0]+p[1]+p[2]+p[3])&0xFF;
if(check_sum == p[4])
return 0;
return -6;
}
3、main函数实现
int main(void)
{
uint8_t buf[5];
int32_t rt;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
/* 初始化串口1波特率为115200bps,若发送/接收数据有乱码,请检查PLL */
usart1_init(115200);
dht11_init();
printf("this is dht11 test\r\n");
printf("1<<6=%X \r\n",1<<6);
printf("1<<3=%X \r\n",1<<3);
while(1)
{
rt = dht11_read(buf);
if( rt == 0)
{
printf("T:%d.%d H:%d.%d\r\n",buf[2],buf[3],buf[0],buf[1]);
}
else
{
printf("dht11 read error code is %d\r\n",rt);
}
//官方要求,每6秒
delay_ms(6000);
}
}
更多推荐
已为社区贡献4条内容
所有评论(0)