恒温控制系统设计.docx
《恒温控制系统设计.docx》由会员分享,可在线阅读,更多相关《恒温控制系统设计.docx(28页珍藏版)》请在冰豆网上搜索。
恒温控制系统设计
恒温控制系统设计
摘要
本设计基于AT89C51和DB18B20来实现温度控制器的制作,它以89C51单片机为核心,配以DS18B20(数字温度传感器),LED灯(模拟对温度的控制系统),数码管来作为实时问的的显示。
系统的设计思路比较简单,且易于实施。
在硬件设计方面,由AT89C51、DS18B20(数字温度传感器)、数码管,小风扇,金属膜电阻构成的电路,在软件方面,以单片机和DS18B20数字温度传感器为中心,详细的阐述了系软件设计的思想,主流程图以及相应电路模块的流程图。
关键词:
DS18B20传感器,AT89C51,温度处理,程序
1绪论
随着电子技术,特别是随大规模集成电路的产生而出现的微型计算机技术的飞速发展,人类生活发生了根本性的改变。
如果说微型计算机的出现使现代科学研究得到了质的飞跃,那么可以毫不夸张地说,单片机技术的出现则是给现代工业测控领域带来了一次新的技术革命。
目前,单片机以其体积小、重量轻、抗干扰能力强、对环境要求不高、高可靠性、高性能价格比、开发较为容易,在工业控制系统、数据采集系统、智能化仪器仪表、办公自动化等诸多领域得到极为广泛的应用,并已走人家庭,从洗衣机、微波炉到音响、汽车,到处都可见到单片机的踪影。
因此,单片机技术开发和应用水平已逐步成为一个国家工业发展水平的标志之一。
本课题研究的内容就是以单片机为主要控制元件,通过温度传感器,实现对温度的测量,并通过数码管直接显示所测温度。
由于使用模拟温度传感器来读取温度的话操作比较麻烦,因此本课程设计恒温控制系统是由数字温度传感器、单片机系统、温度显示系统、温控电路构成。
其基本工作原理:
单片机通过程序处理和数字温度传感器进行通讯,从而读取其中的温度,然后同过程序处理实现数码管的控制显示出当前的温度,当温度超出所要求的温度范围后,通过程序处理实现单片机对温控电路的控制,当温度达到要求的范围之后停止温控电路的工作,从而实现恒温控制。
基本工作原理框图如图1所示。
图1电路整体框图
2相关芯片的介绍
2.1AT89C51芯片
AT89C51是美国ATMEL公司生产的低电压,高性能CMOS8位单片机,片内含4kbytes的反复擦写的Flash只读程序存储器和128bytes的随机存取数据存储器(RAM),器件采用ATMEL公司高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器(CPU)和Flash存储单元,功能强大AT89C51单片机可为您提供许多高性价比的应用场合,可灵活应用于各种控制领域。
AT89C51引脚图如图2所示。
图2AT89C51引脚图
AT89C51的功能特性
AT89C51提供以下标准功能:
4K字节Flash闪速存储器,128字节内部RAM,32个I/O口线,两个十六位定时/计数器,一个5向量两级中断结构,一个全双工串行通信口,片内振荡器及时钟电路。
同时,AT89C51可降至0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式。
空闲方式停止CPU的工作,但允许RAM,定时/计数器,串行通信口及中断系统继续工作。
掉电方式保存RAM中的内容,但振荡器停止工作并禁止其他所有部件工作直到下一个硬件复位。
2.2DS18B20数字温度传感器
2.2.1DS18B20的基本介绍
数字化温度传感器DS18B20芯片是世界上第一片采用单总线方式的温度传感器。
如图2为芯片的外形图和引脚图。
图中显示了该芯片的两种封装形式,SOIC为小外形集成电路封装,另一种为三极管外形封装。
图2DS18B20芯片外形及引脚
该芯片测量物体的温度,并在单总线上传送测量数据。
和传统的模拟信号测量方式相比,它提高了抗御干扰的能力,适用于环境控制、设备控制、过程控制以及测温类消费电子产品等领域。
1)三极管外形封装的DS18B20,外形如同一只小功率三极管,其引脚定义是:
1、GND接地
2、DQ单总线接口
3、VDD电源
2)DS18B20芯片的主要特点
工作电压3.0V~5.5V
温度测量范围-55°C~125°C
在-10°C~+85°C范围内,测量精度为±0.5°C。
待机状态下无功率消耗。
可编程分辨率9~12位,每位分别代表0.5°C、0.25°C、0.125°C和0.0625°C。
温度测量时间200ms。
温度传感器是芯片的核心部分,它连续地对物体温度进行测量,并连续地将新测量结果存放在高速暂存器RAM中,存放形式如表1:
表1温度传感器的温度表
低字节(LSByte)
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
23
22
21
20
2-1
2-2
2-3
2-4
高字节(MSByte)
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
S
S
S
S
S
26
25
24
测量温度值被放在两个字节中,高字节的高5位是符号位,代表一位符号。
若这5位均为“0”,表示符号为正,测量温度为正值;若这5位均为“1”,则表示符号为负,测量的温度为负值。
高字节的低3位和低字节的8位,共11位,是测量的数值部分。
测量值为正时,将数值乘以0.0625即可得到实际测量温度数;测量值为负时,将数值其变补再乘以0.0625即可得到实际测量温度的绝对值。
比如温度+125°C对应的转换数字为07D0H,温度-55°C对应的转换数字为FC90H。
2.2.2DS18B20指令以及读写
1)DS18B20的ROM指令和RAM指令
ROM指令用来确认DS18B20的身份,即在众多的单总线芯片或多个DS18B20中指定某一个芯片作为操作对象。
确定的基本方式是核对各芯片的64位的序列号代码,该过程比较复杂,需要若干条ROM指令的配合;在仅用1个DS18B20芯片的场合,只需用“跳过”指令(CCH),就可省略确认身份的过程。
DS18B20的RAM指令见表2。
RAM指令用来对已经确认身份、被指定为操作对象的DS18B20芯片进行具体的读写操作。
表2DS18B20的RAM指令
指令
代码
功能
温度变换
44H
启动温度转换,12位转换时最长为750ms。
结果存入内部9字节RAM中
指令
代码
功能
读暂存器
BEH
读DS18B20RAM中9字节内容
写暂存器
4EH
发出向内部RAM的2、3、4字节写上、下限温度数据和配置寄存器命令,紧跟该命令之后,是传送三字节的数据
复制暂存器
48H
将RAM中2、3字节的内容复制到E2PROM中
重调E2PROM
B8H
将E2PROM中内容恢复到RAM中的第2、3字节
读供电方式
B4H
读供电模式。
寄生供电模式时发送“0”,外接电源供电发“1”
2)DS18B20的读写操作过程
1、DS18B20的初始化:
(1)先将数据线置高电平“1”。
(2)延时(该时间要求的不是很严格,但是尽可能的短一点)(3)数据线拉到低电平“0”。
(4)延时750微秒(该时间的时间范围可以从480到960微秒)。
(5)数据线拉到高电平“1”。
(6)延时等待(如果初始化成功则在15到60毫秒时间之内产生一个由DS18B20所返回的低电平“0”。
据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。
(7)若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。
(8)将数据线再次拉高到高电平“1”后结束。
2、DS18B20的写操作:
(1)数据线先置低电平“0”。
(2)延时确定的时间为15微秒。
(3)按从低位到高位的顺序发送字节(一次只发送一位)。
(4)延时时间为45微秒。
(5)将数据线拉到高电平。
(6)重复上
(1)到(6)的操作直到所有的字节全部发送完为止。
(7)最后将数据线拉高。
3、DS18B20的读操作:
(1)将数据线拉高“1”。
(2)延时2微秒(3)将数据线拉低“0”。
(4)延时15微秒。
(5)将数据线拉高“1”。
(6)延时15微秒。
(7)读数据线的状态得到1个状态位,并进行数据处理。
(8)延时30微秒。
根据DS18B20的通讯协议,主机(单片机)控制DS18B20完成温度转换必须经过三个步骤:
每一次读写之前都要对DS18B20进行复位操作,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。
复位要求主CPU将数据线下拉500微秒,然后释放,当DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。
3硬件电路设计
3.1主控制电路设计
由于本系统是利用AT89C51单片机设计的,因此,首先应该构建以51单片机为核心的最小系统,然后在此最小系统的基础上进行扩展外围接口从而实现不同功能的控制。
单片机的最基本的电路,由复位电路(RST)和晶振电路(为系统工作提供时钟脉冲)两部分组成,电路图如图3所示。
图3单片机最基本电路
通过此最基本电路可以在外围加上显示电路、和温控电路以及DS18B20的温度读取电路再加上程序的控制就可以工程一个恒温控制系统。
3.2外围接口电路
1、DS18B20电路
这个芯片是单总线设计模式,因此电路的连接非常简单,仅仅有数据口DQ和单片机的P1.1口相连接,然后就是电源线和地线,如下图所示:
图4DS18B20电路
2、数码管显示电路
图5数码显示电路
数码显示电路(共阳数码管)是单片机的P2、P3口来控制的。
P2口接的是数码管的段选地址,用以显示不同的数字;P3口接的是数码管的为选,用不同的位选以控制不同的数码管的显示情况。
3、温度控制电路
图6温度控制电路
温度控制电路是由单片机的P1口输出高低电平控制三极管Q1的导通与不导通来控制继电器开关的闭合情况,这里用两个发光二极管作为温度控制的模拟实现温度的控制。
4软件系统软件设计
4.1软件系统设计
一个应用系统要完成各项功能,首先必须有较完善的硬件作保证。
同时还必须得到相应设计合理的软件的支持,尤其是微机应用高速发展的今天,许多由硬件完成的工作,都可通过软件编程而代替。
甚至有些必须采用很复杂的硬件电路才能完成的工作,用软件编程有时会变得很简单,如数字滤波,信号处理等。
因此充分利用其内部丰富的硬件资源和软件资源,采用与C51系列单片机相对应的C51语言和结构化程序设计方法进行软件编程。
本装置的软件包括主程序、读出温度子程序、复位应答子程序、写入子程序、以及有关DS18B20的程序(初始化子程序、写程序和读程序)。
4.2程序组成
系统程序主要包括主程序,读出温度子程序,写入子程序,门限调节子程序等。
1)主程序
主程序的主要功能是负责对DS18B20传感器测量温度的读取,然后再通过C51的程序对读出的温度进行转化处理,最后在对温度的要求对环境进行控制并通过显示设备显示出来。
温度的读取显示与控制要相隔相当短的时间重复操作,以实现对温度的准确控制。
通过调用读温度子程序把从温度传感器中读出的整数部分与小数部分存放在一个字符串中,然后通过调用显示子程序显示出来,主程序的流程图如下图7所示。
N
Y/N
Y
图7主程序流程图
2)读出温度子程序
读出温度子程序的主要功能是读出RAM中的9字节,在读出时需进行CRC校验,校验有错时不进行温度数据的改写,程序流程图如图8所示。
DS18B20的各个命令对时序的要求特别严格,所以必须按照所要求的时序才能达到预期的目的,同时,要注意读进来的是高位在后低位在前,共有16位数,小数4位,整数7位,还有5位符号位,具体的参数见DS18B20温度传感器的介绍(表1)。
DS18B20复位、应答子程序
跳过ROM匹配命令
写入子程序
温度转换命令
写入子程序
显示子程序(延时)
DS18B20复位、应答子程序
跳过ROM匹配命令
写入子程序
读温度命令子程序
图8读出温度子程序流程图
3)温度处理并显示程序
由于单片机从DS18B20中读取道德温度是两个字节的数据,在这两个字节的数据中高字节的8为数据中,高5位数据代表着符号位,当这5位全部为1时,表示这时所读取的温度是负值;低3位和低字节中的8位数据分别代表着实时的温度,所以并不能直接将温度通过显示设备显示出来,而是需要通过相应的程序作为处理才能作为最终的温度显示出来如图8所示。
判断温度的正负
(高字节数>127?
)
Y/N
N
Y
温度为负数,
求出温度的补码
对温度进行处理保存
小数部分、百位、十位和个位
把处理后的
数据显示出来
图8温度处理并显示程序流程图
4.3总程序
#include//包含单片机寄存器的头文件
#include//包含_nop_()函数定义的头文件
#include
#include
sbitDQ=P1^1;//定义数据口
sbitjdq=P1^0;//定义继电器控制口
sbitdot=P2^7;//定义显示小数点
unsignedcharcodexiaoshu[]={0xc0,0xc0,0xf9,0xf9,0xa4,0xb0,0xb0,0x99,
0x92,0x92,0x82,0xf8,0xf8,0x80,0x80,0x90};
charduan[4]={0,0,0,0};//存放段控的数据
unsignedcharcodeweikong[]={0x01,0x02,0x04,0x08,0x10,0x20};
//存放数码管的位控数据
unsignedcharcodetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//数码管显示字符
intbai,shi,ge,flag=0,i;
unsignedchartemp;
unsignedcharTL;//储存暂存器的温度低位
unsignedcharTH;//储存暂存器的温度高位
unsignedcharTN;//储存温度的整数部分
unsignedintTD;//储存温度的小数部分
/*--------------------1ms的延时程序--------------------*/
voiddelay1ms()
{
unsignedchari,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++);
}
/*--------------------带参数nms的延时程序------------------*/
voiddelaynms(intn)
{
unsignedchari;
for(i=0;idelay1ms();
}
unsignedchartime_DS18B20;//设置全局变量,专门用于严格延时
/*------------------DS18B20的初始化------------------------*/
bitInit_DS18B20(void)
{
bitflag_DS18B20;//储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在
DQ=1;/先将数据线拉高
for(time_DS18B20=0;time_DS18B20<2;time_DS18B20++);//略微延时约6微秒
DQ=0;//再将数据线从高拉低,要求保持480~960us
for(time_DS18B20=0;time_DS18B20<200;time_DS18B20++);//略微延时约600微秒以向DS18B20发出一持续480~960us的低电平复位脉冲
DQ=1;//释放数据线(将数据线拉高)
for(time_DS18B20=0;time_DS18B20<10;time_DS18B20++);//延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)
flag_DS18B20=DQ;//让单片机检测是否输出了存在脉冲(DQ=0表示存在)
for(time_DS18B20=0;time_DS18B20<200;time_DS18B20++);//延时足够长时间,等待存在脉冲输出完毕
return(flag_DS18B20);//返回检测成功标志
}
/*--------------------读一个字节的程序----------------------*/
unsignedcharReadOneChar()
{
unsignedchari=0;
unsignedchardat;//储存读出的一个字节数据
for(i=0;i<8;i++)
{
DQ=1;//先将数据线拉高
_nop_();//等待一个机器周期
DQ=0;//单片机从DS18B20读书据时,将数据线从高拉低即启动读时序
dat>>=1;
_nop_();//等待一个机器周期
DQ=1;//将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备
for(time_DS18B20=0;time_DS18B20<3;time_DS18B20++);//延时约6us,使主机在15us内采样
if(DQ==1)
dat|=0x80;//如果读到的数据是1,则将1存入dat
else
dat|=0x00;//如果读到的数据是0,则将0存入dat将单片机检测到的电平信号DQ存入r[i]
for(time_DS18B20=0;time_DS18B20<8;time_DS18B20++);//延时3us,两个读时序之间必须有大于1us的恢复期
}
return(dat);//返回读出的十进制数据
}
/*--------------------写一个字节的程序----------------------*/
WriteOneChar(unsignedchardat)
{
unsignedchari=0;
for(i=0;i<8;i++)
{
DQ=1;//先将数据线拉高
_nop_();//等待一个机器周期
DQ=0;//将数据线从高拉低时即启动写时序
DQ=dat&0x01;//利用与运算取出要写的某位二进制数据,并将其送到数据线上等待DS18B20采样
for(time_DS18B20=0;time_DS18B20<10;time_DS18B20++);//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样
DQ=1;//释放数据线
for(time_DS18B20=0;time_DS18B20<1;time_DS18B20++);//延时3us,两个写时序间至少需要1us的恢复期
dat>>=1;//将dat中的各二进制位数据右移1位
}
for(time_DS18B20=0;time_DS18B20<4;time_DS18B20++);//稍作延时,给硬件一点反应时间
}
voidReadyReadTemp(void)
{
Init_DS18B20();//将DS18B20初始化
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0x44);//启动温度转换
for(time_DS18B20=0;time_DS18B20<100;time_DS18B20++);//温度转换需要一点时间
Init_DS18B20();//将DS18B20初始化
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0xBE);//读取温度寄存器,前两个分别是温度的低位和高位
TL=ReadOneChar();//先读的是温度值低位
TH=ReadOneChar();//接着读的是温度值高位
}
/*--------------------温度数据显示子程序----------------------*/
voiddisplay()
{
if(TH>=8)
{
TH=~TH;//当温度为负数时求负数的补码
TL=~TL;
TL=TL+1;
flag=1;//当温度为负值时标志置1
if(TL==0)
TH+=1;
}
duan[0]=TL&0X0f;//保存小数部分的值
temp=(((TH<<4)&0x70)|(TL>>4));//将高8位的低3位和低8位的高4位合并构成温度的整数部分
duan[3]=temp/100;//取百位
duan[2]=temp%100/10;//取十位
duan[1]=temp%10;//取个位
P2=xiaoshu[duan[0]];//显示小数部分
P3=0x01;
delaynms(3);
P3=0;
if(duan[3])//显示百位
{
P3=weikong[3];
P2=table[duan[3]];
delaynms(3);
P3=0;
}
if(duan[3])//显示十位
{
P3=weikong[2];
P2=table[duan[2]];
delaynms(3);
P3=0;
}
else
{
if(duan[2])//显示十位
{
P3=weikong[2];
P2=table[duan[2]];
delaynms(3);
P3=0;
}
}
P3=weikong[1];//显示个位
P2=table[duan[1]];
dot=0;//显示小数点
delaynms(3);
P3=0;
if(flag)//当温度为负数时显示符号位
{
P2=0xbf;
if(!
duan[3])
{
P3=0x08;
if(!
duan[2])
P3=0x04;
}
else
{
P3=0x10;
}
delaynms
(1);
P3=0;
flag=0;
}
delaynms(25);//延时一段时间
}
/*----------------