打印

51通过DHT获取温湿度,仿真温湿度智能显示偶数?

[复制链接]
392|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
请教各位大神,51单片机通过DHT11获取温湿度时,只能显示偶数值的温湿度,时序什么的都没发现问题
程序如下:
#include <reg52.h>
#include <stdio.h>
#include <intrins.h>
#define  uchar unsigned char
#define  uint  unsigned int
sbit DAT=P3^7;     //温度传感器信号线
sbit LED0=P2^0;                //湿度十位控制位
sbit LED1=P2^1;                //湿度个位控制位
sbit LED2=P2^2;                //温度十位控制位
sbit LED3=P2^3;                //温度个位
sbit LED4=P2^4;                //温度时分位
uchar code dula[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};                //数码管显示0~9数组
uchar RH0=0;
uchar Rh=0;        //用于存放上一次的湿度值,当获得的数据不满足校验要求时,显示上一次的温度值
uint tmp0=0,tmp1=0;                //tmp0用于存储温度值整数部分,tmp1用于存储温度值小数部分
uint tmp2=0,tmp3=0;                //tmp2用于存储上一次温度值的整数部分,tmp3用于存储上一次温度值的小数部分
/**********************************************************************
函数功能:延时子函数
入口参数:设置延时时长
时间:2019年08月09日
**********************************************************************/
void delayus(uint z)
{
        while(--z);
}
void delayms(uint x)
{
        uchar y;
        while(x--)
        {
                for(y=0;y<114;y++);
        }
}
/**********************************************************************
函数功能:DHT11
时间:2019年08月20日
**********************************************************************/
void start()
{
        DAT=1;
        delayus(2);
        DAT=0;
        delayms(30);                //主机拉低总线必须大于18ms,保证DHT11能检测到起始信号
        DAT=1;                        //发送起始信号结束后,拉高等待
        delayus(10);                //等待20~40us
}
/**********************************************************************
函数功能:从DHT11中获取 一个字节数据
时间:2019年08月20日
**********************************************************************/
uchar ReadByte(void)
{
        uchar dat=0,i;
        for(i=0;i<8;i++)
        {
                while(!DAT);                //等待50us的低电平开始信号结束
                delayus(5);                        //开始信号结束后,延时26~28us
                if(DAT==1)
                        dat|=0x01;                        //时间为26~28us,还为高电平,表示接收的数据为1
                else
                        dat|=0x00;
                while(DAT);                        //等待数据信号高电平,0为26~28us,1为70us
                dat<<=1;
        }
        return dat;
}
/**********************************************************************
函数功能:读温度值和湿度值,并校验温度值与湿度值
校验过程:校验数=温度值+湿度值
出口参数:读取的温度值
时间:2019年08月20日
**********************************************************************/
void DHT11()
{
        uchar Hh,Hl,Th,Tl,Rc;
        start();                        //开始信号
        DAT=1;
        delayus(10);
        Hh=ReadByte();                //接收湿度高8位
        Hl=ReadByte();                //接收湿度低8位
        Th=ReadByte();                //接收温度高8位
        Tl=ReadByte();                //接收温度低8位
        Rc=ReadByte();                //接收校正位
        DAT=0;                                //传输完40位,拉低结束,拉低时间54us,然后释放总线
        delayus(20);                //输出40位数据后,继续输出低电平54us后转为输入状态
        DAT=1;
        if((Hh+Hl+Th+Tl)==Rc)        //校正数据,如果等于,则执行下面语句,否则保持上一个数据不变
        {
                RH0=Hh;                        //湿度整数部分
                tmp0=Th;
                tmp1=Tl;
                Rh=RH0;                        //将得到的温度值放入Rh中以便不满足校验值时显示出来
                tmp2=tmp0;                //
                tmp3=tmp1;
        }
        else
        {
                RH0=Rh;                        //不满足校验要求显示上一次的湿度值
                tmp0=tmp2;                //不满足校验要求显示上一次的温度值
                tmp1=tmp3;
        }
}   
/**********************************************************************
函数功能:显示温/湿度子函数
入口参数:要显示的温度值和湿度值
时间:2019年08月20日
**********************************************************************/
void display()
{
        uchar s1,s2,w1,w2,w3;
        s1=RH0/10;                        //分离出湿度值十位数
        s2=RH0%10;                        //分离出湿度值个位数
        w1=tmp0/10;                        //分离出温度值十位数
        w2=tmp0%10;                        //分离出温度值个位数               
        w3=tmp1/10;                        //分离出温度值十分位数
        P2=0xff;
        P0=dula[s1];                //显示湿度值十位数
        LED0=0;
        delayus(200);
        P2=0xff;
        P0=dula[s2];                //显示湿度值个位数
        LED1=0;
        delayus(200);
        P2=0xff;
        if(tmp0>=10)
                P0=dula[w1];        //显示温度值十位数
        else
                P0=0x00;
        LED2=0;
        delayus(200);
        P2=0xff;
        P0=dula[w2]|0x80;        //显示温度值个位数
        LED3=0;
        delayus(200);
        P2=0xff;
        P0=dula[w3];        //显示温度值个位数
        LED4=0;
        delayus(200);
}
void main()
{
        uint sum=0;
        DAT=1;
        delayms(1000);
        while(1)
        {
                sum++;
                if(sum==100)
                {
                        sum=0;
                        DHT11();
                }
                display();
                delayms(10);
        }
}

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

457

主题

483

帖子

1

粉丝