课程设计报告项目名称:基于51单片机的恒温控制系统项目主持人:_________孔亮 ___________班级:_______09电子信息工程_________学号:_________0928401116___________摘要本恒温控制系统设计采用现在流行的51系列单片机,配以DS18B20数字温度传感器,能够较精确的控制温度,并显示设定温度与当前温度。
单片机将检测到的温度信号与设定的温度进行比较,根据两者差值输出相应占空比的PWM波,近而实现对温度的线性控制。
本系统的加热功率为0~10W,供电电源为直流10V,调温范围理论上可达+0℃~100℃,温度调节精度为±0.5℃。
关键词:51单片机;恒温控制;DS18B20;线性控制。
AbstractThis temperature control system design using popular MCS-51 microcontroller, with digital temperature sensor DS18B20, can control temperature quite accurately and display the temperature has been set and the temperature at the present. The microcontroller will compare the tempature detected with the set one, output the PWM wave whose Duty Ratio will change according to the difference of the two tempratures, and to achieve the linear control of the temprature.The heating power is 0 ~ 10W, power supply is 10V (DC), Temperature range +0 ℃~ +100 ℃theoretically , temperature control accuracy of ± 0.5 ℃.Keywords:MCS-51 microcontroller ; temperature control system ; DS18B20 ; linear control .目录摘要 (2)1 引言 (4)1.1 恒温控制系统设计的背景、发展历史及意义 (4)1.2 温度控制系统的目的 (4)1.3 温度控制系统完成的功能 (4)2 总体设计方案 (5)2.1 单片机主控制电路 (5)2.2 人机交互模块 (5)2.3 温度测量与控制模块 (6)3 硬件电路详细设计 (7)3.1 单片机最小系统 (7)3.2 人机交互模块 (7)3.3 测温模块 (9)3.4 温度控制模块 (9)3.5 总电路图 (10)3.6 硬件实物图 (10)4 系统软件设计 (11)4.1 原理框图 (11)4.2 详细程序 (13)5 系统性能测试与分析 (21)5.1 数据记录 (21)5.2 数据分析与结论 (21)6 结束语 (22)1 引言1.1 恒温控制系统设计的背景、发展历史及意义随着社会的发展,科技的进步,以及测温仪器在各个领域的应用,智能化已是现代温度控制系统发展的主流方向。
特别是近年来,温度控制系统已应用到人们生活的各个方面,但温度控制一直是一个未开发的领域,却又是与人们息息相关的一个实际问题。
针对这种实际情况,设计一个温度控制系统,具有广泛的应用前景与实际意义。
温度是科学技术中最基本的物理量之一,物理、化学、生物等学科都离不开温度。
在工业生产和实验研究中,像电力、化工、石油、冶金、航空航天、机械制造、粮食存储、酒类生产等领域内,温度常常是表征对象和过程状态的最重要的参数之一。
比如,发电厂锅炉的温度必须控制在一定的范围之内;许多化学反应的工艺过程必须在适当的温度下才能正常进行;炼油过程中,原油必须在不同的温度和压力条件下进行分馏才能得到汽油、柴油、煤油等产品。
没有合适的温度环境,许多电子设备就不能正常工作,粮仓的储粮就会变质霉烂,酒类的品质就没有保障。
因此,各行各业对温度控制的要求都越来越高。
可见,温度的测量和控制是非常重要的。
单片机在电子产品中的应用已经越来越广泛,在很多的电子产品中也用到了温度检测和温度控制。
随着温度控制器应用范围的日益广泛和多样,各种适用于不同场合的智能温度控制器应运而生。
1.2 温度控制系统的目的本设计的内容是恒温控制系统,控制对象是温度。
温度控制在日常生活及工业领域应用相当广泛,比如温室、水池、发酵缸、电源等场所的温度控制。
而以往温度控制是由人工完成的而且不够重视,其实在很多场所温度都需要监控以防止发生意外。
针对此问题,本系统设计的目的是实现一种可连续高精度调温的温度控制系统,它应用广泛,功能强大,是一款既实用又廉价的控制系统。
1.3 温度控制系统完成的功能本设计是对温度进行实时监测与控制,设计的恒温控制系统实现了基本的温度控制功能:当温度低于设定温度1℃时,系统输出占孔比为1的波形,使加热电阻全功率加热,使温度快速上升,同时红灯亮;当温度上升到与设定温度差值小于1℃时,系统开始输出相应占空比的PWM波,随着温度的上升而不断减小加热电阻功率;当温度上升到设定温度时,系统输出占孔比为0的波形,停止加热,同时绿灯亮。
数码管即时显示温度,精确到小数点一位。
同时可以通过4个按键进行对设定温度的调节。
2 总体设计方案系统总体框图如图1所示。
图1 系统总框图2.1单片机主控制电路主控制电路准备用STC 89C52的单片机作为控制主机。
之所以选择89C52作为主机,是因为89C52作为51系列单片机的一种,其使用性能稳定,价格便宜,完全能够满足此次设计的需求。
而且89C52内部集成了程序存储器,可以装载用户程序,方便后续的课程设计需要。
图2 单片机最小应用系统框图2.2人机交互模块人机交互模块主要包括键盘、数码管、LED指示灯等功能模块,其中键盘用于供用户输入温度期望值,数码管用于显示用户设定温度及容器中水温,LED 指示灯用于指示系统工作状态(加热中、保温中)。
图3 人机交互模块系统框图2.3温度测量与控制模块温度测量模块准备采用美国DALLAS半导体公司的DS18B20温度传感器。
该传感器与传统的热敏电阻等测温元件相比,它能直接读出被测温。
这一部分主要完成对温度信号的采集和转换工作,由DS18B20数字温度传感器及其与单片机的接口部分组成。
数字温度传感器DS18B20把采集到的温度通过数据引脚传到单片机的IO口,单片机接受温度并存储。
此部分只用到DS18B20和单片机,硬件很简单温度控制模块准备采用FAIRYCHILD的8N60C开关管、10W10Ω的水泥电阻。
由单片机根据设定温度与测量温度之差输出相应占空比的PWM波,控制8N60C开关管的通断,近而控制水泥电阻的加热功率。
图3 温度测量与控制模块系统框图3 硬件电路详细设计3.1 单片机最小系统:包括复位电路、时钟电路、电源电路、烧录口共四个单元,其中电源电路与烧录口省略。
电路图如下:其中,31端口接高电平,表明单片机复位后访问内部程序存储器;由于P0口作为输出口时处于漏极开路状态,所以必须外接上拉电阻,如果后期实验中不使用其作为输出口,则此处可省略。
3.2 人机交互模块:(1)、数码管:其中,采用8段共阴数码管,P0口输出段码、位码,P2.2和P2.3分别为段锁存和位锁存。
数码管前四位显示用户测量温度,后四位显示测量温度。
(2)、LED指示灯:其中,指示灯绿色用于指示保温中、红色用于指示加热中,当两个LED均亮起时,表示正处于设置温度状态。
(3)、按键:其中,四个按键分别表示温度设置、上升1摄氏度、下降1摄氏度、确定。
温度设置键用于触发外部中断,以进行温度的调节。
3.3 测温模块:测温模块采用美国DALLAS 半导体公司的DS18B20温度传感器。
其输出与P1.0相连。
3.4 温度控制模块:8N60C 的栅极(G)与P1.1相连,源级(S)接地(注意与单片机控制端共地,否则将导致无法关断),漏极(D)接水泥电阻,水泥电阻另一端接10V 直流电。
水泥电阻是将电阻线绕在无碱性耐热瓷件上,外面加上耐热、耐湿及耐腐蚀之材料保护固定并把绕线电阻体放入方形瓷器框内,用特殊不燃性耐热水泥充填密封而成。
水泥电阻的外侧主要是陶瓷材质。
8N60C 是仙童公司出品的一款N 沟道的MOSFET ,最小开启电压为4V ,最大关断电压为2V ,故可以直接接在单片机IO 口,由高低电平控制通断。
DS18B20引脚图水泥电阻实物图3.5 总电路图:3.6 硬件实物图:4 系统软件设计 4.1 原理框图:(1)、主程序:(2)、定时中断0程序:4.2 详细程序:(1)、main.c#include<reg52.h>#include "18b20.h"#include "delay.h"#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换sbit PWM=P1^1;sbit LED_G=P1^2;sbit LED_R=P1^3;sbit LATCH1=P2^2;//定义锁存使能端口 段锁存sbit LATCH2=P2^3;// 位锁存sbit UP=P3^3;sbit DOWN=P3^4;sbit OK=P3^5;bit ReadTempFlag;//定义读时间标志unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9unsigned char code WeiMa[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]={0x3f,0xbf,0x3f,0x39,0x6d,0xbf,0x3f,0x39}; //存储显示值的全局变量unsigned int temp;volatile int usertemp=50;void Display(unsigned char Num);//数码管显示函数void Init_Timer0(void);//定时器初始化void Init_Int0(void);//外部中断初始化/*------------------------------------------------主函数------------------------------------------------*/void main (void){unsigned int TempH,TempL,temp,CYCLE=100,DELTA;Init_Timer0();Init_Int0();while (1) //主循环{if(ReadTempFlag==1){ReadTempFlag=0;temp=ReadTemperature();TempH=temp>>4;TempL=temp&0x0F;TempL=TempL*6/10;//小数近似处理if(TempH/10==0)TempData[0]=0;//消隐elseTempData[0]=DuanMa[TempH/10]; //十位温度TempData[1]=DuanMa[TempH%10]|0x80; //个位温度,带小数点 TempData[2]=DuanMa[TempL];TempData[3]=0x39;//显示C符号}if(TempH<usertemp-1){LED_R=0;LED_G=1;PWM=1;}else{if(TempH>=usertemp){LED_R=1;LED_G=0;PWM=0;}else{LED_R=0;LED_G=1;DELTA=(usertemp-TempH-TempL*10)*100;PWM=1;DelayMs(DELTA);PWM=0;DelayMs(CYCLE-DELTA);}}}/*------------------------------------------------ 显示函数,用于动态扫描数码管------------------------------------------------*/ void Display(unsigned char Num){static unsigned char i=0;DataPort=0; //数码管清零,防止重影LATCH1=1; //段锁存LATCH1=0;DataPort=WeiMa[i]; //取位码LATCH2=1; //位锁存LATCH2=0;DataPort=TempData[i]; //取显示数据,段码LATCH1=1; //段锁存LATCH1=0;i++;if(i==Num)i=0;}/*------------------------------------------------ 定时器初始化子程序------------------------------------------------*/ void Init_Timer0(void){TMOD |= 0x01; //使用模式1,16位定时器//TH0=0x00; //给定初值//TL0=0x00;EA=1; //总中断打开ET0=1; //定时器中断打开TR0=1; //定时器开关打开}/*------------------------------------------------ 定时器中断子程序------------------------------------------------*/ void Timer0_isr(void) interrupt 1{static unsigned int num;TH0=(65536-2000)/256;TL0=(65536-2000)%256;Display(8); // 调用数码管扫描num++;if(num==300) //{num=0;ReadTempFlag=1; //读标志位置1}}/*------------------------------------------------外部中断初始化子程序------------------------------------------------*/void Init_Int0(void){EA=1; //全局中断开EX0=1; //外部中断1开IT0=1; //IT1=1表示边沿触发}/*------------------------------------------------外部中断中断子程序------------------------------------------------*/void ISR_INT0(void) interrupt 0{while(OK){LED_R=0;LED_G=0;if(!UP) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!UP) //再次确认按键是否按下,没有按下则退出{while(!UP);//如果确认按下按键等待按键释放,没有释放则一直等待 {usertemp++;TempData[4]=DuanMa[usertemp/10];TempData[5]=DuanMa[usertemp%10]|0x80;}}}if(!DOWN) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!DOWN) //再次确认按键是否按下,没有按下则退出{while(!DOWN);//如果确认按下按键等待按键释放,没有释放则一直等待 {usertemp--;TempData[4]=DuanMa[usertemp/10];TempData[5]=DuanMa[usertemp%10]|0x80;}}}Display(8);}return;}(2)、18b20.c#include"delay.h"#include"18b20.h"/*------------------------------------------------18b20初始化------------------------------------------------*/bit Init_DS18B20(void){bit dat=0;DQ = 1; //DQ复位DelayUs2x(5); //稍做延时DQ = 0; //单片机将DQ拉低DelayUs2x(200); //精确延时 大于 480us 小于960usDelayUs2x(200);DQ = 1; //拉高总线DelayUs2x(50); //15~60us 后 接收60-240us的存在脉冲dat=DQ; //如果x=0则初始化成功, x=1则初始化失败DelayUs2x(25); //稍作延时返回return dat;}/*------------------------------------------------读取一个字节------------------------------------------------*/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;DelayUs2x(25);}return(dat);}/*------------------------------------------------写入一个字节------------------------------------------------*/void WriteOneChar(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;DelayUs2x(25);DQ = 1;dat>>=1;}DelayUs2x(25);}/*------------------------------------------------读取温度------------------------------------------------*/unsigned int ReadTemperature(void){unsigned char a=0;unsigned int b=0;unsigned int t=0;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换DelayMs(10);Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度 a=ReadOneChar(); //低位b=ReadOneChar(); //高位b<<=8;t=a+b;return(t);}(3)、18b20.h#ifndef __DS18B20_H__#define __DS18B20_H__#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int;/*------------------------------------------------端口定义------------------------------------------------*/ sbit DQ=P1^0;//ds18b20 端口/*------------------------------------------------函数声明------------------------------------------------*/ unsigned int ReadTemperature(void);bit Init_DS18B20(void);unsigned char ReadOneChar(void);void WriteOneChar(unsigned char dat);#endif(4)、delay.c#include "delay.h"/*------------------------------------------------uS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,,大致延时长度如下 T=tx2+5 uS ------------------------------------------------*/ void DelayUs2x(unsigned char t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M------------------------------------------------*/void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}(5)、delay.h#ifndef __DELAY_H__#define __DELAY_H__/*------------------------------------------------uS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,大致延时长度如下 T=tx2+5 uS ------------------------------------------------*/ void DelayUs2x(unsigned char t);/*------------------------------------------------mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M------------------------------------------------*/ void DelayMs(unsigned char t);#endif5 系统性能测试与分析5.1 数据记录:设定温度:42℃ 供电电压:10V时间、温度数据记录表:时间/s 0 21 43 62 87 107 135 温度/℃ 34.5 35 35.5 36 36.5 37 37.5 时间/s 157 185 209 241 270 302 330 温度/℃ 38 38.5 39 39.5 40 40.5 41 时间/s 340 350 360 370 380 390400 温度/℃ 41 41.1 41.2 41.3 41.3 41.1 41.1 时间/s 410 420 430 440 450 460 470 温度/℃ 41 40.9 40.8 40.8 40.8 40.9 41 时间/s 480 490 500 510 520 温度/℃ 41.1 41.1 41.3 41.3 41.35.2 数据分析与结论:由温度响应曲线可以观察出,最终温度应逐渐稳定在41℃,虽然与设定值42℃仍存在一定的误差,但已基本达到要求。