2016-2017学年第1学期单片机应用系统设计/工程实践(课号:103G06B/D/E)实验报告项目名称:基于AT89C51单片机温度报警系统学号姓名班级学院信息科学与工程学院完成时间目录一、项目功能及要求 (3)1.1、课程设计的性质和目的 (3)1.3、项目设计要求 (3)二、系统方案设计及原理 (3)2.1、设计主要内容 (3)2.2 、AT89C51单片机简介 (3)2.3 、DS18B20简介 (4)2.4 、数码管显示 (5)2.5、报警电路 (6)三、系统结构及硬件实现 (7)3.1、总电路图 (7)3.2、单片机控制流程图 (8)四、软件设计过程 (8)五、实验结果及分析 (8)5.1 、Proteus仿真 (8)5.2 、C程序调试 (9)六、收获及自我评价 (14)七、参考文献 (15)一、项目功能及要求1.1、课程设计的性质和目的本温度报警器以AT89C51单片机为控制核心,由一数字温度传感器DS18B20测量被控温度,结合7段LED以及驱动LED的74LS245组合而成。
当被测量值超出预设范围则发出警报,且精度高。
利用现代虚拟仿真技术可对设计进行仿真实验,与单片机仿真联系紧密的为proteus仿真,利用keil软件设计单片机控制系统,然后与proteus进行联合调试,可对设计的正确性进行检验。
1.2、课程设计的要求1、遵循硬件设计模块化。
2、要求程序设计结构化。
3、程序简明易懂,多运用输入输出提示,有出错信息及必要的注释。
4、要求程序结构合理,语句使用得当。
5、适当追求编程技巧和程序运行效率。
1.3、项目设计要求1、基于AT89C51单片机温度报警系统;2、设计3个按键分别为:设置按钮、温度加、温度减;3、DS18B20温度传感器采集温度,并在数码管上显示按键的区别;二、系统方案设计及原理2.1、设计主要内容本设计以AT89C51单片机为核心,从而建立一个控制系统,实现通过3个按键控制温度,以达到设置温度上下限的功能,并在数码管上显示三个数字当前的温度上下限设置值和DS18B20温度采集值的显示(精确到小数点后一位),当温度高于上限或者低于下限蜂鸣器报警。
2.2 、AT89C51单片机简介AT89C51是一个低功耗,高性能CMOS8位单片机,片内含4kBytes ISP(In-system programmable)的可反复擦写1000次的Flash只读程序存储器,器件采用A TMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及89C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,功能强大的微型计算机的AT89C51可为许多嵌入式控制应用系统提供高性价比的解决方案.AT89C51具有如下特点:40个引脚,4k Bytes Flash片内程序存储器,128 bytes的随机存取数据存储器,32个外部双向输入/输出(I/O)口,5个中断优先级2层中断嵌套中断,2个16位可编程定时计数器,2个全双工串行通信口,片内时钟振荡器。
此外,AT89C51设计和配置了振荡频率可为0Hz并可通过软件设置省电模式。
空闲模式下,CPU暂停工作,而RAM定时计数器,串行口,外中断系统可继续工作,掉电模式冻结振荡器而保存RAM的数据,停止芯片其它功能直至外中断激活或硬件复位。
同时该芯片还具有PDIP、TQFP和PLCC等三种封装形式,以适应不同产品的需求。
AT89C51单片机的基本结构和外部引脚如下图所示。
图2.12.3 、DS18B20简介(1)DS18B20内部结构DS18B20是Dallas公司继DS1820后推出的一种改进型智能数字温度传感器,与传统的热敏电阻相比,只需一根线就能直接读出被测温度值,并可根据实际需求来编程实现9~12位数字值的读数方式。
DS18B20的外形如一只三极管,引脚名称及作用如下:GND:接地端,DQ:数据输入/输出脚,与TTL电平兼容,VDD:可接电源,也可接地。
因为每只DS18B20都可以设置成两种供电方式,即数据总线供电方式和外部供电方式。
采用数据总线供电方式时VDD接地,可以节省一根传输线,但完成数据测量的时间较长;采用外部供电方式则VDD接+5V,多用一根导线,但测量速度较快,内部结构如图如图3-1.图3.1(2)DS18B20供电方式DS18B20可以采用外部电源供电和寄生电源供电两种模式。
外部电源供电模式是将DS18B20的GND直接接地,DQ与但单总线相连作为信号线,VDD与外部电源正极相连。
如图3.2图3.2(3)DS18B20的测温原理DS1820是这样测温的:用一个高温度系数的振荡器确定一个门周期,内部计数器在这个门周期内对一个低温度系数的振荡器的脉冲进行计数来得到温度值。
计数器被预置到对应于-55℃的一个值。
如果计数器在门周期结束前到达0,则温度寄存器(同样被预置到-55℃)的值增加,表明所测温度大于-55℃。
同时,计数器被复位到一个值,这个值由斜坡式累加器电路确定,斜坡式累加器电路用来补偿感温振荡器的抛物线特性。
然后计数器又开始计数直到0,如果门周期仍未结束,将重复这一过程。
斜坡式累加器用来补偿感温振荡器的非线性,以期在测温时获得比较高的分辨率。
DS18B20内部对此计算的结果可提供0.5℃的分辨率。
温度以16bit带符号位扩展的二进制补码形式读出,DS18B20遵循单总线协议,每次测温时都必须有4个过程]:初始化、传送ROM操作命令、传送ROM操作命令、数据交换。
2.4 、数码管显示数码管内部由七个条形发光二极管和一个小圆点发光二极管组成,根据各管的亮暗组合成字符。
常见数码管有10根管脚。
管脚排列如下图所示。
其中COM为公共端,根据内部发光二极管的接线形式可分为共阴极和共阳极两种。
共阳、阴极内部原理图(如图4.1),其中引脚图的两个COM端连在一起,是公共端,共阴数码管要将其接地,共阳数码管将其接正5伏电源。
一个八段数码管称为一位,多个数码管并列在一起可构成多位数码管,它们的段选线(即a,b,c,d,e,f,g,dp)连在一起,而各自的公共端称为位选线。
显示时,都从段选线送入字符编码,而选中哪个位选线,那个数码管便会被点亮。
本次试验的显示电路如图4.2.图4.1图4.22.5、报警电路通过P2口控制,当温度高于设置的上限或者设置的下限时蜂鸣器响报警。
如图5.1.图5.2三、系统结构及硬件实现3.1、总电路图本电路是由A T89C51和DS18B20为核心,加上串口电路来实现对整个电路的控制和设计,电路图如下。
3.2、单片机控制流程图四、软件设计过程(1)、把程序在Keil uVision4中调试,成功无错误后生成Hex文件。
(2)、根据电路图在proteus软件中回去电路图,检查无错误。
(3)、双击89C51导入生成Hex文件。
(4)、点击proteus软件左下方的开始键,进行仿真,观察高低电平情况。
五、实验结果及分析5.1 、Proteus仿真(1)Proteus软件是英国Labcenter electronics公司出版的EDA工具软件。
它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。
它是目前最好的仿真单片机及外围器件的工具。
Proteus是世界上著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。
在PROTEUS绘制好原理图后,调入已编译好的目标代码文件:*.HEX,可以在PROTEUS的原理图中看到模拟的实物运行状态和过程。
使用Proteus软件进行单片机系统仿真设计,是虚拟仿真技术和计算机多媒体技术相结合的综合运用,有利于培养学生的电路设计能力及仿真软件的操作能力;实践证明,在使用Proteus进行系统仿真开发成功之后再进行实际制作,能极大提高单片机系统设计效率。
因此,Proteus有较高的推广利用价值。
(2)在仿真时按设置按钮,按一次设置温度上限,按第二次设置温度下限,按第三次回到当前温度显示值,其它两个按键是对设置值的加减;或者利用串口在上位机上进行设置,端口选择COM2,波特率选择9600,三个按钮的功能和仿真图里的按键功能一样,对温度进行设置。
如图5.1图5.15.2 、C程序调试在Kill4中对程序进行编写调试源代码如下:# include <reg51.h>#define uint unsigned int#define uchar unsigned char //宏定义sbit but1=P1^0;sbit but2=P1^1;sbit but3=P1^2;sbit p34=P2^4;sbit p35=P2^5;sbit p36=P2^6;sbit dp=P0^7;sbit p37=P2^7;sbit DQ=P2^2; //定义DS18B20总线I/Osbit LING=P2^0; //定义响铃uchar shezhi=0;uint shangxian=300; //上限报警温度,默认值为60uint xiaxian=200; //下限报警温度,默认值为0uchar code LEDData[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};bit s1,s2,s3,s4;/*****延时子程序*****/void Delay(uint i){while( i-- );}void delayms(uint x){uchar i;while(x--);for(i=0;i<120;i++);}void Init_DS18B20(void){unsigned char x=0;DQ=1;Delay(8); //稍做延时DQ=0; //单片机将DQ拉低Delay(80); //精确延时,大于480usDQ=1; //拉高总线Delay(14);x=DQ; //稍做延时后,如果x=0则初始化成功,x=1则初始化失败Delay(20);}/*****读一个字节*****/unsigned char ReadOneChar(void){unsigned char i=0;unsigned char dat=0;for (i=8;i>0;i--){DQ=0; // 给脉冲信号dat>>=1;DQ=1; // 给脉冲信号if(DQ) dat|=0x80;Delay(4);}return(dat); }/*****写一个字节*****/void WriteOneChar(unsigned char dat){ unsigned char i=0;for (i=8; i>0; i--){DQ=0;DQ=dat&0x01;Delay(5);DQ=1; dat>>=1;}}void Tmpchange(void) //发送温度转换命令{Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0x44); //启动温度转}unsigned int ReadTemperature(void){unsigned char a=0;unsigned char b=0;unsigned int t=0;float tt=0;Tmpchange();Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器a=ReadOneChar(); //读低8位b=ReadOneChar(); //读高8位t=b;t<<=8;t=t|a;tt=t*0.0625;t= tt*10+0.5; //放大10倍输出并四舍五入return(t);}Disp_Temperature(uint e) //显示温度{ uint a,b,c,d;a=e/1000; //计算得到十位数b=e/100-a*10; //计算得到个位数字d=e%10; //计算得到小数点后两位c=(e%100)/10; //计算得到小数点后一位p34=0;p35=0;p36=0;p37=0;P0 =LEDData[d]; //显示小数点后两位p34=1;p35=0;p36=0;p37=0;Delay(500);p34=0;p35=0;p36=0;p37=0;P0 =LEDData[c]; //显示小数点后一位dp=0;p34=0;p35=1;p36=0;p37=0;Delay(500);p34=0;p35=0;p36=0;p37=0;P0 =LEDData[b]; //显示个位p34=0;p35=0;p36=1;p37=0;Delay(500);p34=0;p35=0;p36=0;p37=0;P0 =LEDData[a]; //显示十位p34=0;p35=0;p36=0;p37=1;Delay(500);p34=0;p35=0;p36=0;p37=0; //关闭显示}void initUart(void)//串口初始化9600{TMOD|=0x20;SCON=0xfc;TH1=0xfd;TL1=0xfd;EA=1;ES=1;TR1=1;}void uart(void) interrupt 4 //串口中断处理函数{if(RI){RI=0;if(SBUF=='a'){s1=1;}if(SBUF=='b'){s2=1;}if(SBUF=='c'){s3=1;}}}/*****主函数*****/void main(void){uint z,e;IT0=1;IT1=1;EX0=1;EX1=1;EA=1;initUart();while(1){if(but1==0 || s1==1){ //判断按钮setDelay(100);if(but1==0 || s1==1){s1=0;while(but1==0);shezhi++;if(shezhi==3)shezhi=0;}}else if(but2==0 || s2==1){ //判断按钮+ Delay(100);if(but2==0 || s2==1){s2=0;while(but2==0);if(shezhi==1)xiaxian++;else if(shezhi==2)shangxian++;}}else if(but3==0 || s3==1){ //判断按钮-Delay(100);if(but3==0 || s3==1){s3=0;while(but3==0);if(shezhi==1)xiaxian--;else if(shezhi==2)shangxian--;}}if(shezhi==0){e=ReadTemperature(); //获取温度值if(e>shangxian || e<xiaxian){LING=0; //温度不在范围内报警}else LING=1;Disp_Temperature(e); //显示温度}else if(shezhi==1){Disp_Temperature(xiaxian); //显示温度下限}else if(shezhi==2){Disp_Temperature(shangxian); //显示温度上限}}}六、收获及自我评价这次课程设计不光是要掌握模单片机书本上的理论基础,还需要我们锻炼自己的动手能力。