|
兩段程序用的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;
}
}
|
|