89C51单片机读取DHT11数据并用数码管显示

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/zxylv/article/details/91989499

前几天发了arduino读取dht11的文章【arduino读取DHT11温度、湿度数据并串口显示 】,里面DHT11的通信协议已经说明了,这里略过,贴个程序吧。测试过可用的。

晶振11.0592Mhz。

   

#include "reg52.h"
unsigned char num[10]={0xde,0x82,0xec,0xe6,0xb2,0x76,0x7e,0xc2,0xfe,0xf6};//数码管段码
unsigned char a[5]={0,0,0,0,0};//存放温度、湿度数据的数组,初始为0
unsigned char i,j,t;//for循环的变量
sbit out=P0^4;//DHT11的数据io接口
void delay(unsigned char x)// 1 ms 延时函数
{
    unsigned char i,j;
    for(i=0;i
        for(j=0;j< 110;j++);
}


void display(unsigned char a,unsigned char c) //数码管显示函数
{
    unsigned char i,b,d;
    b=a%10;//求出温度个位
    a=a/10;//温度十分位
    d=c%10;//湿度个位
    c=c/10;//湿度十分位
    for(i=0;i< 200;i++)
            {
            P2=num[a];//写入段码
            P0=0xfe;//打开第一个数码管
            delay(3);//延时
            P2=num[b];//写入段码
            P0=0xfd;//打开第二个数码管
            delay(3);//延时
            P2=num[c];//。。。。依此类推
            P0=0xfb;
            delay(3);
            P2=num[d];
            P0=0xf7;
            delay(3);
            }
}

void begin()//DHT11初始函数
{
  out=1;
  out=0;//数据线拉低
  delay(32);  //延时至少28ms
    out=1;//拉高
}

void read1()//读取温、湿度数据函数
{
    for(t=0;t< 3;t++);//延时大约30us
    if(out==0)//判断DHT11是否响应
    {
        while(out==0);//等待80us的低电平结束
        for(t=0;t< 2;t++);//延时若干us
        while(out==1);//等待80us的高电平结束
        for(i=0;i< 5;i++)//温度、湿度整数、小数部分以及校验值五个数据
        {
            for(j=0;j< 8;j++)//8位二进制数
            {  
                                while(out==0);//等待50us的低电平结束
                                a[i]=a[i]<<1;//数据左移1位
                                for(t=0;t< 4;t++);//等待大于30us小于70us的时间,这个指令具体延时多少不太确定
                                if(out==1)//如果数据线依然为高电平
                {
                    a[i]=a[i]|0x01;//说明此位是1
                                        while(out==1);//等待高电平结束进入下一位
                                }
                        }
                }
    }
    else    //如果DHT11无响应,则数据全为0
    {
        for(i=0;i< 5;i++)  
        {
         a[i]=0; 
        }
     }
        if(a[0]+a[2]!=a[4])//如果校验不通过,则数码管显示8888(因为读取到的小数位为0,这里就直接只取了整数位)
        {
            for(i=0;i< 5;i++)  
        {
         a[i]=88; 
        }
        }
}

void main()//主函数
{
    while(1)
    {
        begin();
        read1();
        out=1;
        display(a[2],a[0]);//因为读取到的小数位为0,这里就直接只取了整数值
    }
}

猜你喜欢

转载自blog.csdn.net/zxylv/article/details/91989499