最近在玩温湿度传感器DHT11、能显示、但是显示的数据不对、大概为正常值的一半左右的样子、我翻阅资料发现像这类的单总线数据传输的模块、对于延时非常精准、我的延时程序基本跟着使用手册写的、但是就是不能正确显示、恳请各路大神指点、下面是我的程序、
#include<lcd1602.h>
#include<dht11.h>
#define uint unsigned int
#define uchar unsigned char
uchar data_byte;
uchar RH,RL,TH,TL;
float R,T;
void delay1() //8us+延时
{
uchar i;
for(i=0;i<1;i++);
}
void start()
{
io=1;
delay1();
io=0;
delay(25); //总线拉低至少18ms、保证DHT11能检测到起始信号
io=1; //发送开始信号结束后、拉高总线20-40us
delay1();delay1();delay1(); //24us+
}
uchar receive_byte()
{
uchar i,temp;
for(i=0;i<8;i++)
{
while(!io); //等待50us的低电平开始信号结束
delay1();delay1();delay1(); //开始信号结束之后、延时26-28us
temp=0; //时间为26us-28us表示接收的为数据'0'
if(io==1)
temp=1; //如果26us-28us之后还为高电平则表示接收的数据为'1'
while(io); //等待数据信号高电平'0'为26us-28us'1'为70us
data_byte<<=1; //接收的数据为高位在前右移
data_byte|=temp;
}
return data_byte;
}
void receive()
{
uchar T_H,T_L,R_H,R_L,check,num_check,i;
start(); //开始信号
io=1; //主机设为输入判断从机DHT11响应信号
if(!io) //判断从机是否有低电平响应信号
{
while(!io); //判断从机发出 80us 的低电平响应信号是否结束
while(!io); //判断从机发出 80us 的高电平是否结束如结束则主机进入数据接收状态
R_H=receive_byte(); //湿度高位
R_L=receive_byte();
T_H=receive_byte(); //温度高位
T_L=receive_byte();
check=receive_byte();
io=0;
for(i=0;i<7;i++) //当最后一bit数据接完毕后从机拉低电平50us
delay1();delay1();delay1();delay1();delay1();delay1();delay1();
io=1; //总线由上拉电阻拉高进入空闲状态
num_check=R_H+R_L+T_H+T_L;
if(num_check==check) //判断读到的四个数据之和是否与校验位相同
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;
check=num_check;
}
}
}
void dhtdisplay()
{
receive();
lcddisplay(0x40,'R');
lcddisplay(0x41,':');
lcddisplay(0x42,(RH/10+0x30));
lcddisplay(0x43,(RH%10+0x30));
lcddisplay(0x44,0x2e);
lcddisplay(0x45,(RL%10+0x30));
lcddisplay(0x46,'%');
lcddisplay(0x48,'T');
lcddisplay(0x49,':');
lcddisplay(0x4a,(TH/10+0x30));
lcddisplay(0x4b,(TH%10+0x30));
lcddisplay(0x4c,0x2e);
lcddisplay(0x4d,(TL%10+0x30));
lcddisplay(0x4e,0xdf);
lcddisplay(0x4f,0x43);
}
头文件
#ifndef _dht11_h_
#define _dht11_h_
#include<reg52.h>
#include<intrins.h>
sbit io=P3^4;
void start();
uchar receive_byte();
void receive();
void dhtdisplay();
#endif
|