搜索
您的当前位置:首页正文

基于AT89C51单片机温度报警系统设计与制作

2020-12-28 来源:步旅网
一、摘要

我们介绍的是一种基于单片机控制的数字温度报警,本温度系统具有多功能性,即可以当数字温度计使用,显示当前环境温度,又可以作为报警器使用,设置报警温度,当温度不在设置范围内时,可以报警,并采取措施使温度下降。

该温度报警系统控制器使用单片机AT89C51,测温传感器使DS18B20,用2位共阳极LED数码管,实现温度显示,能准确达到以上要求。

二、设计方案

1、方案一

由于本设计是测温电路,可以使用热敏电阻之类的器件利用其感温效应,在将随被测温度变化的电压或电流采集过来,进行A/D转换后,就可以用单片机进行数据的处理,在显示电路上,就可以将被测温度显示出来,这种设计需要用到A/D转换电路,感温电路比较麻烦。

2、 方案二

进而考虑到用温度传感器,在单片机电路设计中,大多都是使用传感器,所以这是非常容易想到的,所以可以采用一只温度传感器DS18B20,此传感器,可以很容易直接读取被测温度值,进行转换,就可以满足设计要求。

从以上两种方案,很容易看出,采用方案二,电路比较简单,软件设计也比较简单,故采用了方案二。

温度报警系统电路设计总体设计方框图如图1所示

单片机复位

LED显示

主 温 度 传 感控

报警点按键调蜂鸣器报警 制小风扇转动

器图1 总体设计方框图 时钟振荡

三、模块功能分析 1、单片机主板电路

单片机AT89C51具有低电压供电和体积小等特点,该模块包括中央处理CPU -AT89C51、时钟电路及复位电路;

图2复位电路 图3 时钟电路 2、DS18B20温度传感器与单片机的接口电路

DS18B20温度传感器是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。

DS18B20是采用电源供电方式,此时DS18B20的1脚接地,2脚作为信号线,3脚接电源。 该电路完成了信号的采集、转换和传输。

图4

3、上下限报警调整电路

分别调整温度的上下限报警设置,有“+“、”“-”、“确定”等键

图5上下限报警调整电路

4、温度显示电路

显示当前测得的温度,数码管采用74LS247驱动

图6温度显示电路

5、报警电路

当环境温度超过设定温度时,蜂鸣器鸣叫,红灯点亮,发生报警;当人员发现警报时,可按图8中的按钮,暂时中断蜂鸣器的鸣叫。

图7 蜂鸣器、亮灯报警电路 图8 中断电路

6、控制电路

该电路的作用是:当测量温度超过设定温度时,小风扇以下转动,加快仪器散热,使温度

保持在设定温度以下。

图9控制电路

四、整体构造及功能

整体电路图如下:

图10整体电路图

实现的总体功能:

 实现对环境温度的测量和显示  能通过按键设置报警温度

 温度超过设置值时,产生光声报警

 报警同时系统自带小风扇转动以降低温度 主程序

主程序的主要功能是负责温度的实时显示、读出并处理DS18B20的测量的当前温度值,温度测量每1s进行一次。这样可以在一秒之内测量一次被测温度,其程序流程见下图所示

开始 初始化 DS 18 B 20 初始化 N 存在吗 DS 18 B 20

Y

对 DS 18 B 20 写指令

读 DS 18 B 20

转换温度

报警

Y 达到上限? 小风扇转动

N

显示温度

附录:

源程序

/*******************************************************************/ /*温度报警器*/

/*******************************************************************/

#include #include

#define uchar unsigned char

#define Tube P0 //数码管端口 #define Key P1 //键盘端口

sbit DQ = P1^4; //温度传感器DS18B20数据传输端 sbit BUZZER = P1^5; //蜂鸣器端口

sbit RUN = P1^6; //运行指示灯端口 sbit SET = P1^7; //设置指示灯端口 sbit Feng = P3^3; //风扇端口

bit Status; //设置状态标志位 bit Warning; //警报标志位 bit Int; //外部中断标志位

uchar OP1L; //原P1端低4位状态 uchar NP1L; //现P1端低4位状态

uchar FinT; //最终测得温度 uchar LimT; //警报温度下限

uchar Count; //定时器计数

/*******************************************************************/

#include\"Delay.h\" #include\"Display.h\" #include\"Initialize.h\" #include\"Error.h\" #include\"KeyScan.h\" #include\"Measure.h\" #include\"Interrupt.h\"

/*******************************************************************/ /*主程序*/

/*******************************************************************/

void main() {

Initialize(); //初始化

do{ //开机自检,跳过默认初始的85℃ Measure();

}while( FinT == 0X55 );

while(1){

KeyScan(); //键盘扫描

Measure(); //获取测量温度

Display(); //显示

} }

/*******************************************************************/ /*初始化*/

/*******************************************************************/

void Initialize() {

Status = 0; //初始化设置状态标志位 Warning = 0; //初始化警报标志位

BUZZER = 1; //初始化蜂鸣器状态 RUN = 0; //初始化运行指示灯 SET = 1; //初始化设置指示灯

Feng = 1; //初始化风扇端口

OP1L = 0X00; //初始化原P1低4位 NP1L = 0X00; //初始化新P1低4位

LimT = 0X1B; //初始化警报温度下限为27℃

}

/*******************************************************************/ /*温度测量*/

/*******************************************************************/

void InitDS18B20(); //初始化DS18B20 void WriteDS18B20( uchar ch ); //写DS18B20数据

