|
1黑幣
請教各位大神,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);
}
}
|
|