恒温控制系统设计文档格式.docx
《恒温控制系统设计文档格式.docx》由会员分享,可在线阅读,更多相关《恒温控制系统设计文档格式.docx(25页珍藏版)》请在冰点文库上搜索。
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°
温度测量时间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)
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所示。
图7主程序流程图
2)读出温度子程序
读出温度子程序的主要功能是读出RAM中的9字节,在读出时需进行CRC校验,校验有错时不进行温度数据的改写,程序流程图如图8所示。
DS18B20的各个命令对时序的要求特别严格,所以必须按照所要求的时序才能达到预期的目的,同时,要注意读进来的是高位在后低位在前,共有16位数,小数4位,整数7位,还有5位符号位,具体的参数见DS18B20温度传感器的介绍(表1)。
图8读出温度子程序流程图
3)温度处理并显示程序
由于单片机从DS18B20中读取道德温度是两个字节的数据,在这两个字节的数据中高字节的8为数据中,高5位数据代表着符号位,当这5位全部为1时,表示这时所读取的温度是负值;
低3位和低字节中的8位数据分别代表着实时的温度,所以并不能直接将温度通过显示设备显示出来,而是需要通过相应的程序作为处理才能作为最终的温度显示出来如图8所示。
图8温度处理并显示程序流程图
4.3总程序
#include<
reg51.h>
//包含单片机寄存器的头文件
intrins.h>
//包含_nop_()函数定义的头文件
#include<
absacc.h>
math.h>
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;
n;
delay1ms();
}
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
200;
time_DS18B20++);
//略微延时约600微秒以向DS18B20发出一持续480~960us的低电平复位脉冲
//释放数据线(将数据线拉高)
//延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)
flag_DS18B20=DQ;
//让单片机检测是否输出了存在脉冲(DQ=0表示存在)
//延时足够长时间,等待存在脉冲输出完毕
return(flag_DS18B20);
//返回检测成功标志
/*--------------------读一个字节的程序----------------------*/
unsignedcharReadOneChar()
unsignedchari=0;
unsignedchardat;
//储存读出的一个字节数据
for(i=0;
8;
{
DQ=1;
//先将数据线拉高
_nop_();
//等待一个机器周期
DQ=0;
//单片机从DS18B20读书据时,将数据线从高拉低即启动读时序
dat>
>
=1;
DQ=1;
//将数据线"
人为"
拉高,为单片机检测DS18B20的输出电平作准备
for(time_DS18B20=0;
3;
//延时约6us,使主机在15us内采样
if(DQ==1)
dat|=0x80;
//如果读到的数据是1,则将1存入dat
else
dat|=0x00;
//如果读到的数据是0,则将0存入dat将单片机检测到的电平信号DQ存入r[i]
//延时3us,两个读时序之间必须有大于1us的恢复期
return(dat);
//返回读出的十进制数据
/*--------------------写一个字节的程序----------------------*/
WriteOneChar(unsignedchardat)
unsignedchari=0;
for(i=0;
i<
i++)
DQ=0;
//将数据线从高拉低时即启动写时序
DQ=dat&
0x01;
//利用与运算取出要写的某位二进制数据,并将其送到数据线上等待DS18B20采样
//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样
DQ=1;
//释放数据线
1;
//延时3us,两个写时序间至少需要1us的恢复期
//将dat中的各二进制位数据右移1位
}
4;
//稍作延时,给硬件一点反应时间
voidReadyReadTemp(void)
Init_DS18B20();
//将DS18B20初始化
WriteOneChar(0xCC);
//跳过读序号列号的操作
WriteOneChar(0x44);
//启动温度转换
100;
//温度转换需要一点时间
Init_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]];
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]];
P3=weikong[1];
//显示个位
P2=table[duan[1]];
dot=0;
//显示小数点
if(flag)//当温度为负数时显示符号位
{
P2=0xbf;
if(!
duan[3])
{
P3=0x08;
if(!
duan[2])
P3=0x04;
{
P3=0x10;
}
delaynms
(1);
P3=0;
flag=0;
delaynms(25);
//延时一段时间
/*--------------------主程序----------------------*/
voidmain()
while
(1)//不断检测并显示温度
ReadyReadTemp();
//读温度准备
display();
if((temp<
25)||(temp>
35))//如果温度超出范围继电器工作控制温度
jdq=1;
jdq=0;
}
/*---------------------总程序结束---------------------