我们介绍的是一种基于单片机控制的数字温度报警,本温度系统具有多功能性,即可以当数字温度计使用,显示当前环境温度,又可以作为报警器使用,设置报警温度,当温度不在设置范围内时,可以报警,并采取措施使温度下降。
该温度报警系统控制器使用单片机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 #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 )(); //软复位 } 因篇幅问题不能全部显示,请点此查看更多更全内容