技術路線及預期目標:
技術路線:本設計是基于AT89C51為核心的單片機溫度監控系統。溫度信號由DHT11溫度傳感器進行采集,輸入單片機,由單片機對數字信號進行相應的處理,最終在1602顯示模塊上顯示。
預期目標:本系統以教室為一個溫度濕度采集范圍。
1.被測溫度均可以在顯示模塊上以數字形式顯示。
2.被測溫度范圍為 ℃,濕度范圍 精度為±0.5℃。
3.溫度和濕度超過額定值時,產生聲光報警。
主要內容:
1、溫度監控系統硬件結構設計
①掌握溫度采集模塊DHT11的工作原理和工作方式。
②掌握AT89C51芯片和顯示模塊1602的工作原理。
③系統對達到報警條件的溫度,如果達到報警讓LED燈產生變化。
2、硬件電路主要分為單片機系統、顯示電路、報警電路、溫度模塊采集電路等。單片機系統通過溫度采集模塊采集溫度,發送到基于AT89C51的單片機,通過基于AT89C51的單片機處理后,將結果送至顯示模塊顯示,并判斷溫度是否達到報警條件。
3、溫度監控系統軟件設計:通過Keil uVision4編寫本次設計的程序代碼,對代碼進行調試,完成后使用燒寫軟件STC_ISP_V480將程序燒寫進單片機。
4、繪制系統總體結構圖,系統原理圖,軟件流程圖。
5、對該系統可能存在的技術和理論問題,作必要的分析和探索研究。
/********************************************************************************/
#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數據接入
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; //設置標志位,報警標志位
uchar s1num,num,shis,shig,wens,weng;
unint8 TH_data,TL_data,RH_data,RL_data,CK_data; // dht11內部變量定義
unint8 TH_temp,TL_temp,RH_temp,RL_temp,CK_temp; // dht11內部變量定義
unint8 com_data,untemp,temp;
unint8 respond;
void delay(uint x) //毫秒級延時函數
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
void di() //蜂鳴器報警
{
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;//數據
P0=date;
delay(5);
en=1;
delay(5);
en=0;
}
void init1602()
{
write_com(0x38); //設置工作方式
write_com(0x0c); //設置光標
write_com(0x06); //設置輸入方式
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() //設置溫度上下限顯示初始化函數
{
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子程序*************************/
/*********************************************************************************/
/*********************************************************************************/
// 毫秒級延時子程序
/*********************************************************************************/
void delay_ms(U16 j)
{ unint8 i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
/*********************************************************************************/
/*********************************************************************************/
//5us級延時程序
/*********************************************************************************/
void delay_us()
{
unint8 i;
i--;
i--;
i--;
i--;
i--;
i--;
}
/********************************************************************************/
/****************************************************************************/
//收發信號檢測,數據讀取
/****************************************************************************/
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++);
//超時則跳出for循環
if(respond==1)break;
//判斷數據位是0還是1
// 如果高電平高過預定0高電平值則數據位為 1
com_data<<=1;
com_data|=temp;
}
return(com_data);
}
/****************************************************************************/
/****************************************************************************/
//濕度讀取子程序
//溫度高8位== TL_data
//溫度低8位== TH_data
//濕度高8位== RH_data
//濕度低8位== RH_data
//校驗 8位 == CK_data
//調用的程序有 delay();, Delay_5us();,RECEIVE();
/***************************************************************************/
void GET_TRH()
{
//主機拉低18ms
TRH=0;
delay_ms(180);
TRH=1;
//DATA總線由上拉電阻拉高 主機延時20us
delay_us();
delay_us();
delay_us();
delay_us();
//主機設為輸入 判斷從機響應信號
TRH=1;
//判斷DHT11是否有低電平響應信號 如不響應則跳出,響應則向下運行
if(!TRH)
{
respond=2;
//判斷DHT11發出 80us 的低電平響應信號是否結束
while((!TRH)&& respond++);
respond=2;
//判斷從機是否發出 80us 的高電平,如發出則進入數據接收狀態
while(TRH && respond++);
//數據接收狀態
RH_temp = receive();
RL_temp = receive();
TH_temp = receive();
TL_temp = receive();
CK_temp = receive();
TRH=1;//ST=1;
//數據校驗
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;
}
}
//濕度整數部分
shis= (char)(0X30+RH_data/10); //濕度的十位
shig= (char)(0X30+RH_data%10); //濕度的個
//溫度整數部分
wens= (char)(0X30+TH_data/10); //溫度的十位
weng= (char)(0X30+TH_data%10); //溫度的個位
//溫濕度顯示函數
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(); //設置溫度上下限初始化
write_H(3,hrh);
write_H(11,htemp);
write_L(3,lrh);
write_L(11,ltemp);
write_com(0x80+4);
write_com(0x0f); //打開光標
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); //關閉光標
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) // 報警
{
}
else
{
}
}
else //不報警
{
lalarm=0;
if(yyp==1)
{
}
}
if(lalarm==1)
{
di();
delay(100);
di();
delay(100);
}
}
/****************************************************************************/
//主函數
//TH,TL,RH,RL分別代表溫濕度的整數和小數部分
/****************************************************************************/
void main()
{
init1602();
while(1)
{
keyscan();
if(yyp==1)
{
keyscan();
GET_TRH();
baojing();
}
}
}
|