基于51单片机的上下限可调的温度报警系统方案.doc
摘 要:单片机技术已经普与到我们生活,工作,科研,各个领域,已经成为一种比拟成熟的技术,本文将介绍一种基于单片机控制的数字温度器,本温度计属于多功能温度计,可以设置上下报警温度,当温度不在设置围时,可以报警。随着现代工农业技术的开展与人们对生活环境要求的提高,人们也迫切需要检测与控制温度。本文通过采用蜂鸣器作为电声元件的温度报警器的设计,说明了该装置进展设计与制作的具体过程与方法。这种温度报警器结构简单,可操作性强,应用广泛。工作时,温度测量围为1823º。当前环境温度假设超过设定的高温临界温度,由单片机发出报警信号,从而防止带来的不必要的损失。造成高温火灾有:电气线路短路、过载、接触电阻过大等引发高温或火灾;静电产生高温或或火灾;雷电等强电侵入导致高温或火灾;最主要是机房电脑、空调等用电设备长时间工作,导致设备老化,空调发生故障,而不能降温;因此机房所属的电子产品发热快,在短时间机房温度升高超出设备正常温度,导致系统瘫痪或产生火灾,这时温度报警系统就会发挥应有的功能。关键词STC89C51单片机,数字控制,温度计,DS18B201 设计方案选择1.1 系统根本方案选择1.1.1 单片机芯片的选择方案方案一:采用STC89C51芯片作为硬件核心。STC89C51部具有8KB ROM 存储空间,512字节数据存储空间,带有2K字节的EEPROM存储空间,与MCS-51系列单片机完全兼容,STC89C51可以通过串口下载。方案二:采用AT89S51。AT89S51片具有8K字节程序存储空间,256字节的数据存储空间没有EEPROM存储空间,也与MCS-51系列单片机完全兼容,具有在线编程可擦除技术。两种单片机都完全能够满足设计需要,STC89C51相对ATS89C52价格廉价,且抗干扰能力强。考虑到本钱因素,因此选用STC89C51。1.1.2 温度传感器设计方案方案一: 由于本设计是测温电路,可以使用热敏电阻之类的器件利用其感温效应,在将随被测温度变化 的电压或电流采集过来,进展 A/D 转换后,就可以用单片机进展数据的处理,在显示电路上,就可以将被测温度显示出来,这种设计需要用到 A/D 转换电路,感温电路比拟麻烦。方案二:进而考虑到用温度传感器,在单片机电路设计中,大多都是使用传感器,所以这是非常容易想到的,所以可以采用一只温度传感器 DS18B20,此传感器,可以很容易直接读取被测温度值,进展转换,就可以满足设计要求。从以上两种方案,两种都完全能够满足设计需要,很容易看出,采用方案二,电路比拟简单,软件设计也比拟简单,故采用了方案二。 综上各方案所述,对此次作品的方案选定: 采用STC89C51单片机作为主控制系统;采用DS18B20为传感器;1.1.3显示电路设计方案一:使用数码管显示,数码管是由多个发光二极管封在在一起组成“8字型的器件,引线已在部连接完成,只需引出它们的各个笔划,公共电极。有共阴,共阳两种。方案二:使用液晶显示屏lcd1602,1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。它由假设干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用。 比拟两种方案将选用方案二,lcd1602操作简单,可以直接对1602的引脚直接操作。2 主要元件介绍2.1.1 STC89C51引脚介绍 主电源引脚2根VCC(Pin40):电源输入,接5V电源GND(Pin20):接地线外接晶振引脚2根XTAL1(Pin19):片振荡电路的输入端XTAL2(Pin20):片振荡电路的输出端控制引脚4根RST/VPP(Pin9):复位引脚,引脚上出现2个机器周期的高电平将使单片机复位。ALE/PROG(Pin30):地址锁存允许信号PSEN(Pin29):外部存储器读选通信号EA/VPP(Pin31):程序存储器的外部选通,接低电平从外部程序存储器读指令,如果接高电平那么从部程序存储器读指令。可编程输入/输出引脚32根STC89C51单片机有4组8位的可编程I/O口,分别位P0、P1、P2、P3口,每个口有8位8根引脚,共32根。P0口Pin39Pin32:8位双向I/O口线,名称为P0.0P0.7P1口Pin1Pin8:8位准双向I/O口线,名称为P1.0P1.7 P2口Pin21Pin28:8位准双向I/O口线,名称为P2.0P2.7 P3口Pin10Pin17:8位准双向I/O口线,名称为P3.0P3.7图1:STC89C51封装图2.1.2 单片机最小系统:当在STC89C51单片机的RST引脚引入高电平并保持2个机器周期时,单片机部就执行复位操作,按键手动复位有电平方式和脉冲方式两种。其中电平复位是通过RST端经过电阻与电源VCC接通而实现的。最小系统如图2图2 单片机最小系统电路电路以STC89C51单片机最小系统为控制核心,测温电路由DS18B20提供,输入局部采用三个独立式按键s0、s1、s2。具体电路连接,详见附录1。2.2 DS18B20传感器介绍2.2.1 DS18B20概述DS18B20的性能特点如下:1 采用DALLAS公司独特的单线接口方式:DS18B20与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯; 2在使用中不需要任何外围元件;3可用数据线供电,供电电压围:+3.0V+5.5V;4测温围:-55+125。固有测温分辨率为0.5。当在-10+85围,可确保测量误差不超过0.5,在-55+125围,测量误差也不超过2;5通过编程可实现912位的数字读数方式;6用户可自设定非易失性的报警上下限值;7支持多点的组网功能,多个DS18B20可以并联在唯一的三线上,实现多点测温8负压特性,即具有电源反接保护电路。当电源电压的极性反接时,能保护DS18B20不会因发热而烧毁,但此时芯片无常工作;9DS18B20的转换速率比拟高,进展9位的温度值转换只需93.75ms;10适配各种单片机或系统;11含64位激光修正的只读存储ROM,扣除8位产品系列号和8位循环冗余校验码(CRC)之后,产品序号占48位。出厂前产品序号存入其ROM中。在构成大型温控系统时,允许在单线总线上挂接多片DS18B20。2.3 LCD1602介绍引脚功能介绍第1脚:VSS为地电源。 第2脚:VDD接5V正电源。 第3脚:VL为液晶显示器比照度调整端,接正电源时比照度最弱,接地时比照度最高,比照度过高时会产生“鬼影,使用时可以通过一个10K的电位器调整比照度。 第4脚:RS为存放器选择,高电平时选择数据存放器、低电平时选择指令存放器。 第5脚:R/W为读写信号线,高电平时进展读操作,低电平时进展写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。 第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。 第714脚:D0D7为8位双向数据线。 第15脚:背光源正极。 第16脚:背光源负极。指令介绍1602液晶模块的读写操作,屏幕和光标的操作都是通过指令编程来实现的。说明1为高电平,0为低电平 指令1:清显示,指令码01H,光标复位到地址00H位置 指令2:光标复位,光标返回到地址00H 指令3:光标和显示位置设置I/D,光标移动方向,高电平右移,低电平左移,S:屏幕上所有文字是否左移或右移,高电平表示有效,低电平表示无效。 指令4:显示开关控制。D:控制整体的显示开与关,高电平表示开显示,低电平表示关显示。C:控制光标的开与关,高电平表示有光标,低电平表示无光标 B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。 指令5:光标或显示移位 S/C :高电平时显示移动的文字,低电平时移动光标 指令6:功能设置命令 DL:高电平时为4位总线,低电平时为8位总线 N:低电平时为单行显示,高电平时为双行显示,F:低电平时显示5X7的点阵字符,高电平时显示5X10的显示字符。 指令7:字符发生器RAM地址设置。 指令8:DDRAM地址设置。 指令9:读忙信号和光标地址 BF:忙标志位,高电平表示忙,此时模块不能接收命令或数据,如果为低电平表示不忙。使用lcd先根据液晶的使用手册写出液晶屏的驱动程序,后使用把信息显示到液晶上时直接调用液晶子程序即可。3.程序流程图图6:程序流程图4.设计总结本次设计功能根本实现,当温度低于下限温度或者高于上限温度时蜂鸣器发出报警。设计电路有温度上下限可调功能,按键按下由于不能再1602显示光标只能使用led的亮灭和蜂鸣器来确定按键是否按下,并且最终能实现了该功能。获取的温度值通过1602显示出来。软件调适通过使用protues进展仿真,开始只是让1602显示出数据,慢慢的参加按键,led指示灯和蜂鸣器。过程中遇到了很多问题,硬件方面:原理图设计好51单片机最小系统再根据仿真软件电路接入温度采集电路,报警电路,显示电路,指示电路,按键和电源接口。画好原理图导出PCB布线,由于对PCB布线规那么不是很了解,粗略步好线打印印板、腐蚀、打孔、焊接,由于经过电子相关的实习,这些步骤还是完成得比拟好。焊接好后第一步就是坚持电路是否短路或者是否有虚焊,屡次对照PCB后没有问题就将下载好程序的单片机插入电路开始调试。设计电路时预留了两个IO口即增加了两个扩展口,所以可以通过之前自己设计的STC串口下载器对单片机程序的下载调试。实际软件件调试也是和仿真一样,先让1602能够显示东西,再把整个程序下载到单片机中,由于仿真时电路要设计的功能根本都能实现了,所以程序下载成功后电路根本实现了功能。只是蜂鸣器在温度没有超出限制围还是有小小的声音产生,找蜂鸣器相关资料发现是因为蜂鸣器在不使用时要给它一个低电平或高电平看电路,这里电路是给低电平,因为不限制蜂鸣器的初始值时电路会出现漏电现象,程序改动后漏电现象消除了。通过本次设计,我学到了很多我们在课堂上学不到的实践能力,动手能力也得到了很大的提升,在书本所学到的知识得到了很大的实践,让我对书本上的知识有了更加深刻的理解。同时也感同学的帮助,在我对电路相关知识不理解时给了我指点,让我能清楚得理解,也通过这次的设计让我电子电路设计有了很大兴趣。参考文献1 郭天祥.51单片机C语言教程.:电子工业出版,2009.2 谭浩强.C语言程序设计M.:清华大学,1991.3 阎石.数字电子技术根底M.:高等教育,2006.4 童诗白.模拟电子技术根底M.:高等教育,2006.5 欣电子设计从零开始M.:清华大学,2005.附录1 系统原理图PCB图16 / 16附录2 C语言程序#include<reg51.h>#include"1602.h"#include"DS18B20.h"#define uchar unsigned char#define uint unsigned intsbit BEEP=P14;sbit led=P10;sbit led0=P11;sbit led1=P12;sbit s0=P30;sbit s1=P31;sbit s2=P32;uchar code tab_0="Temp: "uchar code tab_1="TH:23 TL:18 "uchar TH,TL; / 定义上下温度变量uchar num; /全局变量/*ms延时非准确*/void delay(uint z) uint i,j;for(i=z;i>0;i-)for(j=120;j>0;j-); /*TH、TL的温度符号*/void fuhao()write_(0x80+5);write_dat(0xdf);write_dat(0x43);write_(0x80+14);write_dat(0xdf);write_dat(0x43);/*初始化*/void init()/*上电显示初始化*/uchar i;TH=23;TL=18;write_(0x80);for(i=0;i<16;i+)write_dat(tab_1i);delay(5);write_(0x80+0x40);for(i=0;i<5;i+)write_dat(tab_0i);delay(5);fuhao();/*定时器初始化*/ TMOD=0x01; /开定时器T0,方式1 TH0=(65536-50000)/256; /装入初值 TL0=(65536-50000)%256; / EA=1; /开全局中断 ET0=1; TR0=1; /打开定时器 /*报警函数*/void bi(uint t)int i,j;for(i=0;i<t;i+)for(j=0;j<50;j+);BEEP=BEEP; /按位取反BEEP/*TH、TL取十位个位送人显示*/void writeT_HL(uchar add,uchar dat)uchar shi,ge;shi=dat/10;/十位ge=dat%10; /个位write_(0x80+add);write_dat(shi+0x30);write_dat(ge+0x30);/*按键函数*/void keyscan()/*功能选择*/ if(s0=0) num+; delay(2); if(s0=0) led=0;while(!s0);bi(300);led=1;/按一下灯亮一下声音响一声if(num=1) TR0=0;write_(0x80+12);delay(10); /write_(0x0f);if(num=2) write_(0x80+4); if(num=3) num=0;TR0=1; /*功能加*/ if(num!=0) if(s1=0) delay(2);if(s1=0) led0=0;while(!s1);bi(300);led0=1; /按一下灯亮一下声音响一声if(num=1) TH+;if(TH=100) TH=0;writeT_HL(3,TH);write_(0x80+4);if(num=2) TL+;if(TL=100) TL=0;writeT_HL(12,TL);write_(0x80+10); /*功能减*/ if(num!=0) if(s2=0) delay(2);if(s2=0) led1=0;while(!s2); bi(300);led1=1; /按一下灯亮一下声音响一声if(num=1) TH-;if(TH=-1) TH=99;writeT_HL(3,TH);write_(0x80+4);if(num=2) TL-;if(TL=-1) TL=99;writeT_HL(12,TL);write_(0x80+10); /*温度报警函数*/void beep()uchar tem;tem=temp/10; /返回的温度值temp放大了十倍,得除十复原if(TH<=tem) bi(500);if(TL>=tem) bi(500);/*主函数*/ void main(void)Init_1602();init();while(1) BEEP=0;keyscan();ds1820disp();beep();/*定时器中断函数*/void time() interrupt 1TH0=(65536-50000)/256; /重装初值TL0=(65536-50000)%256;DS1802驱动程序#ifndef _DS18B20_H_#define _DS18B20_H_#define uchar unsigned char#define uint unsigned intsbit DQ = P13;uchar tab5;uint temp;/温度值bit tflag;/*延时1微秒*/void delay_18B20(uint i) while(i-);/*ds1820复位*/void ds1820rst() uchar x=0;DQ=1; /DQ复位delay_18B20(8); /延时DQ=0; /DQ拉低delay_18B20(80); /准确延时大于480usDQ=1; /拉高delay_18B20(14);x=DQ; /稍做延时后 如果x=0那么初始化成功 x=1那么初始化失败while(!DQ);delay_18B20(20);/*读一个字节*/ uchar ds1820rd() uchar i=0;uchar dat=0;for (i=8;i>0;i-) DQ=0; /给脉冲信号dat>>=1;DQ=1; /给脉冲信号if(DQ)dat|=0x80;delay_18B20(4);return(dat);/*写一个字节*/void ds1820wr(uchar dat)uchar i=0;for (i=8;i>0;i-) DQ=0;DQ=dat&0x01;delay_18B20(5);DQ=1;dat>>=1;/*读取温度值并转换*/ read_temp()uchar a,b; ds1820rst(); ds1820wr(0xcc);/跳过读序列号 ds1820wr(0x44);/启动温度转换delay_18B20(100); ds1820rst(); ds1820wr(0xcc);/跳过读序列号 ds1820wr(0xbe);/读取温度 delay_18B20(100); a=ds1820rd(); b=ds1820rd(); temp=b; temp<<=8; temp=temp|a;if(temp<0x0fff) tflag=0; else temp=temp+1;tflag=1; temp=temp*(0.625);/温度值扩大10倍,准确到1位小数 return(temp);/*温度值显示*/void ds1820disp() uchar flagdat;read_temp();tab0=temp%1000/100+0x30; /十位数tab1=temp%100/10+0x30; /个位数tab2=temp%10+0x30; /小数位if(tflag=0) flagdat=0x20;/正温度不显示符号 else flagdat=0x2d;/负温度显示负号:- if(tab0=0x30) tab0=0x20; /如果十位为0,不显示write_(0x80+0x40+6);write_dat(flagdat); /显示正负write_dat(tab0); /显示十位 write_dat(tab1); /显示个位write_dat(0x2e); /显示小数点 write_dat(tab2); /显示小数位write_dat(0xdf);write_dat(0x43);#endifLCD1602驱动程序#ifndef _1602_H_#define _1602_H_#define uint unsigned int#define uchar unsigned char#define LCD P0sbit RS=P24;sbit RW=P25;sbit EN=P26;void delayms(uint z);void Init_1602(void);void check_busy(void);void write_(uchar );void write_dat(uchar dat);/*延时z毫秒*/ void delayms(uint z)int i,j;for(i=z;i>0;i-)for(j=120;j>0;j-); /*1cd1602初始化*/void Init_1602(void)delayms(15);write_(0x38);delayms(5);write_(0x0c);delayms(5);write_(0x06);delayms(5);write_(0x01);delayms(5);write_(0x80);delayms(5);/*将数据二进制高地位对换为了连线方便但片机P0口与lcd1602数据口反接)*/uchar HL_exchange(uchar dat) uchar i,temp; temp = 0x00; for(i=0;i<8;i+) temp >>= 1; if(dat<<i)&0x80) temp |= 0x80; else temp &= 0x7F; return temp; /*读忙*/void check_busy(void)uchar x;x=HL_exchange(0x80);while(x&HL_exchange(0x80)RS=0;RW=1;EN=1;x=LCD;EN=0;delayms(10); /*写指令*/void write_(uchar )check_busy();RS=0;RW=0;EN=1;LCD=0XFF;LCD=HL_exchange();EN=0;delayms(10);/*写数据*/void write_dat(uchar dat)check_busy();RS=1;RW=0;EN=1;LCD=0XFF;LCD=HL_exchange(dat);EN=0;delayms(10);#endif