高级会员

- 积分
- 800
- 金钱
- 800
- 注册时间
- 2011-11-18
- 在线时间
- 5 小时
|
DHT11精度不咋地,很迟纯的感觉,比18b20差多了。但还好,有个湿度数据,日常生生活还可以的,做工业控制可能会摊上大事.....................
原子的MINI板直接运行
#ifndef __DHT11_H
#define __DHT11_H
#include "sys.h"
//IO方向设置
#define DHT11_IO_IN() {GPIOA->CRL&=0XFFFFFF0F;GPIOA->CRL|=0X00000080;GPIOA->ODR|=1<<1;}
#define DHT11_IO_OUT() {GPIOA->CRL&=0XFFFFFF0F;GPIOA->CRL|=0X00000030;GPIOA->ODR|=1<<1;}
////IO操作函数
#define DHT11_DQ_OUT PAout(1) //数据端口 PA1
#define DHT11_DQ_IN   Ain(1) //数据端口 PA1
#define OK 1
#define ERROR 0
u8 read_one_byte(void); //返回1个字节
u8 read_all_Byte(void); //返回 1:OK 2:ERROR
#endif
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "rtc.h"
#include "NRF24L01.h"
#include "remote.h"
#include "Fox_lcd.h"
#include "interface.h"
#include "BH1750.h"
#include "DS18B201.h"
#include "timer.h"
#include "flash.h"
#include "spi.h"
#include "FLOW.h"
#include "DHT11.h"
u8 U8DHT11_byte;
u8 U8DHT11_status;
u8 U8DHT11_data[5]; //0:湿度高8位 1:湿度低8位 2:温度高8位 3:温度低8位 4:校验位
extern u16 F_COLOR,B_COLOR;
//串行总线
u8 read_one_byte(void) //返回1个字节
{
u8 i,U8temp;
u8 electrical_level_count=0; //计数器
DHT11_IO_IN(); //输入模式
for(i=0;i<8;i++)
{
U8DHT11_byte <<=1; //先向左移一位 这样重复8次就读一个字出来了 !!!!!!!!! 这个不能放在最后,这是当式循环 放在最后会移多一位 !!!!!!!!!!!
electrical_level_count=0; //重置计数器
while(DHT11_DQ_IN == 0) //每一个byte之前都会有一个底电平 为50us 我们起个名字叫:字节前底电平
{
delay_us(10); //延时10us
electrical_level_count = electrical_level_count + 1; //每次延时10us,累计次数
if(electrical_level_count > 6) //如果累计次数超过5就出错退出,这里为了容错,加了一次累计
{
// printf("DHT11 low level ERROR :%x\n",i); //打印信息输出
U8DHT11_status = ERROR;
return 0;
}
}
delay_us(10); //延时30us ==》分三次,保险一点 这里的时间会大于delay_us(30);
delay_us(10);
delay_us(10);
//字节前底电平 后 是数据电平,如果高电平只有26-28us 那么这个表示数据 0,如果高电平有70us长(也可以说超过30us)那个这个表示数据 1.
U8temp=0;//先装入0,下面会判断数据电平如果超出30us会变成1的。
electrical_level_count=0; //重置计数器
while(DHT11_DQ_IN==1) //余下还有40us,看情况
{
delay_us(10); //延时10us
U8temp=1; //如果到这里DTA线还是高位就表示已经超过30us了,就表示这个byte是1.
electrical_level_count = electrical_level_count + 1; //每次延时10us,累计次数
if(electrical_level_count > 5) //如果累计次数超过4就出错退出,这里为了容错,加了一次累计
{
// printf("DHT11 hight level ERROR :%x\n",i); //打印信息输出
U8DHT11_status = ERROR;
return 0;
}
}
//好了,如果高电平 在合理要求内,程式会执行到这里,就算是正常了,接下来会对这个byte压进数据字里
U8DHT11_byte=U8DHT11_byte + U8temp; //这个byte压进数据字里
}//end of for(i=0;i<8;i++)
U8DHT11_status = OK; //状态值置OK
return U8DHT11_byte; //胜利返回一个U8DHT11字节
}
u8 read_all_Byte(void) //返回 1:OK 2:ERROR
{
u8 i;
u8 judge_count;
//主机拉低18ms
DHT11_IO_OUT(); //DAT线置为输出状态
DHT11_DQ_OUT=0;
delay_ms(18);
DHT11_DQ_OUT=1;
//总线由上拉电阻拉高 主机延时20-40us
delay_us(10);
delay_us(10);
delay_us(10);
delay_us(10);
//主机设为输入 判断从机响应信号
DHT11_IO_IN(); //输入模式
judge_count = 0;
while(DHT11_DQ_IN==1) //余下还有80us是DHT11表状态,看情况 如果80us内出现低电平,表示DHT11还活着,如果没有就表示挂了
{
delay_us(10); //延时10us
judge_count = judge_count + 1; //每次延时10us,累计次数
if(judge_count > 8) //如果累计次数超过8就出错退出
{
printf("DHT11 not noline(hight level) :%x\n",judge_count); //打印信息输出
return ERROR;
}
}
//执行到这里表示DHT11还活着 有应答信号:低电平
judge_count = 0;
while(DHT11_DQ_IN==0) //余下还有80us是低电平状态,看情况 如果超出80us低电平,表示DHT11又挂了
{
delay_us(10); //延时10us
judge_count = judge_count + 1; //每次延时10us,累计次数
if(judge_count > 8) //如果累计次数超过8就出错退出
{
printf("DHT11 not noline(low level) :%x\n",judge_count); //打印信息输出
return ERROR;
}
}
//执行到这里表示DHT11还活着 又来一个80us的高电平
judge_count = 0;
while(DHT11_DQ_IN==1) //余下还有80us是高电平状态,看情况 如果超出80us高电平,表示DHT11又挂了
{
delay_us(10); //延时10us
judge_count = judge_count + 1; //每次延时10us,累计次数
if(judge_count > 10) //如果累计次数超过10就出错退出 加多点是为了保险
{
printf("DHT11 not noline(no.2 hight level) :%x\n",judge_count); //打印信息输出
return ERROR;
}
}
//执行到这里表示DHT11还活着,活到这里DHT11就开始输出5个数据了
for(i=0;i<5;i++)
{
read_one_byte();
if(U8DHT11_status==OK)
{
U8DHT11_data = U8DHT11_byte;
}
else
{
printf("DHT11 read byte ERROR :%x\n",i); //打印信息输出
break;
}
}
//执行到这里DHT11还没挂,恭喜恭喜,数据读出来了 下面要看数据对不对,最后一个数是前4个数的总和。
printf("DHT11 U8DHT11_data[0] :%x\n",U8DHT11_data[0]);
printf("DHT11 U8DHT11_data[1] :%x\n",U8DHT11_data[1]);
printf("DHT11 U8DHT11_data[2] :%x\n",U8DHT11_data[2]);
printf("DHT11 U8DHT11_data[3] :%x\n",U8DHT11_data[3]);
printf("DHT11 U8DHT11_data[4] :%x\n",U8DHT11_data[4]);
if(U8DHT11_data[4]==U8DHT11_data[0]+U8DHT11_data[1]+U8DHT11_data[2]+U8DHT11_data[3]) printf("DHT11 data check OK :%x\n",U8DHT11_data[4]);
else printf("DHT11 data check ERROR :%x\n",U8DHT11_data[4]);
delay_ms(1000); //读取模块数据周期不宜小于 2S
delay_ms(1000);
return OK;
}
|
|