温度检测与高温警报系统.docx
《温度检测与高温警报系统.docx》由会员分享,可在线阅读,更多相关《温度检测与高温警报系统.docx(20页珍藏版)》请在冰豆网上搜索。
![温度检测与高温警报系统.docx](https://file1.bdocx.com/fileroot1/2023-3/29/5478e2fe-cc29-4f3d-b279-b7d395075601/5478e2fe-cc29-4f3d-b279-b7d3950756011.gif)
温度检测与高温警报系统
《单片机原理》
实训报告
姓名:
沈俊卫
学号:
1145533129
班级:
11电气1班
专业:
电气工程及其自动化
学院:
电气与信息工程学院
江苏科技大学(张家港)
2014年12月
目录
一设计内容及要求2
二设计方案2
三硬件系统设计2
1、STC89C522
2、时钟晶振3
3、LED指示灯3
4、数码管3
5、矩阵键盘3
6、蜂鸣器4
四、软件系统设计4
五、程序代码6
基于51单片机的温度检测与高温报警系统
一设计内容及要求
设计内容:
基于单片机的室内温度检测LED数码管显示及高温报警
要求:
检测室内温度变化,并进行显示;
可进行正常运行与报警不同状态的显示;
可预设报警温度,一旦超过该温度进行报警;
温度报警:
超出温度上下限BEEP报警。
二设计方案
测温部分:
采用18B20作为温度传感器,有一个由高低电平触发的且不因掉电而丢失的报警功能。
控制部分:
STC89C52实验开发板
显示部分:
八段数码管显示。
三硬件系统设计
1、STC89C52
图1STC89C52引脚图
8k字节Flash,512字节RAM,32位I/O口线,看门狗定时器,内置4KBEEPROM,MAX810复位电路,3个16位定时器/计数器,4个外部中断,一个7向量4级中断结构(兼容传统51的5向量2级中断结构),全双工串行口。
另外STC89C52可降至0Hz静态逻辑操作,支持2种软件可选择节电模式。
空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。
掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。
最高运作频率35MHz。
(如图1所示)
2、时钟晶振
原理图如图2所示。
图2时钟晶振原理图
3、LED指示灯
原理图如图3所示。
图3LED灯原理图
4、数码管
原理图如图4所示。
图4数码管原理图
5、矩阵键盘
矩阵键盘原理图如图5所示。
设计中用S2作为设定确认键,S3和S4分别作为温度加和减的设定键。
图5矩阵键盘
6、蜂鸣器
原理图如图6所示。
图6蜂鸣器原理图
四、软件系统设计
系统设计原理:
本次设计是基于单片机的数码管温度计设计,在开始设计的之前学会使用KEIL软件。
根据设计要求选择好器件,编写好程序运行成功之后进行程序调试,验证系统是否正确。
通过筛选,选用单片机STC89C52作为主控制系统;用数码管作为温度数据显示装置;智能温度传感器采用DS18B20器件作为测温电路主要组成部分。
程序流程图如图7-9所示。
图7主程序流程图
图8读取温度流程图
图9数码管显示流程图
五、程序代码
#include
#defineucharunsignedchar
#defineuintunsignedint
#definedisplay10xfe//数码管1从右至在
#definedisplay20xfd//数码管2从右至在
#definedisplay30xfb//数码管3从右至在
#definedisplay40xf7//数码管4从右至在
#definedisplay50xef//数码管5从右至在
#definedisplay60xdf//数码管6从右至在
//===以下IO定义请根据您硬件的连接修改===
sbitdula=P2^6;
sbitwela=P2^7;
sbitled=P2^5;
sbitTMDAT=P2^2;//根据实实际情况设定
sbitset=P3^4;//设定
sbitup=P3^5;//加
sbitdown=P3^6;//减
sbitld7=P2^4;//输出指示//负温度标志led
sbitpoint=P0^7;//小数点显示
sbitsound=P2^3;
uchartempint,f,bb,tempth,settemp;//温度整数部分和小数部分
inttempdf,c;
codeunsignedcharledmap[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x40};
//7段数码管0~9数字的共阳显示代码和负号位代码(最后一位)
voidset_ds18b20();//初始化DS18B20子程序
voidget_temperature();//获得温度子程序
voidread_ds18b20();//读DS18B20子程序
voidwrite_ds18b20(ucharcommand);//向DS18B20写1字节子程序
voiddelayms(ucharcount);//延时count毫秒子程序
voiddisp_temp();//显示温度子程序
voidkeyscan();
voidhigh_LED();
voidmain()
{set_ds18b20();
write_ds18b20(0xcc);//发跳过ROM匹配命令
write_ds18b20(0xbe);//发出读温度命令
read_ds18b20();//将读出的数据
settemp=tempth;//将TH读到单片机
P1=0xfe;
SP=0x60;//设置堆栈指针
bb=0;
led=0;
while
(1)
{
keyscan();
if(bb==0)
{
get_temperature();//获得温度
high_LED();
}
disp_temp();//显示温度
}
}
//***********************初始化DS18B20子程序**********************************
//****************************************************************************
voidset_ds18b20()
{
while
(1)
{
uchardelay,flag;
flag=0;
TMDAT=1;
delay=1;
while(--delay);
TMDAT=0;//数据线置低电平
delay=250;
while(--delay);//低电平保持500us
TMDAT=1;//数据线置高电平
delay=30;
while(--delay);//高电平保持60us
while(TMDAT==0)//判断DS18B20是否发出低电平信号
{
delay=210;//DS18B20响应,延时420us
while(--delay);
if(TMDAT)//DS18B20发出高电平初始化成功,返回
{
flag=1;//DS18B20初始化成功标志
//初始化成功LED标志
break;
}
}
if(flag)//初始化成功,再延时480us,时序要求
{
delay=240;
while(--delay);
break;
}
}
}
//***********************获得温度子程序***************************************
//****************************************************************************
voidget_temperature()//温度转换、获得温度子程序
{
set_ds18b20();//初始化DS18B20
write_ds18b20(0xcc);//发跳过ROM匹配命令
write_ds18b20(0x44);//发温度转换命令
disp_temp();//显示温度,等待AD转换
set_ds18b20();
write_ds18b20(0xcc);//发跳过ROM匹配命令
write_ds18b20(0xbe);//发出读温度命令
read_ds18b20();//将读出的温度数据保存到tempint和tempdf处
}
//***********************读DS18B20子程序***************************************
//****************************************************************************
voidread_ds18b20()
{
uchardelay,i,j,k,temp,temph,templ;
j=3;//读2位字节数据
do
{
for(i=8;i>0;i--)//一个字节分8位读取
{
temp>>=1;//读取1位右移1位
TMDAT=0;//数据线置低电平
delay=1;
while(--delay);
TMDAT=1;//数据线置高电平
delay=4;
while(--delay);//延时8us
if(TMDAT)//读取1位数据
temp|=0x80;
delay=25;//读取1位数据后延时50us
while(--delay);
}
if(j==3)
templ=temp;//读取的第一字节存templ
if(j==2)
temph=temp;//读取的第二字节存temph
if(j==1)
tempth=temp;//读取的第3字节存tempthTH的值
}while(--j);
f=0;
if((temph&0xf8)!
=0x00)//若温度为负的处理,对二进制补码的处理
{
f=1;//为负温度f置1
temph=~temph;
templ=~templ;
k=templ+1;
templ=k;
if(k>255)
{
temph++;
}
}
tempdf=templ&0x0f;//将读取的数据转换成温度值,整数部分存tempint,小数部分存tempdf
c=(tempdf*625);
tempdf=c;
templ>>=4;
temph<<=4;
tempint=temph|templ;//两字节合并为一个字节
}
//***********************写DS18B20子程序***************************************
//****************************************************************************
voidwrite_ds18b20(ucharcommand)
{
uchardelay,i;
for(i=8;i>0;i--)//将一字节数据一位一位写入
{
TMDAT=0;//数据线置低电平
delay=6;//延时12us
while(--delay);
TMDAT=command&0x01;//将数据放置在数据线上
delay=25;//延时50us
while(--delay);
command=command>>1;//准备发送下一位数据
TMDAT=1;//发送完一位数据,数据线置高电平
}
}
//***********************显示子程序***************************************
//****************************************************************************
voiddisp_temp()
{
uchartempinth,tempintl,cnt,tempinbai,shifen,baifen,gefen,mi;
if(bb!
=0)
{tempint=settemp;
tempdf=0;
cnt=2;}
else
{cnt=100;}
tempinbai=tempint/100;
tempinth=tempint%100/10;//整数取模
tempintl=tempint%10;//整数取模
baifen=tempdf%10000/1000;
shifen=tempdf%1000/100;
gefen=tempdf%100/10;//小数取模
mi=tempdf%10;
while(--cnt)
{
if(tempth>tempint)
ld7=1;
else
ld7=1;
while(f==1)
{
dula=1;
P0=ledmap[10];
dula=0;
if(tempinth==0)
{wela=1;
P0=display1;
wela=0;
delayms
(1);
gotoloop;
}
else
{P0=0xdf;}
}
delayms
(1);
dula=1;
P0=ledmap[tempinbai];
dula=0;
wela=1;
P0=display1;//开百位
wela=0;
delayms
(2);
dula=1;
P0=ledmap[tempinth];
dula=0;
wela=1;
P0=display2;//开十位
wela=0;
delayms
(2);
loop:
dula=1;
P0=ledmap[tempintl];
point=1;//小数点显示
dula=0;
wela=1;
P0=display3;//开个位
wela=0;
delayms
(2);
dula=1;
P0=ledmap[baifen];
dula=0;
wela=1;
P0=display4;//开分位
wela=0;
delayms
(2);
dula=1;
P0=ledmap[shifen];
dula=0;
wela=1;
P0=display5;//开十分位
wela=0;
delayms
(2);
dula=1;
P0=ledmap[gefen];
dula=0;
wela=1;
P0=display6;//开百分位
wela=0;
delayms
(2);
}
}
//***********************延时countms子程序***************************************
//****************************************************************************
voiddelayms(ucharcount)//延时countms子程序
{
uchari,j;
do
{
for(i=5;i>0;i--)
for(j=98;j>0;j--);
}while(--count);
}
//***********************键盘扫描子程序***************************************
//****************************************************************************
voidkeyscan()//键盘扫描
{
if(set==0)
{
delayms
(1);
}
if(set==0)
{
bb++;
while(!
set);//循环在此非0=1
}
if(bb==1)
{
if(up==0)
{
delayms
(1);
}
if(up==0)
{
disp_temp();
if(settemp<125)
{settemp++;}
while(!
up)//非0=1
{
disp_temp();
}
}
if(down==0)
{
delayms
(1);
}
if(down==0)
{
disp_temp();
if(settemp!
=0)//不等于0为真执行
{
settemp--;
while(!
down)//down为(非0=1)循环执行
{
disp_temp();
}
}
}
}
if(bb==2)
{bb=0;
set_ds18b20();//初始化DS18B20
write_ds18b20(0xcc);//发跳过ROM匹配命令
write_ds18b20(0x4e);//发温度转换命令
write_ds18b20(settemp);//写TH3
set_ds18b20();//初始化DS18B20
write_ds18b20(0xcc);//发跳过ROM匹配命令
write_ds18b20(0x48);
}}
//***********************温度过高提示***************************************
//****************************************************************************
voidhigh_LED()
{
if(settemp<=tempint)
{
led=1;
P1=0x00;
sound=0;
led=0;
}
elseif(bb==0)
{
led=1;
P1=0xfe;
sound=1;
led=0;
}
}