|
技術(shù)路線及預(yù)期目標(biāo):
技術(shù)路線:本設(shè)計(jì)是基于AT89C51為核心的單片機(jī)溫度監(jiān)控系統(tǒng)。溫度信號由DHT11溫度傳感器進(jìn)行采集,輸入單片機(jī),由單片機(jī)對數(shù)字信號進(jìn)行相應(yīng)的處理,最終在1602顯示模塊上顯示。
預(yù)期目標(biāo):本系統(tǒng)以教室為一個(gè)溫度濕度采集范圍。
1.被測溫度均可以在顯示模塊上以數(shù)字形式顯示。
2.被測溫度范圍為 ℃,濕度范圍 精度為±0.5℃。
3.溫度和濕度超過額定值時(shí),產(chǎn)生聲光報(bào)警。
主要內(nèi)容:
1、溫度監(jiān)控系統(tǒng)硬件結(jié)構(gòu)設(shè)計(jì)
①掌握溫度采集模塊DHT11的工作原理和工作方式。
②掌握AT89C51芯片和顯示模塊1602的工作原理。
③系統(tǒng)對達(dá)到報(bào)警條件的溫度,如果達(dá)到報(bào)警讓LED燈產(chǎn)生變化。
2、硬件電路主要分為單片機(jī)系統(tǒng)、顯示電路、報(bào)警電路、溫度模塊采集電路等。單片機(jī)系統(tǒng)通過溫度采集模塊采集溫度,發(fā)送到基于AT89C51的單片機(jī),通過基于AT89C51的單片機(jī)處理后,將結(jié)果送至顯示模塊顯示,并判斷溫度是否達(dá)到報(bào)警條件。
3、溫度監(jiān)控系統(tǒng)軟件設(shè)計(jì):通過Keil uVision4編寫本次設(shè)計(jì)的程序代碼,對代碼進(jìn)行調(diào)試,完成后使用燒寫軟件STC_ISP_V480將程序燒寫進(jìn)單片機(jī)。
4、繪制系統(tǒng)總體結(jié)構(gòu)圖,系統(tǒng)原理圖,軟件流程圖。
5、對該系統(tǒng)可能存在的技術(shù)和理論問題,作必要的分析和探索研究。
/********************************************************************************/
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char //宏定義
#define uint unsigned int
typedef unsigned char unint8;
typedef unsigned char unint16;
typedef unsigned int U16;
uchar code table[] = {" s: %RH "};
uchar code table1[] ={" w: "};
uchar code table2[] ={"SH: % WH: C "};
uchar code table3[] ={"SL: % WL: C "};
sbit TRH = P1^1;//溫濕度傳感器DHT11數(shù)據(jù)接入
sbit rs = P2^6;
sbit en = P2^7;
sbit beep=P1^0;//蜂鳴器控制端
sbit k1=P3^1;
sbit k2=P3^2;
sbit k3=P3^3;
uchar htemp=33,ltemp=15,hrh=60,lrh=10; //溫濕度上下線初始化
bit yyp=1,lalarm=0; //設(shè)置標(biāo)志位,報(bào)警標(biāo)志位
uchar s1num,num,shis,shig,wens,weng;
unint8 TH_data,TL_data,RH_data,RL_data,CK_data; // dht11內(nèi)部變量定義
unint8 TH_temp,TL_temp,RH_temp,RL_temp,CK_temp; // dht11內(nèi)部變量定義
unint8 com_data,untemp,temp;
unint8 respond;
void delay(uint x) //毫秒級延時(shí)函數(shù)
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
void di() //蜂鳴器報(bào)警
{
beep=0;
delay(100);
beep=1;
}
void write_com(uchar com)
{
rs=0;//命令
P0=com;
delay(5);
en=1;
delay(5);
en=0;
}
void write_date(uchar date)
{
rs=1;//數(shù)據(jù)
P0=date;
delay(5);
en=1;
delay(5);
en=0;
}
void init1602()
{
write_com(0x38); //設(shè)置工作方式
write_com(0x0c); //設(shè)置光標(biāo)
write_com(0x06); //設(shè)置輸入方式
write_com(0x01); //清屏
write_com(0x80);
for(num=0;num<16;num++)
{
write_date(table[num]);
}
write_com(0x80+0x40);
for(num=0;num<16;num++)
{
write_date(table1[num]);
}
}
void init16021() //設(shè)置溫度上下限顯示初始化函數(shù)
{
write_com(0x80);
for(num=0;num<16;num++)
{
write_date(table2[num]);
}
write_com(0x80+0x40);
for(num=0;num<16;num++)
{
write_date(table3[num]);
}
write_com(0x80+0x40+13);
write_date(0xdf);
write_com(0x80+13);
write_date(0xdf);
}
void write_H(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void write_L(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
/////////////////////////////////
/***********DHT11子程序*************************/
/*********************************************************************************/
/*********************************************************************************/
// 毫秒級延時(shí)子程序
/*********************************************************************************/
void delay_ms(U16 j)
{ unint8 i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
/*********************************************************************************/
/*********************************************************************************/
//5us級延時(shí)程序
/*********************************************************************************/
void delay_us()
{
unint8 i;
i--;
i--;
i--;
i--;
i--;
i--;
}
/********************************************************************************/
/****************************************************************************/
//收發(fā)信號檢測,數(shù)據(jù)讀取
/****************************************************************************/
char receive()
{
unint8 i;
for(i=0;i<8;i++)
{
respond=2;
while((!TRH)&&respond++);
delay_us();
delay_us();
delay_us();
temp=0;
if(TRH)temp=1;
respond=2;
while((TRH)&&respond++);
//超時(shí)則跳出for循環(huán)
if(respond==1)break;
//判斷數(shù)據(jù)位是0還是1
// 如果高電平高過預(yù)定0高電平值則數(shù)據(jù)位為 1
com_data<<=1;
com_data|=temp;
}
return(com_data);
}
/****************************************************************************/
/****************************************************************************/
//濕度讀取子程序
//溫度高8位== TL_data
//溫度低8位== TH_data
//濕度高8位== RH_data
//濕度低8位== RH_data
//校驗(yàn) 8位 == CK_data
//調(diào)用的程序有 delay();, Delay_5us();,RECEIVE();
/***************************************************************************/
void GET_TRH()
{
//主機(jī)拉低18ms
TRH=0;
delay_ms(180);
TRH=1;
//DATA總線由上拉電阻拉高 主機(jī)延時(shí)20us
delay_us();
delay_us();
delay_us();
delay_us();
//主機(jī)設(shè)為輸入 判斷從機(jī)響應(yīng)信號
TRH=1;
//判斷DHT11是否有低電平響應(yīng)信號 如不響應(yīng)則跳出,響應(yīng)則向下運(yùn)行
if(!TRH)
{
respond=2;
//判斷DHT11發(fā)出 80us 的低電平響應(yīng)信號是否結(jié)束
while((!TRH)&& respond++);
respond=2;
//判斷從機(jī)是否發(fā)出 80us 的高電平,如發(fā)出則進(jìn)入數(shù)據(jù)接收狀態(tài)
while(TRH && respond++);
//數(shù)據(jù)接收狀態(tài)
RH_temp = receive();
RL_temp = receive();
TH_temp = receive();
TL_temp = receive();
CK_temp = receive();
TRH=1;//ST=1;
//數(shù)據(jù)校驗(yàn)
untemp=(RH_temp+RL_temp+TH_temp+TL_temp);
if(untemp==CK_temp)
{
RH_data = RH_temp;
RL_data = RL_temp;
TH_data = TH_temp;
TL_data = TL_temp;
CK_data = CK_temp;
}
}
//濕度整數(shù)部分
shis= (char)(0X30+RH_data/10); //濕度的十位
shig= (char)(0X30+RH_data%10); //濕度的個(gè)
//溫度整數(shù)部分
wens= (char)(0X30+TH_data/10); //溫度的十位
weng= (char)(0X30+TH_data%10); //溫度的個(gè)位
//溫濕度顯示函數(shù)
write_com(0x80+6);
write_date(shis);
write_date(shig);
write_date('%'); //濕度符號
write_com(0x80+0x40+6);
write_date(wens);
write_date(weng);
write_date(0xdf); //溫度符號
write_date('C');
}
/****按鍵掃描******/
void keyscan()
{
if(k1==0)
{
delay(10);
if(k1==0)
{
s1num++;
while(!k1); //等待按鍵釋放
yyp=0;
di();
switch(s1num)
{
case 1: init16021(); //設(shè)置溫度上下限初始化
write_H(3,hrh);
write_H(11,htemp);
write_L(3,lrh);
write_L(11,ltemp);
write_com(0x80+4);
write_com(0x0f); //打開光標(biāo)
break;
case 2: write_com(0x80+0x40+4);
break;
case 3: write_com(0x80+12);
break;
case 4: write_com(0x80+0x40+12);
break;
case 5: s1num=0;
write_com(0x0c); //關(guān)閉光標(biāo)
yyp=1;
init1602(); //上電后顯示初始化
break;
}
}
}
if(s1num!=0)
{
if(k2==0)
{
delay(10);
if(k2==0)
{
while(!k2); //等待按鍵釋放
di();
switch(s1num)
{
case 1: hrh++;
if(hrh==85)hrh=0;
write_H(3,hrh);
write_com(0x80+4);
break;
case 2: lrh++;
if(lrh==60)lrh=0;
write_L(3,lrh);
write_com(0x80+0x40+4);
break;
case 3: htemp++;
if(ltemp==50)ltemp=0;
write_H(11,htemp);
write_com(0x80+11);
break;
case 4: ltemp++;
if(ltemp==50)ltemp=0;
write_L(11,ltemp);
write_com(0x80+0x40+12);
break;
}
}
}
if(k3==0)
{
delay(10);
if(k3==0)
{
while(!k3); //等待按鍵釋放
di();
switch(s1num)
{
case 1: hrh--;
if(hrh==0)hrh=85;
write_H(3,hrh);
write_com(0x80+4);
break;
case 2: lrh--;
if(lrh==0)lrh=60;
write_L(3,lrh);
write_com(0x80+0x40+4);
break;
case 3: htemp--;
if(ltemp==0)ltemp=50;
write_H(11,htemp);
write_com(0x80+11);
break;
case 4: ltemp--;
if(ltemp==0)ltemp=50;
write_L(11,ltemp);
write_com(0x80+0x40+12);
break;
}
}
}
}
}
void baojing()
{
if((TH_data>htemp||RH_data>hrh)||(TH_data<ltemp||RH_data<lrh))//判斷溫濕度
{
lalarm=1;
if(RH_data>hrh||RH_data<lrh) // 報(bào)警
{
}
else
{
}
}
else //不報(bào)警
{
lalarm=0;
if(yyp==1)
{
}
}
if(lalarm==1)
{
di();
delay(100);
di();
delay(100);
}
}
/****************************************************************************/
//主函數(shù)
//TH,TL,RH,RL分別代表溫濕度的整數(shù)和小數(shù)部分
/****************************************************************************/
void main()
{
init1602();
while(1)
{
keyscan();
if(yyp==1)
{
keyscan();
GET_TRH();
baojing();
}
}
}
|
|