|
/************************************************
項 目:溫、濕度測量程序
單片機:STC12C5A60S2
傳感器:DHT11
日 期:2015.04.09
************************************************/
#include <stc12c5a60s2.h>
#define uint unsigned int
#define uchar unsigned char
sbit io = P2^0; //定義數據端口
uchar data_byte; //定義全局變量
uchar RH,RL,TH,TL; //定義全局變量
unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 顯示段碼值0~9
uchar TempData[5]; //存儲顯示值的全局變量
/*------------------------------------------------
uS延時函數,含有輸入參數 unsigned char t,無返回值
unsigned char 是定義無符號字符變量,其值的范圍是
0~255 這里使用晶振12M,精確延時請使用匯編,大致延時
長度如下 T=tx2+5 uS
------------------------------------------------*/
void delayus(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延時函數,含有輸入參數 unsigned char t,無返回值
unsigned char 是定義無符號字符變量,其值的范圍是
0~255 這里使用晶振12M,精確延時請使用匯編
------------------------------------------------*/
void delayms(unsigned char t)
{
while(t--)
{
//大致延時1mS
delayus(245);
delayus(245);
}
}
/******************** DHT11測試模塊**********************/
void start() //開始信號
{
io=1;
delayus(10);
io=0;
delayms(30); //10~60之間
io=1;
delayus(100); //關鍵時間:35-250之間
}
/**********************接收一個字節(jié)**********************/
uchar receive_byte()
{
uchar i,temp,count;
for(i=0;i<8;i++)
{
count=2;
while((!io)&&count++)
temp=0;
delayus(150); //關鍵時間:10~23之間
if(io==1)temp=1;
count=2;
while((io)&&count++);
if(count==1)break;
data_byte<<=1;
data_byte|=temp;
}
return data_byte;
}
/************************接收數據************************/
void receive()
{
uchar T_H,T_L,R_H,R_L,check,num_check;
uchar count;
start(); //開始信號
io=1;
if(!io) //讀取DHT11響應信號
{
count=2;
while((!io)&&count++); //DHT11高電平80us是否結束
count=2;
while((io)&&count++);
R_H=receive_byte();
R_L=receive_byte();
T_H=receive_byte();
T_L=receive_byte();
check=receive_byte();
io=0;
delayms(1); //拉低延時
io=1;
num_check=R_H+R_L+T_H+T_L;
if(num_check=check)
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;
check=num_check;
}
}
}
/**********************************************************************
顯示子函數
**********************************************************************/
void display()
{
P2=0xef;
P0=TempData[0];
delayms(20);
P2=0xff;
P2=0xdf;
P0=TempData[1];
delayms(20);
P2=0xff;
P2=0xbf;
P0=TempData[2];
delayms(20);
P2=0xff;
P2=0x7f;
P0=TempData[3];
delayms(20);
P2=0xff;
}
/*******************************************************************
定時器初始化子函數
*******************************************************************/
void InitTimer(void)
{
TMOD |= 0x01; //定義定時器T0,工作方式1
TH0=(65536-20000)/256;
TL0=(65536-20000)%256; //50ms
ET0=1;
TR0=1;
EA = 1; //開總中斷
}
/***************************主函數**************************/
void main()
{
P0M0=0xFF; //定義P0口為推挽輸出 1111 1111
// P2M0=0xF0; //定義P2.4 ~ P2.7口為推挽輸出 1111 0000
InitTimer();
delayms(10);
while(1)
{
receive();
TempData[0]=DuanMa[RH/10];
TempData[1]=DuanMa[RH%10];
TempData[2]=DuanMa[TH/10];
TempData[3]=DuanMa[TH%10];
delayms(20);
display();
}
}
/***********************************************************************
定時器T1中斷子函數
***********************************************************************/
void timer0(void) interrupt 1
{
uchar ms;
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
ms++; //ms++
if(ms==50) //如果等于10*500us=5ms
{
ms=0; //ms清0
}
// display(); //調用顯示子函數
}
|
|