OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4916|回复: 2

近来要用DHT11来做试验,供应商和网上的例子很乱自己重写一次,感觉好看多了,给同学们共享一下

[复制链接]

71

主题

467

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2011-11-18
在线时间
5 小时
发表于 2014-7-13 20:41:07 | 显示全部楼层 |阅读模式
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; 
}

我的工作就是天天在玩
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2014-9-26
在线时间
0 小时
发表于 2014-9-26 22:33:22 | 显示全部楼层
求助

我那个怎么不行http://www.openedv.com/posts/list/39952.htm
回复 支持 反对

使用道具 举报

71

主题

467

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2011-11-18
在线时间
5 小时
 楼主| 发表于 2014-9-27 19:30:21 | 显示全部楼层
飙泪呀,偶不想看代码了..................我的代码是可以直接用的,你对比一下吧。
我的工作就是天天在玩
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-1 03:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表