uchar ReadDS18B20(); //读DS18B20数据

void Measure() {

uchar TemH; //保存传感器发送数据高8位

uchar TemL; //保存传感器发送数据低8位 InitDS18B20();

WriteDS18B20( 0XCC ); //跳过ROM _nop_(); InitDS18B20();

WriteDS18B20( 0XCC ); //跳过ROM _nop_();

WriteDS18B20( 0X44 ); //发送温度转换指令 Delay1ms( 25 ); Delay1ms( 25 ); Delay1ms( 25 );

Delay1ms( 25 ); //等待1s转换

InitDS18B20();

WriteDS18B20( 0XCC ); //跳过ROM

WriteDS18B20( 0XBE ); //发送温度转换指令 TemL = ReadDS18B20(); //读低位温度值

TemH = ReadDS18B20(); //读高位温度值 Delay1ms( 2 );

TemH = ( TemH<<4 )|( TemL>>4 ); //保留温度值整数部分

FinT = TemH;

Count = 0X00; EA = 1; EX0 = 1; IT0 = 1; //初始化定时器计数单元 //开总中断

//开外部中断0中断允许

//设置外部中断0为边沿触发方式

if( FinT > LimT ){ Warning = 1; } else{

Warning = 0; } }

uchar ReadDS18B20() {

uchar ch; uchar q ;

for( q=0; q<8; q++ ){ ch = ch >> 1; DQ = 0; _nop_(); DQ = 1; _nop_(); _nop_(); _nop_(); _nop_();

if( DQ == 1 ){

ch = ch | 0X80; } else{

ch = ch & 0X7f; }

Delay15us( 3 ); DQ = 1; }

return( ch ); }

void WriteDS18B20( uchar ch ) {

uchar i;

for( i=0; i<8; i++ ) {

DQ=0;

Delay15us( 1 ); DQ = ch & 0X01;

//判断是否警报

//读DS18B20数据

//写DS18B20数据

Delay15us( 3 ); DQ = 1;

ch = ch >> 1; _nop_(); } }

void InitDS18B20() //初始化DS18B20 {

DQ = 0;

Delay15us( 33 ); //至少延时480us DQ = 1;

Delay15us( 10 ); //至少延时100us }

/*******************************************************************/ /*显示*/

/*******************************************************************/

void Display() {

uchar T;

if( Status == 1 ){ //判断状态 T = LimT; } else{

T = FinT; }

T = T % 10 + T / 10 * 16; //将2进制码转化为BCD码 Tube = T; //数码管显示

RUN = Warning; //运行指示灯显示 BUZZER = !Warning || Int; //蜂鸣器

Feng = !Warning; //风扇

SET = !Status; //设置指示灯显示

Delay1ms( 20 ); }

/*******************************************************************/

/*键盘扫描*/

/*******************************************************************/

void KeyScan() {

NP1L = Key; NP1L = NP1L & 0X0F; NP1L = NP1L ^ 0X0F;

if( NP1L != OP1L ){

switch(NP1L){ case 0X01: Status = 1; break;

case 0X02: if( Status == 1){ LimT++; LimT = LimT % 100; Delay1ms(255); } else{

Error(); }

break;

case 0X04: if( Status == 1){ LimT--; if( LimT < 0 ){ LimT = 0X63; }

Delay1ms(255); } else{

Error(); }

break;

case 0X08: Status = 0; break;

default: //读取按键状态 //判断按键

//按键为“设置” //进入设置状态 //按键为“+1”

//判断是否为设置状态 //警报温度下限+1 //超过99清零 //按键为“-1”

//判断是否为设置状态 //警报温度下限-1

//低于0变为99 //按键为“确认” //返回测温状态 //多键按下

Error(); //出错复位 break; }

NP1L = 0X00; //重新初始化 } }

/*******************************************************************/ /*中断服务*/

/*******************************************************************/

void Int0( void ) interrupt 0 {

Int = 1; //外部中断标志位置1 EX0 = 0; //关外部中断0中断允许

TMOD = 0X01; //设置定时器0工作在模式1 TH0 = 0X3C;

TL0 = 0XB0; //为T0赋初值,令其定时50ms Count = 0X3C; //设置计数次数 ET0 = 1; //开T0中断允许 TR0 = 1; //开T0中断 }

/*******************************************************************/

void Timer0( void ) interrupt 1 {

if( Count == 0 ){ //判断定时计数是否结束 ET0 = 0; //关T0中断允许 TR0 = 0; //关T0中断

Int = 0; //外部中断标志位置0 EX0 = 1; //开外部中断0中断允许 } else{

TL0 = 0XB0; //重新赋T0初值 TH0 = 0X3C;

Count --; //定时计数减1 } }

/*******************************************************************/

/*延迟函数*/

/*******************************************************************/

void Delay15us( uchar n ) //延迟n*15us {

do{

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();

n--;

}while( n ); }

void Delay1ms( uchar delay ) //延迟delay*1ms {

uchar i;

while( delay-- ) {

for( i=0; i<124; i++); } }

/*******************************************************************/ /*报错复位*/

/*******************************************************************/

void Error() {

Tube = 0XAA; //出错显示 BUZZER = 0; //鸣蜂鸣器 RUN = 1; //LED警报

Delay1ms( 255 ); //延迟 Delay1ms( 255 ); Delay1ms( 255 ); Delay1ms( 255 ); Delay1ms( 255 );

( *(void(*)())0 )(); //软复位 }

因篇幅问题不能全部显示,请点此查看更多更全内容

Top