|
/*P0口段輸出,P2口位控制,前兩位數碼管顯示濕度,后三位顯示溫度,溫度值為-19.9度至99.9度之間,顯示負溫度時要在前面加負號,小數點隨溫度變化要改變他的位置。下面程序數碼管不顯示,請高手指教!*/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define TEMP_MEASURE 0x03 //000 00011 測試溫度命令
#define HUMI_MEASURE 0x05 //000 00101 測試溫度命令
sbit DHT_DATA=P1^6;
sbit DHT_SCK=P1^7;
uchar code SEGMENT_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40,0x46,0x79,0x38,0x76};//0,1,2,3,4,5,6,7,8,9,熄滅,-,-1,E,L,H
uchar code BIT_CODE[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,0x3f,0xc7,0x00};
uchar wen,a,shan,tt,sec_point,shift,shi_12,shi_a,sec_point_flag,DHT_TIME,TEMP_LOW,TEMP_HIGH;
uchar k_d_s;
uchar tab1[9];
uchar tab2[9];
uchar DHT_L,DHT_H,DHT_ACK,DHT_ERROR;
unsigned int VALUE_TEMP,VALUE_HUMI,DIS_TEMP,DIS_HUMI;//濕度顯示值
uchar TEMP_SIGNS;
uchar TEMP_L_BYTE,TEMP_H_BYTE,TEMP_DECIMAL;
/*************************************************
延時程序
**************************************************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=60;y>0;y--);
}
/*************************************************
DHT61讀高低兩個字節,返回應答信號
**************************************************/
void DHT61_READ_TWO_BYTE()
{
unsigned char i,val=0;
DHT_L=0;
DHT_H=0;
DHT_DATA=1; //釋放數據總線
for (i=0x80;i>0;i/=2) //位移8位
{ DHT_SCK=1; //上升沿讀入
if (DHT_DATA) val=(val | i); //確定值
DHT_SCK=0;
}
DHT_DATA=0; //讀應答信號,有應答為1,無應答為0 通過CPU下拉為應答
DHT_SCK=1; //第9個脈沖
_nop_(); _nop_(); _nop_(); //pulswith approx. 5 us
DHT_SCK=0;
DHT_DATA=1; //釋放數據總線
DHT_H=val;
val=0;
////低8位/////////////////////////////
DHT_DATA=1; //釋放數據總線
for (i=0x80;i>0;i/=2) //位移8位
{ DHT_SCK=1; //上升沿讀入
if (DHT_DATA) val=(val | i); //確定值
DHT_SCK=0;
}
DHT_DATA=1;//0; //不需要應答 通過CPU下拉為應答
DHT_SCK=1; //第9個脈沖
_nop_(); _nop_(); _nop_(); //pulswith approx. 5 us
DHT_SCK=0;
DHT_DATA=1; //釋放數據總線
DHT_L=val;
}
/**************************************************
向DHT61寫一個字節 返回應答信號
*****************************************************/
char WRITE_DHT61_BYTE(unsigned char value)
{
unsigned char i ;
DHT_ACK=0;
for (i=0x80;i>0;i/=2) //釋放數據總線
{ if (i & value) DHT_DATA=1; //寫入值
else DHT_DATA=0;
DHT_SCK=1; //上升沿寫入
_nop_(); _nop_(); _nop_(); //延時
DHT_SCK=0;
}
DHT_DATA=1; //釋放數據總線
DHT_SCK=1; //第9個脈沖
if (DHT_DATA==1) DHT_ACK=1;
//讀應答信號
DHT_SCK=0;
return DHT_ACK; //error=1 表示沒有應答
}
/**************************
函數功能:DHT61啟動時序
***************************/
void DHT_START(void)
{
DHT_DATA=1; DHT_SCK=0; //數據為1,SCK=0
_nop_();
DHT_SCK=1; //第一個脈沖
_nop_();
DHT_DATA=0; //數據跌落
_nop_ ();
DHT_SCK=0; //完成一個脈沖
_nop_(); _nop_(); _nop_();
DHT_SCK=1; //再一個脈沖
_nop_();
DHT_DATA=1; //數據變為1
_nop_();
DHT_SCK=0; //完成該脈沖
}
/**************************
DHT61復位時序
***************************/
void DHT_RESET(void)
{
unsigned char i;
DHT_DATA=1; DHT_SCK=0; //數據為1 時鐘為0
for(i=0;i<9;i++) //9 個脈沖為 復位
{ DHT_SCK=1;
DHT_SCK=0;
}
DHT_START(); //啟動
}
/***********************************************
DHT61測量溫度或者是溫度,返回校驗值
***********************************************/
void DHT_MEASURE(unsigned char ml)
{
DHT_START(); //啟動
WRITE_DHT61_BYTE(ml);//寫入測溫度
if (DHT_ACK==1)
{
DHT_RESET() ;//復位
WRITE_DHT61_BYTE(ml);//寫入測溫度
}
}
/**************************
DHT61溫度處理
/***************************/
void PROCESS_DHT_TEMP()
{
float aa=0,bb=0,temp_zi;
int abcd=0;
aa=(float)DHT_H*256+(float)DHT_L;
temp_zi=0.01*aa-40;
if (temp_zi<0)
{TEMP_SIGNS=1;
temp_zi=-temp_zi*10;
VALUE_TEMP=(int)temp_zi;
if(VALUE_TEMP>=200) TEMP_LOW=1;
else TEMP_LOW=0;
}
else {TEMP_SIGNS=0;
temp_zi=temp_zi*10;
VALUE_TEMP=(int)temp_zi;//給顯示值
}
}
/**************************
DHT61濕度處理
***************************/
void PROCESS_DHT_HUMI()
{
float aa=0,bb=0,humi_zi;
int abcd=0;
aa=(float)DHT_H*256+(float)DHT_L;
bb=aa*aa*2.8/1000000;
aa=0.0405*aa;
aa=aa-4-bb;
humi_zi=aa;
if (humi_zi>99.9)
{
humi_zi=99.9;
}
humi_zi=humi_zi*10;
VALUE_HUMI=(int)humi_zi;
}
/*************************************************
萬年歷顯示子程序
**************************************************/
void display()
{
DIS_HUMI=VALUE_HUMI;
P0=SEGMENT_CODE[DIS_HUMI/100];
P2=BIT_CODE[12];
DIS_HUMI=DIS_HUMI%100;
P0=SEGMENT_CODE[DIS_HUMI/10];
P2=BIT_CODE[12];
DIS_TEMP=VALUE_TEMP;
DIS_TEMP=DIS_TEMP%1000;
/* 下為修正負溫度顯示而加 可顯示-19.9~99.9溫度 下 */
if(TEMP_SIGNS==1)
{
if((DIS_TEMP/100)==0)
P0=SEGMENT_CODE[11];
if((DIS_TEMP/100)==1)
P0=SEGMENT_CODE[12];
if((DIS_TEMP/100)>1)
P0=SEGMENT_CODE[13];
}
/* 上 為修正負溫度顯示而加 可顯示-19.9~99.9溫度 上 */
else
P0=SEGMENT_CODE[DIS_TEMP/100];
P2=BIT_CODE[12];
/* 為修正負溫度顯示而加 溫度低于-20攝氏度時,顯示E-L */
if(TEMP_LOW==1)
{
P0=SEGMENT_CODE[11];
P0=SEGMENT_CODE[14];
}
else
{
DIS_TEMP=DIS_TEMP%100;
P0=SEGMENT_CODE[DIS_TEMP/10]|0x80;
DIS_TEMP=DIS_TEMP%10;
P0=SEGMENT_CODE[DIS_TEMP%10];
}
P2=BIT_CODE[12];
P0=SEGMENT_CODE[10];
P2=BIT_CODE[12];
}
/*************************************************
主程序
**************************************************/
void main()
{
TMOD=1;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
EA=1;
ET0=1;
TR0=1;
shan=0x00;
DHT_DATA=1;
DHT_SCK=1;
while(1)
{
}
DHT_ERROR=0;
DHT_ACK=0;
DHT_RESET() ;//復位
DHT_MEASURE(TEMP_MEASURE);
while (DHT_DATA)
{
}
DHT61_READ_TWO_BYTE();//讀溫度
PROCESS_DHT_TEMP();
DHT_MEASURE(HUMI_MEASURE);
while(DHT_DATA)
{
}
DHT61_READ_TWO_BYTE();//讀溫度
PROCESS_DHT_HUMI();
}
/*************************************************
定時中斷子程序
**************************************************/
void time0() interrupt 1
{
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
display();
tt++;
sec_point++;
if(tt==50) //設置閃爍
{tt=0;
shan=~shan;
}
if(sec_point==100) //秒點閃爍
{ sec_point=0;
sec_point_flag=~sec_point_flag;
}
}
|
|