资源描述
基于PID算法的水温控制系统设计报告
49
2020年4月19日
文档仅供参考
基于PID的水温控制系统设计
摘 要
本次设计采用proteus仿真软件,以AT89C51单片机做为主控单元,运用PID控制算法,仿真实现了一个恒温控制系统。设计中使用温度传感器DS18B20采集实时温度,不需要复杂的信号调理电路和A/D转换电路,能直接与单片机完成数据的采集和处理,使用PID算法控制加热炉仿真模型进行温度控制,总体实现了一个恒温控制仿真系统。系统设计中包含硬件设计和软件设计两部分,硬件设计包含显示模块、按键模块、温度采集模块、温度加热模块。软件设计的部分,采用分层模块化设计,主要有:键盘扫描、按键处理程序、液晶显示程序、继电器控制程序、温度信号处理程序。另外以 AT89C51 单片机为控制核心,利用PID 控制算法提高了水温的控制精度,使用PID 控制算法实施自动控制系统,具有控制参数精度高、反映速度快和稳定性好的特点。
关键词 :proteus仿真,PID,AT89C51,DS18B20温度控制
目 录
1 系统总体设计方案论证 1
1.1 设计要求 1
1.2 总体设计方案 2
2 系统的硬件设计 3
2.1 系统硬件构成概述 3
2.2 各单元总体说明 4
2.3 按键单元 5
2.4 LCD液晶显示单元 6
2.5 温度测试单元 7
2.6 温度控制器件单元 8
3 恒温控制算法研究(PID) 11
3.1 PID控制器的设计 11
3.2 PID算法的流程实现方法与具体程序 12
4 系统的软件设计 16
4.1 统软件设计概述 16
4.2 系统软件程序流程及程序流程图 17
4.3 温度数据显示模块分析 18
4.4 测试分析 20
5 模拟仿真结果 22
1系统总体设计方案论证
1.1 设计要求
一种基于数字PID和单片机的温度控制系统设计。要求如下:
1、超调量≤10%
2、温度可调,范围;K1=50度 K2=60度 K3=70度 K4=80度
3、人—机对话方便
4、温度误差≤±1℃
1.2 总体设计方案
在仿真设计中,先经过按键设置温度,然后经过温度传感器DS18B20,从环境中采集温度,由单片机获取采集的温度值,经过处理后,可得到当前环境温度中一个比较稳定的温度值,而且经过LCD液晶显示。再去根据当前设定的温度值进行比较,温度未达到预定的下限温度时,单片机将经过P2.6口连接的RELAY输出高电平控制信号来驱动RL1,使得加热棒工作,为系统提供热量,来升高温度。温度上升到预定上限温度时,单片机将经过P2.6口连接的RELAY输出低电平控制信号来驱动RL1,使得加热棒停止加热,让温度慢慢回落[3]。
工作原理图如图1.1所示:
在设计中使用温度传感器DS18B20采集实时温度,使用PID算法控制加热炉仿真模型进行温度控制。DS18B20是DALLAS公司生产的经典的数字温度传感器,具有低功耗、高性能、抗干扰能力、微型化、强易配处理器等等优点,它特别适合用于多点温度测控的系统,它可直接将温度转化成数字信号,交给单片机处理,而且在同一总线上可挂接多个传感器芯片,进行范围性的温度检测。在其内部集成了A/D转换器,可使电路结构更简单,且减少了温度测量转换时的精度损失。数字温度传感DS18B20只用一个引脚,即可与单片机进行连接了,这样大大的减少了设计中接线麻烦的问题,使得单片机能够节约许多端口。DS18B20芯片的体积又比较小,且还是单线与主控芯片连接,于是在实际运用中,常常把数字温度传感器DS18B20做成小型的测量温度的探头,即使是一些狭小的位置也能很方便的检测到,使温控系统发挥最大的作用[4]。
在本仿真设计中DS18B20与51单片机的P3.4口链接。DS18B20能够仿真设置环境温度,来完成设计要求。
本次设计采用proteus仿真软件,以AT89C51单片机做为主控单元。51单片机上连接晶振和复位电路,保证单片机的正常运行。P0口与LCD液晶连接,显示测量结果。P1.0,P1.4,P3.3,P3.4分别与4个控制按键连接。由AT89C51的端口丰富使得整个系统设计起来方便简单,线路清晰,且AT89C51是一个高性能,低功耗的CMOS 8位单片机,AT89C51设计和配置了振荡频率可为0Hz,在实际的应用中性价比很高,是温控系统的不二选择。本设计中选择AT89C51做为主控单位也是考虑到了实际的需求和做此设计的意义的[5]。
2系统的硬件设计
2.1 系统硬件构成概述
本章主要介绍本次设计中的硬件设计部分,其中包含:显示模块、按键扫描模块、温度采集模块、温度加热模块。
2.2 各单元总体说明
1、 显示模块:本设计中采用LCD液晶显示温度值,其中最后一位为小数位。
2、 按键模块:本设计中采用5按键设置,第一按键为复位按键,第2、3、4、5按键为温度档位按键,连接上拉电阻使其未按键时能够保持高电平。
3、 温度采集模块:本次设计中使用温度传感器DS18B20采集实时温度,使用PID算法控制加热炉仿真模型进行温度控制,数字温度传感器DS18B20只需一个引脚,即可与单片机进行通信,在设计中将DS18B20与51单片机的P3.4口连接,用其来完成温度的测量[6]。
4、 温度加热模块:本设计采用加热棒来进行温度值的控制,其配有功率显示表,以便在仿真中与温度传感器DS18B20相对应,便于统计。加热棒与光电耦合器连接,光电耦合器经过RELAY与51单片机的P2.6口连接。经过51单片机发送信号来控制加热棒的运作。
2.3 按键单元
一般的键盘设计采用的是硬件设计,可是其在仿真设计中连接,线路会比较麻烦。因此在本此设置中我采用的是5按键软件控制,第一个按键为复位按键,其它两个为档位调节按键,K1为50度、K2为60度、K3为70度、K4为80度,方便简洁,线路清晰设计起来也较为方便。连接上上拉电阻,使其当未有按键按下时,各各按键位都处于高电平。
按键操作说明:
1号按键为复位设置按键,第一次按下它时,1号按键位将处于低电平,LCD液晶将会显示未加热时的温度,此时,可经过档位按键设置温度,然后进行其它功能模块的操作。
电路如图3.1所示:
图3.1 按键电路
3.6 温度测试单元
在本设计中温度测试采用温度芯片DS18B20与51单片机的P3.4口连接。此集成芯片,能够很好的减少外界的干扰。其内部集成A/D转换器,使得电路结构更简单,且减少了温度测量转换时的精度损失,从而使测量的温度值更为精确,具有实在的设计意义。且数字温度传感器DS18B20只用一个引脚,即可与单片机进行通信了,大大的减少了接线麻烦的问题,使得单片机更加具扩展性。由于DS18B20芯片的小型化,经过单条数据线,就能够和主电路连接,在实际应用中,可把数字温度传感器DS18B20做成测温探头,可方便的探入到狭小的地方,从而增加了实用性[9]。
DS18B20的开始运作时,首先要做的是复位工作,即在开始工作前,51单片机将会给DS18B20当总先发送一个不小于480us的低电平信号,对其进行复位。DS18B20在接收到这个信号后的15~60us内会回发一个芯片的存在脉冲。为了接收存在脉冲,数据当总线将会被控制器拉高,存在脉冲是一个60~240us的低电平信号。接下去将进行51单片机与DS18B20间的通信。51单片机发送控制的指令共有5指令,而每一个工作周期只能够发送一条指令。5条指令分别为:读取数据、指定匹配的芯片、跳跃ROM、芯片搜索、报警芯片搜索。接着51单片机发送存储器操作指令(在指令发送给DS18B20后,马上就发送存储器操作指令了)。存储器指令的功能就是控制DS18B20怎么样进行工作。
DS18B20同51单片机的接线如图3.4所示:
见图可知DS18B20只需与单片机的一个端口连接即可,不过当总线为开漏需要外接一个上拉电阻,为4.7KΩ。
3.7 温度控制器件单元
在本次设计中,是采用加热棒经过PID算法来对温度进行控制的,以便在仿真中与温度传感器DS18B20相对应,便于统计。加热棒与光电耦合器连接,光电耦合器经过RELAY与51单片机的P2.6口连接。
51单片机经过RELAY口向光电耦合器发送高电平时,无电流流过,光电耦合器将不导通,继电器也不能导通,继电器的线圈无电流经过,RL1打向电源处,加热棒通电开始工作加热,能够看出加热棒提升的温度。
当测量到的温度值超出先前设定的预期温度值上限时,51单片机通同过RELAY口向光电耦合器发送低电平时,光电耦合器将导通,有电流流过,使得继电器也导通,继电器的线圈有电流经过,RL1打向继电器线圈,加热棒断开连接,停止工作,使温度慢慢的回落。
温控系统连接方法如图3.5所示:
图3.5 温控系统电路
4 恒温控制算法研究(PID)
4.1 PID控制器的设计
PID控制是当前在温度控制中应用最广泛的一种控制算法,其核心思想是按设定值与测量值之间的偏差比例、偏差的积累和偏差变化的趋势来控制输出量,即根据偏差值来计算控制量。数字PID控制律的实现,需采用数值逼近法,当采样的周期相当短时,能够用用差商代替微分,求和代替积分,能够有如下近似变换[10]。
(4.1)
式中,k为采样的序号,k=l,2,…;T为采样的周期。
在离散化的过程中,采样时间T须足够的短,不然难以确保精度。在运算时,把表示成等,省去了T。则可推算出离散的PID表示式写成:
(4.2)
式中,k为采样的序号,k=1,2,…;是第k次采样时,计算机输出的值;是第k次采样时输入的偏差值;是第次采样时输入的偏差值;是积分系数,;是积分系数,。
在实际的应用中,一般采用增量式PID控制算法,即数字控制器输出只是控制量的增量,该算法编程简单,数据能够递推使用,占用存储空间少,运算快。
根据递推原理可得:
4 恒温控制算法研究(PID)
4.1 PID控制器的设计
PID控制是当前在温度控制中应用最广泛的一种控制算法,其核心思想是按设定值与测量值之间的偏差比例、偏差的积累和偏差变化的趋势来控制输出量,即根据偏差值来计算控制量。数字PID控制律的实现,需采用数值逼近法,当采样的周期相当短时,能够用用差商代替微分,求和代替积分,能够有如下近似变换[10]。
(4.1)
式中,k为采样的序号,k=l,2,…;T为采样的周期。
在离散化的过程中,采样时间T须足够的短,不然难以确保精度。在运算时,把表示成等,省去了T。则可推算出离散的PID表示式写成:
(4.2)
式中,k为采样的序号,k=1,2,…;是第k次采样时,计算机输出的值;是第k次采样时输入的偏差值;是第次采样时输入的偏差值;是积分系数,;是积分系数,。
在实际的应用中,一般采用增量式PID控制算法,即数字控制器输出只是控制量的增量,该算法编程简单,数据能够递推使用,占用存储空间少,运算快。
根据递推原理可得:
(4.3)
公式(4.2)与公式(4.3)相减,即得到增量式PID控制算法(4.4):
(4.4)
本次设计中,控制器的设计采用增量数字PID控制算法的功能,能够比较灵活的调节控制信号的导通时间来控制温度值控制的工作。能够基本满足温度控制的要求。
4.2 PID算法的流程实现方法与具体程序
本系统设计的温度控制系统是与光电耦合器连接的加热炉。传统的方法是:当测量的环境温度达到设定值时,加热炉不在加热状态,可是此时加热炉的温度依然会高与设定的温度值,加热炉还是会起到加热的作用,使得系统的温度经常继续要升高一会后才能开始下降。当下降到设定的下限温度值时,温控系统会促使加热炉开始工作,对系统进行加热,此过程需要一定的时间,因此往往又会下降一定温度,才能开始上升温度。因此传统的方法往往会出现一定的误差,此误差就是温度的惯性引起的[11]。
PID算法是PID模糊控制技术的核心部分,经过比例、积分、微分三方面的结合与调整构成一个反馈控制,可解由于温度的惯性而产生的误差。
经过PID控制器处理后可输出电压的控制信号,从而反馈调节温度。数字PID的控制示意图如图4.1所示:
图4.1 数字PID的控制
实验中最主要的就是PID参数的选择,它决定着整个温度控制的精确度。我们能够根据具体情况的要求,来调节合适的参数。
P为比例系数,当在一定范围内若是调节增加P时,系统的反映将会变的灵敏,稳态的误差值将会变小,可要是P值过大时的话,同样会时系统变得不稳定。P值过于小了,系统的反映又会变的很慢。可见的,P值要是选取不恰当,测量值就会和设定值的偏差越来越大,要是出现了这样的问题时,可将P值的符号取反[12]。
I为积分系数,I的值越小积分的作用就会越强,积分作用强了就会导致系统的稳定性下降,不过T值小了,稳态所产生的误差将会减小。
D为微分控制,微分控制能够改进动态的特性,当D偏大时,超调量随之变大,调节时间会减短;D偏小时,超调量同样变大,不过调节时间就会比较长,只有D合适时,才能使超调量较小,调节时间也较短。
调试时,只能参考参数对系统控制过程的变化趋势,来对参数调整来先比例,后积分,再微分的步骤慢慢调试,一直凑到满意的结果为止。
数字PID的差分方程:
(4.5)
在上式中,称为比例项;称为积分项;称为微分项。
得到增量式公式为:
(4.6)
在此式中,,,。
PID的具体算法程序如下[13]:
Enum{Y,U,R,,};//Y采集量、U控制量、R设定量、采样时间、微分、比例
int para[6],ptr,out;//out是从PID( )得到的控制量
int r,,,Ts,e2,e1,e0,u;
/************************************************************************/
Void initPID( ) // 初始化PID函数
{para[R]=20;
para[]=2;
para[]=2;
para[]=1
}
Void PID( )
{ para[Y]=(int)(ad_data);
r=para[R];
e0=e1;e1=e2;e2=r-para[Y]/10;
=para[];Kd=para[];ts=para[];
u=r+*[e2+*(e2-e1)];,
if(u<0)u=0; // 控制量限制
if(u>200)u=200;
para[u[=u/10;
out=para[u];
}
Void Tem_timer0( ) interrupt 1 // 采样时间
{ THO=tim0>>8;TL0=tim0;
If(tm++>out)TEM=1;
else TEM=0;
if(m>200)tm=0;
if(out<10)TEM=1;
if(timecnt++==100) timecnt=0;
}
Void timer1( ) interrupt 3
{ TH1=timer 1( )>>8;TLI=tim 1;
If(dealCS==0)
{
wdCtrl=para[R];
if((wdCtrl-(int)(ad_data)/10)>10)out=200;
else if (((int)(ad_data)/10-wdCtrl)>2)out=0;
else out=Ctrltab[wdCtrl+2-(int)(ad_data)/10];
}
Else if (tx++>=ts)
{ PID( );
t=0;
}
}
5 系统的软件设计
5.1 统软件设计概述
在恒温PID控制系统中软件是整个系统的核心,在软件设计中采用分层模块化设计,其中主要的模块包含:人机交互模块、数据显示模块、PID控制器模块、信号采集模块、超、低温报警模块几部分[14]。
1、人机交互模块,是经过3位按键来实现的。第一个按键为复位按键,其它两个为调节按键,当有键按下时该键位将会处于低电平状态,按键连接上了电阻,使其当未有按键按下时,各各按键位都处于高电平[15]。本设计中的按键具体原理与操作方法,在第三章的按键单元中已经做了详细的说明。
2、数据显示模块,是经过LCD液晶实现的。采用的是经过动态显示法,分时分别控制LCD液晶的COM端,使每个位轮流显示,每位点亮的时间间隔大概为1ms左右。
3、PID控制器模块,本设计是运用PID控制算法,仿真实现一个恒温控制系统。在上一章中我们已经描述了,电压的控制信号,从而反馈调节温度。设计中最主要的就是PID参数的选择,它决定着整个温度控制的精确度。我们能够根据具体情况的要求,来调节合适的参数。对PID函数进行初始化时,需设置函数参数,这些参数都是根据实验测定获得的,具体参数在上一章PID算法研究中有详细说明。
4、信号采集模块,本设计中是运用DS18B20进行温度采集的,在DS18B20开始运作时,首先要做的是复位工作,DS18B20在接收到这个信号后的15~60us内会回发一个芯片的存在脉冲。为了接收存在脉冲,数据当总线将会被控制器拉高,存在脉冲是一个60~240us的低电平信号。接下去将进行51单片机与DS18B20间的通信。接着51单片机发送存储器操作指令(在指令发送给DS18B20后,马上就发送存储器操作指令了)。控制DS18B20怎么样进行工作[16]。
5.2 系统软件程序流程及程序流程图
系统软件流程如图5.2所示:
图5.2 系统软件流程图
程序流程为:
在程序开始的时,先设置初始化,经过按键设置预定温度值,然后经过数码管来显示当前的温度,再比较设定的预期温度与测量温度值的大小,将比较的信息经过继电器,去根据当前设定的温度值的上下限,当测量到的温度值未达到先前设定的预期温度值下限时,使单片机向蜂鸣器发送高电平信号使其发出警报生,再经过RELAY口向光电耦合器发送高电平时,无电流流过,光电耦合器将不导通,继电器也不能导通,继电器的线圈无电流经过,RL1打向电源处,加热棒通电开始工作加热,能够根据功率表的数据显示看出加热棒提升的温度。当测量到的温度值超出先前设定的预期温度值上限时,使单片机将向蜂鸣器发送高电平信号使其发出警报生,再经过过RELAY口向光电耦合器发送低电平时,光电耦合器将导通,有电流流过,使得继电器也导通,继电器的线圈有电流经过,RL1打向继电器线圈,加热棒断开连接,停止工作,使温度慢慢的回落。
5.3 温度数据显示模块分析
在本次软件设计中,核心的部分就是PID算法的控制与DS18B20温度采集的实现,PID算法在上文中已经做了详细的介绍,在此再具体的分析下DS18B20。
在本次设计我选择了DS18B20来继续温度检测,因为数字温度传感器DS18B20只需一个引脚,即可与单片机进行通信了,大大的减少了接线麻烦的问题,使得单片机更加具扩展性。由于DS18B20芯片的小型化,经过单条数据线,就能够和主电路连接,可把数字温度传感器DS18B20做成测温探头,可方便的探入到狭小的地方,从而增加了实用性。且本次设计采用proteus仿真软件,在proteus仿真软件里DS18B20能够随意设定温度,模仿实际环境温度值,便于实验[17]。
DS18B20数字温度传感器的内部包含了高速暂存RAM与用来存储TH、TL的E2ARM。接受到的数据先是存入RAM,经检验后传送至E2ARM。RAM中的第5个字节用与控制温度的数字转换分辨率,此分辨率决定DS18B20工作时温度转换的先对应的数值。其中要注意的是设定的分辨率越高,就需要消耗越多的转换时间。因此在设置分辨率时我们需要有所考虑[18]。
DS18B20在接收到温度转换的命令后,将温度值数据转换成以二进制补码的形式存储在RAM中,然后51单片机再经过单总线接收此数据,以地位在前高位在后的方式来读取数据。接收数据后经过温度计算,将得出的温度值与设定的TH、TL进行比较,51单片机再根据比较的结果做出相应的运行工作。
为此我们在程序设计中设计了下面主要几个子程序。
首先对DS18B20进行初始化处理
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 0; //单片机将DQ拉低
delay_18B20(80); //精确延时大于480us
DQ = 1; //拉高总线
delay_18B20(14);
x=DQ; //稍做延时后,如果x=0则初始化成功x=1则初始化失败
delay_18B20(20);
}
在初始化后,先让DS18B20读一个字节
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_18B20(4);
}
return(dat);
}
再让其写一个字节,运行子程序如下:
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}
接下来设计DS18B20的工作状态,设置其上、下限报警温度分别为TH和TL,且设置显示的分辨率为RS,执行的子程序如下[18]:
void setds18b20(unsigned char TH,unsigned char TL,unsigned char RS)
{
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x4E); // //写入“写暂存器”命令,修改TH和TL和分辩率配置寄存器
//先写TH,再写TL,最后写配置寄存器
WriteOneChar(TH); //写入想设定的温度报警上限
WriteOneChar(TL); //写入想设定的温度报警下限
WriteOneChar(RS); //写配置寄存器,格式为0 R1 R0 1,1 1 1 1
//R1R0=00分辨率娄9位,R1R0=11分辨率为12位
}
最后就是读取DS18B20的温度值了,执行子程序如下:
unsigned char *ReadTemperature(void)
{ unsigned char tt[2];
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay_18B20(70); // 温度转化要一段时间
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度
//delay_18B20(70);
tt[0]=ReadOneChar(); //读取温度值低位
tt[1]=ReadOneChar(); //读取温度值高位
return(tt);
}
5.4 测试分析
1、测试环境
仿真环境温度20—90摄氏度。
2、测试方法
用调节DS18B20,来模拟环境温度,经过按键来设置温度的上、下限与复位,根据LCD液晶显示来观察结果。
3、测试结果
(1)设定温度由20摄氏度到90摄氏度。
(2)标定温差≦1摄氏度调节时间15s(具体情况随实际情况)。
(3)静态误差≦0.5摄氏度最大超调量1摄氏度。
4、经过仿真测试分析,对于实际的室内的温度控制,能够再得出以下2点方法:
(1)我们能够经过增加传感器的个数,然后算出平均值,这样能够获得较为精确的温度值。
(2)在对环境温度的控制环节中,我们可采用功率较大的加热电阻,实现对环境温度的提升,用风扇来对环境温度进行降温处理。
51单片机经过RELAY口向光电耦合器发送高电平时,无电流流过,光电耦合器将不导通,继电器也不能导通,继电器的线圈无电流经过,RL1打向电源处,如图6.2所示:
图6.2 17℃时系统电流流向图
此时加热棒通电开始工作加热,能够根据功率表的数据显示得出加热棒提升的温度,如图6.3所示:
51单片机通同过RELAY口向光电耦合器发送低电平时,光电耦合器将导通,有电流流过,使得继电器也导通,继电器的线圈有电流经过,RL1打向继电器线圈,如图6.5所示:
图6.5 41℃时的系统电流流向图
此时加热棒断开连接,停止工作,可是加热棒还是会有一定的延迟性,只能让温度慢慢的回落,如图6.6所示:
结 论
本次设计采用proteus仿真软件,以AT89C51单片机做为主控单元,运用PID控制算法,仿真实现了一个恒温控制系统。设计中使用温度传感器DS18B20采集实时温度,使用PID算法控制加热棒仿真模型进行温度控制,总体实现了一个恒温控制仿真系统。仿真中先经过按键设置温度,然后经过温度传感器DS18B20,从环境中采集温度,由单片机获取采集的温度值,经过处理后,可得到当前环境温度中一个比较稳定的温度值,而且经过LCD液晶显示。再去根据当前设定的温度值的上下限,温度未达到预定的下限温度时,同时经过P2.6口连接的RELAY输出高电平控制信号来驱动RL1,使得加热棒工作,为系统提供热量,来升高温度。温度上升到预定上限温度时,同时经过P2.6口连接的 RELAY输出低电平控制信号来驱动RL1,使得加热棒停止加热,让温度慢慢回落。
附 录
主程序
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^4;//ds18b20与单片机连接口
unsigned char code led[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82
,0xf8,0x80,0x90,0xff};
uchar data disdata[5];
uchar Vref=5;
uchar a[6];
sbit PIN=P0^7;
unsigned int tvalue;//温度值
signed int temp=0;
uchar tflag;//温度正负标志
signed char th=40;//上限温度
signed char tl=20; //下限温度
sbit SPEAKER=P1^5;
sbit SET=P1^0;
sbit ADD=P1^4;
sbit SUB=P3^3;
unsigned char num;
sbit RELAY=P2^6;
/*************************LCD1602程序**************************/
void delay1ms(unsigned int ms)//延时1毫秒(不够精确的)
{unsigned int i,j;
for(i=0;i<ms;i++)
for(j=0;j<100;j++);
}
void keyscan()
{
if(SET==0)
{
delay1ms(10);
if(SET==0)
{
num++;
if(num==3)
num=0;
while(!SET);
}
}
if(num!=0)
{
if(ADD==0)
{
delay1ms(10);
if(ADD==0)
{
if(num==1)
{
th++;
if(th==125)
th=tl+1;
}
if(num==2)
{
if(tl<(th-1))
tl++;
}
}
while(!ADD);
}
if(SUB==0)
{
delay1ms(10);
if(SUB==0)
{
if(num==1)
{
th--;
if(th==(tl+1))
th=125;
}
if(num==2)
{
tl--;
if(tl==-25)
tl=th-1;
}
}
while(!SUB);
}
}
}
/*************************DS18B20程序**************************/
void delay_18B20(unsigned int i)//延时1微秒
{
while(i--);
}
void ds1820rst()/*ds1820复位*/
{ unsigned char x=0;
DQ = 1; //DQ复位
delay_18B20(4); //延时
DQ = 0; //DQ拉低
delay_18B20(100); //精确延时大于480us
DQ = 1; //拉高
delay_18B20(40);
}
uchar ds1820rd()/*读数据*/
{ 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_18B20(10);
}
return(dat);
}
void ds1820wr(uchar wdata)/*写数据*/
{unsigned char i=0;
for (i=8; i>0; i--)
{ DQ = 0;
DQ = wdata&0x01;
delay_18B20(10);
DQ = 1;
wdata>>=1;
}
}
read_temp()/*读取温度值并转换*/
{uchar a,b;
ds1820rst();
ds1820wr(0xcc);//*跳过读序列号*/
ds1820wr(0x44);//*启动温度转换*/
ds1820rst();
ds1820wr(0xcc);//*跳过读序列号*/
ds1820wr(0xbe);//*读取温度*/
a=ds1820rd();
b=ds1820rd();
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a;
if(tvalue<0x0fff)
{
tflag=0;
}
else
{tvalue=~tvalue+1; //低于零度
tflag=1;
}
tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数
return(tvalue);
}
/*******************************************************************/
void ds1820disp()//温度值显示
{
disdata[0]=tvalue/1000;
disdata[1]=tvalue%1000/100;
disdata[2]=tvalue%100/10;
disdata[3]=tvalue%10;//小数位
//disdata[]=0;
//}
if(tflag==0)
{
P2=0x01;
P0=led[disdata[0]];
delay1ms(10);
P2=0x02;
P0=led[disdata[1]];
delay1ms(10);
P2=0x04;
P0=led[disdata[2]];
PIN=0;
delay1ms(10);
P2=0x08;
P0=led[disdata[3]];
delay1ms(10) ;
}
else
{
P2=0x01;
P0=0xbf;
delay1ms(10);
P2=0x02;
P0=led[tvalue%1000/100];
delay1ms(10);
P2=0x04;
P0=led[tvalue%100/10];
PIN=0;
delay1ms(10);
P2=0x08;
P0=led[tvalue%10];
delay1ms(10) ;
}
}
void displayth(void)
{
P2=0x01;
P0=0x89;
delay1ms(10);
if(th>0)
{
P2=0x02;
P0=led[th/100];
delay1ms(10);
P2=0x04;
P0=led[th%100/10];
delay1ms(10);
P2=0x
展开阅读全文