赞
踩
1.原理图
DHT11使用单总线通信,使用一根数据线进行传输,再加上VCC,GND,闲置接口(NC),一共四根线。
数据线连接到了CPU的PG9,外接上拉电阻。
2.查看DHT11的说明手册了解其如何工作
数据格式:
通信时序:
CPU发送起始信号 ===> DTH11响应起始信号 ===> DHT11发回温湿度数据
(1)CPU发送起始信号和模块响应
(2)如何传输1位数据
3.代码实现
(1)起始信号和模块响应
说明一下这段代码的写法:
- //等待拉低
- while(DQ_IN&&retry<100){
- retry++;
- delay_us(1);
- }
- if(retry>=100)//如果没有拉低,无响应
- return 1;
逻辑或&&:表达式1 || 表达式2 || 表达式3...如果表达式1的运算结果为true,则整个表达式的结果为true,同时不会再执行后面的表达式,如果表达式1的运算结果为false,则根据表达式2的运算结果继续判断。
逻辑与||:表达式1 && 表达式2 && 表达式3...如果表达式1的运算结果为false,则整个表达式的结果为false,同时不会再执行后面的表达式,如果表达式1的运算结果为true,则根据表达式2的运算结果继续判断。
(2)读一位数据
(3)读取温湿度
- //读1字节数据,高位先出
- u8 dht11_read_byte(void)
- {
- u8 i,dat = 0;
-
- //连续读取8位
- for(i=0;i<8;i++){
- dat |= dht11_read_bit()<<(7-i);
- }
-
- return dat;
- }
-
- //读取温湿度数据
- //返回0表示成功,非0表示失败
- //temp和humi是输出参数,输出温湿度
- u8 dht11_read_data(u8 *temp,u8 *humi)
- {
- u8 i,buf[5];
-
- //起始信号
- if(dht11_check()==0){
- //读取40bit数据
- for(i=0;i<5;i++){
- buf[i] = dht11_read_byte();
- }
- //验证校验和
- if(((buf[0]+buf[1]+buf[2]+buf[3])&0xff)==buf[4]){
- *humi = buf[0];
- *temp = buf[2];
-
- return 0;
- }
- }
-
- return 1;
- }
//代码实现
- #include <stm32f4xx.h>
- #include <dht11.h>
- #include <delay.h>
-
- //配置DQ 输入模式/输出模式
- void dht11_set_io(GPIOMode_TypeDef IO)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
-
- //1.开启GPIOG的时钟
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);
-
- //2.GPIO初始化 PG9
- GPIO_InitStruct.GPIO_Mode = IO;
- GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽输出
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//高速
- GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
- GPIO_Init(GPIOG,&GPIO_InitStruct);
- }
-
- //测试dht11是否有响应,返回0表示正常,非0表示无响应
- u8 dht11_check(void)
- {
- u32 retry = 0;
-
- //输出模式
- dht11_set_io(GPIO_Mode_OUT);
- //发送>18ms低电平起始信号
- DQ_OUT = 0;
- //保持20ms
- delay_ms(20);
- DQ_OUT = 1;
-
- //等待20~40us
- delay_us(30);
-
- //输入模式
- dht11_set_io(GPIO_Mode_IN);
-
- //等待拉低
- while(DQ_IN&&retry<100){
- retry++;
- delay_us(1);
- }
- if(retry>=100)//如果没有拉低,无响应
- return 1;
-
- retry = 0;
- //80us后拉高
- while(!DQ_IN&&retry<100){
- retry++;
- delay_us(1);
- }
- if(retry>=100)//如果没有拉高,无响应
- return 1;
-
- return 0;
- }
-
- //读1位数据
- u8 dht11_read_bit(void)
- {
- u32 retry = 0;
-
- //等待变为低电平,80us
- while(DQ_IN&&retry<100){
- retry++;
- delay_us(1);
- }
- if(retry>=100)//如果没有拉低,无响应
- return 100;
-
- retry = 0;
- //等待拉高,50us
- while(!DQ_IN&&retry<100){
- retry++;
- delay_us(1);
- }
- if(retry>=100)//如果没有拉高,无响应
- return 100;
-
- //延时40us,读取电平 低电平 ----- 0 高电平 ----- 1
- delay_us(40);
- return DQ_IN;
- }
-
- //读1字节数据,高位先出
- u8 dht11_read_byte(void)
- {
- u8 i,dat = 0;
-
- //连续读取8位
- for(i=0;i<8;i++){
- dat |= dht11_read_bit()<<(7-i);
- }
-
- return dat;
- }
-
- //读取温湿度数据
- //返回0表示成功,非0表示失败
- //temp和humi是输出参数,输出温湿度
- u8 dht11_read_data(u8 *temp,u8 *humi)
- {
- u8 i,buf[5];
-
- //起始信号
- if(dht11_check()==0){
- //读取40bit数据
- for(i=0;i<5;i++){
- buf[i] = dht11_read_byte();
- }
- //验证校验和
- if(((buf[0]+buf[1]+buf[2]+buf[3])&0xff)==buf[4]){
- *humi = buf[0];
- *temp = buf[2];
-
- return 0;
- }
- }
-
- return 1;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。