找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2394|回复: 0
打印 上一主题 下一主题
收起左侧

51单片机+DHT11读数据时而正确时而错误

[复制链接]
跳转到指定楼层
楼主
ID:884998 发表于 2021-2-27 21:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
两段程序用的DHT11驱动是同一个文件,
下面这段程序可以正常运行,可以正常显示数据,数据也是正常的:

    #include<reg51.h>
        #include<intrins.h>
    #define uchar unsigned char        //无符号字符型类型数据
    #define uint unsigned int //无符号整型数据

        extern void InitLCD1602();
        extern void LcdShowStr(uchar x, uchar y, uchar *str);
        extern void DHT11GetData(uchar *dat);
        extern void Delay20ms();
        void Delay1000ms();
        void RefreashDHT11DataShow();
        sbit lcd1602bg = P2^2;
        uchar dht11data[5] = {48,49,50,51,'\0'};
        
        void main()
        {
            
            lcd1602bg = 0;
            Delay1000ms();
            
            InitLCD1602();
            while(1)
            {
                Delay1000ms();
                DHT11GetData(dht11data);
                LcdShowStr(0,0,dht11data);
                RefreashDHT11DataShow();
            }
        }

        
        
void RefreashDHT11DataShow()
{
    static uchar RH[3],Temp[3];
   
    RH[0] = dht11data[0];
    RH[1] = dht11data[1];
    RH[2] = '\0';
    Temp[0] = dht11data[2];
    Temp[1] = dht11data[3];
    Temp[2] = '\0';
   
    LcdShowStr(13,0,RH);
    LcdShowStr(12,1,Temp);
}

void Delay1000ms()        //@11.0592MHz
{
    unsigned char i, j, k;

    _nop_();
    i = 8;
    j = 1;
    k = 243;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}






下面这段程序就会出现数据时而正确,时而错误(省去了关于时间和按键的代码,时间和按键的代码也是完全正常的运行,之前测试过了):
#include <reg52.h>

typedef unsigned char uchar;
typedef unsigned int uint;


bit timeflag200ms = 1;
bit dht11flag1s = 0;
struct stime buftime;                                        //日期时间缓冲区
uchar dht11data[4];                                          //湿度十位,湿度个位,温度十位,温度个位
uchar T0RH = 0;                                              //T0重载值的高字节
uchar T0RL = 0;                                              //T0重载值的低字节
uint setindex = 0;                                           //时间设置索引

sbit lcd1602gb = P2^2;
extern void KeyScan();                                       //扫描按键
extern void KeyDriver();                                     //按键驱动
   
extern void InitDS1302();                                    //初始化DS1302
extern void GetRealTime(struct stime *time);                 //获得时间
extern void SetRealTime(struct stime *time);                 //设置时间

extern void InitLcd1602();                                   //初始化LCD1602
extern void LcdShowStr(uchar x, uchar y, uchar *str);        //显示字符串 在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,str-字符串指针
extern void LcdSetCursor(uchar x, uchar y);                  //设置坐标
extern void LcdOpenCursor();                                 //打开闪烁光标
extern void LcdCloseCursor();                                //关闭光标
extern void LcdWriteDat(uchar dat);                         //写字符
extern void LcdSetCursor(uchar x, uchar y);                  //设置光标位置

extern void DHT11GetData(uchar *dat);                        //获取DHT11数据

void ConfigTimer0(uint ms);                                  //配置计时器T0
void RefreshTimeShow();                                      //刷新时间显示
void RefreashDHT11DataShow();                                //刷新DHT11数据显示

void main()
{
    uchar psec = 0xAA;                //秒备份,初值AA确保首次读取时间后会刷新显示
  uchar du = 0xdf;                  //°ascii码         
    EA = 1;                           //开总中断
    ConfigTimer0(1);                  //T0定时1ms
    InitDS1302();                     //初始化实时时钟
    InitLcd1602();                    //初始化液晶
   
    //初始化屏幕上固定不变的内容
  LcdShowStr(0, 0, "20  -  -       %");
  LcdShowStr(0, 1, "  :  :         C");
    LcdSetCursor(14,1);
    LcdWriteDat(du);                  //显示°符号
    lcd1602gb = 0;                    //默认打开背光
   
    while(1)
    {
        KeyDriver();
        if(timeflag200ms && (setindex == 0))
        {
            timeflag200ms = 0;
            GetRealTime(&buftime);        //获取当前时间
            if (psec != buftime.sec)      //检测到时间有变化时刷新显示
            {
                RefreshTimeShow();
                psec = buftime.sec; //用当前值更新上次秒数
            }
        }
                  if(dht11flag1s && (setindex == 0))
                {
                    dht11flag1s = 0;
                    DHT11GetData(dht11data);
                    RefreashDHT11DataShow();
                }
    }
}

void ConfigTimer0(uint ms)
{
    unsigned long tmp;                //临时变量
   
    tmp = 11059200 / 12;                //定时器计数频率
    tmp = (tmp * ms) / 1000;          //计算所需的计数值
    tmp = 65536 - tmp;                //计算定时器重载值
    tmp = tmp + 28;                   //补偿中断响应延时造成的误差
    T0RH = (uchar)(tmp>>8);           //定时器重载值拆分为高低字节
    T0RL = (uchar)tmp;
    TMOD &= 0xF0;                     //清零T0的控制位
    TMOD |= 0x01;                     //配置T0为模式1
    TH0 = T0RH;                       //加载T0重载值
    TL0 = T0RL;                       
    ET0 = 1;                          //使能T0中断
    TR0 = 1;                          //启动T0
}

void RefreashDHT11DataShow()
{
    static uchar RH[3],Temp[3];
   
    RH[0] = dht11data[0];
    RH[1] = dht11data[1];
    RH[2] = '\0';
    Temp[0] = dht11data[2];
    Temp[1] = dht11data[3];
    Temp[2] = '\0';
   
    LcdShowStr(13,0,RH);
    LcdShowStr(12,1,Temp);
}

void InterruptTimer0() interrupt 1
{
    static uint tmr200ms = 0;
    static uint tmr1s = 0;
   
    TH0 = T0RH;  //重新加载重载值
  TL0 = T0RL;
    KeyScan();
   
    tmr200ms++;
    tmr1s++;
   
    if (tmr200ms >= 200)  //定时200ms
    {
        tmr200ms = 0;
        timeflag200ms = 1;
    }
        if(tmr1s >= 1000)
        {
            tmr1s = 0;
            dht11flag1s = 1;
        }
}




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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