技术路线及预期目标:
技术路线:本设计是基于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();
}
}
}
|