基于51单片机的PID调温热得快资料.docx

上传人:b****5 文档编号:14448799 上传时间:2023-06-23 格式:DOCX 页数:32 大小:1.33MB
下载 相关 举报
基于51单片机的PID调温热得快资料.docx_第1页
第1页 / 共32页
基于51单片机的PID调温热得快资料.docx_第2页
第2页 / 共32页
基于51单片机的PID调温热得快资料.docx_第3页
第3页 / 共32页
基于51单片机的PID调温热得快资料.docx_第4页
第4页 / 共32页
基于51单片机的PID调温热得快资料.docx_第5页
第5页 / 共32页
基于51单片机的PID调温热得快资料.docx_第6页
第6页 / 共32页
基于51单片机的PID调温热得快资料.docx_第7页
第7页 / 共32页
基于51单片机的PID调温热得快资料.docx_第8页
第8页 / 共32页
基于51单片机的PID调温热得快资料.docx_第9页
第9页 / 共32页
基于51单片机的PID调温热得快资料.docx_第10页
第10页 / 共32页
基于51单片机的PID调温热得快资料.docx_第11页
第11页 / 共32页
基于51单片机的PID调温热得快资料.docx_第12页
第12页 / 共32页
基于51单片机的PID调温热得快资料.docx_第13页
第13页 / 共32页
基于51单片机的PID调温热得快资料.docx_第14页
第14页 / 共32页
基于51单片机的PID调温热得快资料.docx_第15页
第15页 / 共32页
基于51单片机的PID调温热得快资料.docx_第16页
第16页 / 共32页
基于51单片机的PID调温热得快资料.docx_第17页
第17页 / 共32页
基于51单片机的PID调温热得快资料.docx_第18页
第18页 / 共32页
基于51单片机的PID调温热得快资料.docx_第19页
第19页 / 共32页
基于51单片机的PID调温热得快资料.docx_第20页
第20页 / 共32页
亲,该文档总共32页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

基于51单片机的PID调温热得快资料.docx

《基于51单片机的PID调温热得快资料.docx》由会员分享,可在线阅读,更多相关《基于51单片机的PID调温热得快资料.docx(32页珍藏版)》请在冰点文库上搜索。

基于51单片机的PID调温热得快资料.docx

基于51单片机的PID调温热得快资料

《自动控制原理》课程设计

 

指导老师:

邹恩

年级专业:

13自动化4班

姓名学号(分工)韩锦澎201330280107(电路设计)

韦伊玲201330280219(程序编写)

徐敏芳201330280723(焊接调试)

王可欣201330280102(论文)

 

2015年1月7日

目录

1.系统设计方案3

1.1方案一3

1.2方案二3

1.3方案三3

1.4方案的比较和确定3

2.系统硬件部分设计3

2.1系统硬件电路图3

2.1.1单片机AT89C524

2.1.2单片机与LCD通信连接4

2.1.3其他电路模块及总电路5

3系统软件部分5

3.1系统的主流程图如下5

4.温度控制系统PID调节6

4.1PID控制传递函数6

4.2PID参数调节方法6

4.3PID参数设定6

5.实验与调试7

6.总论8

附录8

参考文献24

1.系统设计方案

1.1方案一

选用铂电阻温度传感器。

此类温度传感器线性度、稳定性等方面性能都很好,但其成本较高。

1.2方案二

采用热敏电阻。

选用此类元器件有价格便宜的优点,但由于热敏电阻的非线性特性会影响系统的精度。

1.3方案三

采用DS18B20温度传感器。

DS18B20是DALLAS公司生产的一线式数字温度传感器,具有3引脚封装形式;温度测量范围为-55℃~+125℃,可编程为9位~12位A/D转换精度,测温分辨率可达0.0625℃,被测温度用符号扩展的16位数字量方式串行输出远端引入1.4方案的比较和确定

比较以上三种方案,方案三具有具有体积小、质量轻、线形度好、性能稳定等优点其各方面特性都满足此系统的设计要求的优点,因此选用方案三。

2.系统硬件部分设计

硬件设计包含DS18B20模块,1602液晶显示模块,继电器模块,键盘输入模块和声光报警模块,DS18B20可以被编程,所以箭头是双向的,CPU(89C52)首先写入命令给DS18B20,然后DS18B20开始转换数据,转换后通89C52来处理数据。

数据处理后的结果就显示到1602液晶上。

2.1系统硬件电路图

2.1.1单片机STC89C52

2.1.2单片机与LCD通信连接

2.1.3其他电路模块及总电路

3.系统软件部分

软件设计的部分采用分层模块化设计,主要有键盘扫描、按键处理程序、数码管显示程序、继电器控制程序、温度信号处理程序、超温报警程序。

另外以AT89C52单片机为控制核心。

利用PID控制算法提高了水温的控制精度使用PID控制算法实施自动控制系统具有控制参数精度高、反映速度快和稳定性好的特点。

3.1系统的主流程图如下

4.温度控制系统PID调节

4.1PID控制传递函数

通过热电偶采集的被测温度偏离所希望的给定值时,PID控制可根据测量信号与给定值的偏差进行比例(P)、积分(I)、微分(D)运算,从而输出某个适当的控制信号给执行机构,促使测量值恢复到给定值,达到自动控制的效果。

4.2PID参数调节方法及参数设定

  PID模块的温度控制精度主要受P、I、D这三个参数影响。

其中P代表比例,I代表积分,D代表微分。

  比例运算(P)

  比例控制是建立与设定值(SV)相关的一种运算,并根据偏差在求得运算值(控制输出量)。

如果当前值(PV)小,运算值为100%。

如果当前值在比例带内,运算值根据偏差比例求得并逐渐减小直到SV和PV匹配(即,直到偏差为0),此时运算值回复到先前值(前馈运算)。

若出现静差(残余偏差),可用减小P方法减小残余偏差。

如果P太小,反而会出现振荡。

  积分运算(I)

  将积分与比例运算相结合,随着调节时间延续可减小静差。

积分强度用积分时间表示,积分时间相当于积分运算值到比例运算值在阶跃偏差响应下达到的作用所需要的时间。

积分时间越小,积分运算的校正时间越强。

但如果积分时间值太小,校正作用太强会出现振荡。

  微分运算(D)

  比例和积分运算都校正控制结果,所以不可避免地会产生响应延时现象。

微分运算可弥补这些缺陷。

在一个突发的干扰响应中,微分运算提供了一个很大的运算值,以恢复原始状态。

微分运算采用一个正比于偏差变化率(微分系数)的运算值校正控制。

微分运算的强度由微分时间表示,微分时间相当于微分运算值达到比例运算值在阶跃偏差响应下达到的作用所需的时间。

微分时间值越大,微分运算的校正强度越强。

5.实验与调试

用继电器模块来控制200W“热得快”来对1升水进行加热,用键盘设定需要加热温度值,观察1602所显示的稳定水温和环境温度降低时温度控制的静态误差。

多次调试并合设定PID参数来完善系统。

实物图:

6.总论

首先,通过本次应用系统设计,在很大程度上提高了我们的独立思考能力和专业知识相信在接下来的日子我们能在已有的基础上做得更好。

我们所设计的该系统主要根据目前省能源的发展趋势和国内实际的应用特点和要求,采用了自动化的结构形式,实现对水温的自动检测和控制。

该系统的主要特点是:

1)适用性强,用户只需对界面参数进行设置并启动系统正常运行便可满足不同用户水温的要求,实现对水温的实时监控。

避免了电力力资源的浪费,节省了能源。

2)将单片机以及温度传感器引入对水温的分析和处理中,单片机控制决策无需建立被控对象的数学模型,系统的适应性强,适合对非线性、时变、滞后系统的控制对水温控制系统进行控制。

3)系统成本低廉,操作非常简单,可扩展性强,只要稍加改变,即可增加其他使用功能。

通过对本设计的思考,更加加深了我们对单片机的认识,熟练了对单片机的控制,更对当前的温度传感器有了更深刻的认识与了解,但是由于此系统依赖温度传感器,因而对温度传感器的稳定性,线性等诸多方面有着严格的要求,但是传感器的性能越好,相对而言其价格也就越高,因而在此设计中,温度传感器觉的还是存在遗憾,由于温度计的使用温度有限所以水温不能达到90℃以上。

最后由于时间紧迫,本设计还有诸多地方需要改进,我们会在接下来的时间里继续完善该设计,以期做的更好。

附录:

部分程序:

//main.c:

#include

#include"lcd.h"

#include"temp.h"

#include"pid.h"

sbitc1=P2^6;

sbitc2=P2^7;

sbitbeep=P1^3;

sbitK3=P3^2;

sbitK4=P3^3;

voidIntConfiguration();

voidDelay(unsignedintn);

unsignedcharKeyValue=0;

externfloatset_temper;

/*******************************************************************************

*函数名:

main

*函数功能:

主函数

*输入:

*输出:

*******************************************************************************/

voidmain()

{

externstructPIDspid;//PIDControlStructure

LcdInit();

IntConfiguration();

PIDInit(&spid);

spid.Proportion=10;//SetPIDCoefficients

spid.Integral=8;

spid.Derivative=6;

spid.SetPoint=100;//SetPIDSetpoint

beep=1;

TMOD=0x21;

TH0=0x2f;

TL0=0x40;

//PCON=0X80;//波特率加倍

//TH1=0XF3;//计数器初始值设置,注意波特率是4800的

//TL1=0XF3;

EA=1;

ET0=1;

//ES=1;

TR0=1;

TR1=1;

c1=0;

c2=0;

P1=0XFF;

while

(1)

{

LcdDisplay(Ds18b20ReadTemp());

LcdDisplay2(set_temper);

//LcdDisplay3(realtmp);

/*if((set_temper-realtmp)<1&&(realtmper-set_temp)<1)

{

beep=0;

}

else

beep=1;*/

compare_temper();

//SBUF=Ds18b20ReadTemp();

//Delay1ms

(1);//1s钟刷一次

}

}

voidIntConfiguration()

{

//设置INT0

IT0=1;//跳变沿出发方式(下降沿)

EX0=1;//打开INT0的中断允许。

//设置INT1

IT1=1;

EX1=1;

EA=1;//打开总中断

}

/*******************************************************************************

*函数名:

Delay(unsignedintn)

*函数功能:

延时

*输入:

n

*输出:

*******************************************************************************/

voidDelay(unsignedintn)//延时50us误差0us

{

unsignedchara,b;

for(;n>0;n--)

{

for(b=1;b>0;b--)

for(a=22;a>0;a--);

}

}

/*******************************************************************************

*函数名:

Int0()interrupt0

*函数功能:

外部中断0的中断函数

*输入:

*输出:

*******************************************************************************/

voidInt0()interrupt0//外部中断0的中断函数

{

Delay

(1);//延时消抖

if(K3==0)

{

while(K3==0);

set_temper++;

}

if(set_temper>60.00)

set_temper=60.00;

}

/*******************************************************************************

*函数名:

Int1()interrupt2

*函数功能:

外部中断1的中断函数

*输入:

*输出:

*******************************************************************************/

voidInt1()interrupt2//外部中断1的中断函数

{

Delay

(1);//延时消抖

if(K4==0)

{

while(K4==0);

set_temper--;

}

if(set_temper<40.00)

set_temper=40.00;

}

//pid.c

#include"pid.h"

#include"temp.h"

structPIDspid;//PIDControlStructure

unsignedintrout;//PIDResponse(Output)

unsignedintrin;//PIDFeedback(Input)

inti=0,j=0,flag2=0,tem=0;

sbitoutput=P1^6;

unsignedcharflag,flag_1=0;

unsignedcharhigh_time,low_time,count=0;//占空比调节参数

floatset_temper=40;

voidPIDInit(structPID*pp)

{

high_time=50;

low_time=50;

memset(pp,0,sizeof(structPID));

}

/*====================================================================================================

PID计算部分

=====================================================================================================*/

unsignedintPIDCalc(structPID*pp,unsignedintNextPoint)

{

unsignedintdError,Error;

Error=pp->SetPoint-NextPoint;//偏差

pp->SumError+=Error;//积分

dError=pp->LastError-pp->PrevError;//当前微分

pp->PrevError=pp->LastError;

pp->LastError=Error;

return(pp->Proportion*Error//比例

+pp->Integral*pp->SumError//积分项

+pp->Derivative*dError);//微分项

}

/***********************************************************

温度比较处理子程序

***********************************************************/

voidcompare_temper()

{

unsignedchari;

externfloatrealtmp;

externunsignedints;

if(set_temper>realtmp)

{

if(set_temper-realtmp>1)

{

high_time=100;

low_time=0;

//P1=0XFF;

//mod1=0;

}

else

{

//P1=0XFF;

//mod2=0;

for(i=0;i<10;i++)

{Ds18b20ReadTemp();

rin=s;//ReadInput

rout=PIDCalc(&spid,rin);//PerformPIDInteration

}

if(high_time<=100)

high_time=(unsignedchar)(rout/800);

else

high_time=100;

low_time=(100-high_time);

}

}

elseif(set_temper<=realtmp)

{

if(realtmp-set_temper>0)

{

//P1=0XFF;

//mod3=0;

high_time=0;

low_time=100;

//mod2=0;

}

else

{

//P1=0XFF;

//mod4=0;

for(i=0;i<10;i++)

{Ds18b20ReadTemp();

rin=s;//ReadInput

rout=PIDCalc(&spid,rin);//PerformPIDInteration

}

if(high_time<100)

high_time=(unsignedchar)(rout/10000);

else

high_time=0;

low_time=(100-high_time);

}

}

//else

//{}

}

/*****************************************************

T0中断服务子程序,用于控制电平的翻转,40us*100=4ms周期

******************************************************/

voidserve_T0()interrupt1using1

{

j++;

if(++count<=(high_time))

{

output=1;

i++;

}

elseif(count<=100)

{

output=0;

}

else

count=0;

if(j==1000)

{j=0;flag2=1;tem=i;i=0;}

TH0=0x2f;

TL0=0xe0;

}

/*****************************************************

串行口中断服务程序,用于上位机通讯

******************************************************/

voidserve_sio()interrupt4

{

/*EA=0;

//flag2=0;

while(!

TI);//等待发送数据完成

TI=0;

EA=1;*/

}

//temp.c

#include"temp.h"

inttemp=0;

unsignedints;

//floatset_temp=27.00;

/*******************************************************************************

*函数名:

Delay1ms

*函数功能:

延时函数

*输入:

*输出:

*******************************************************************************/

voidDelay1ms(unsignedinty)

{

unsignedintx;

for(y;y>0;y--)

for(x=110;x>0;x--);

}

/*******************************************************************************

*函数名:

Ds18b20Init

*函数功能:

初始化

*输入:

*输出:

初始化成功返回1,失败返回0

*******************************************************************************/

unsignedcharDs18b20Init()

{

unsignedinti;

DSPORT=0;//将总线拉低480us~960us

i=70;

while(i--);//延时642us

DSPORT=1;//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低

i=0;

while(DSPORT)//等待DS18B20拉低总线

{

i++;

if(i>5000)//等待>5MS

return0;//初始化失败

}

return1;//初始化成功

}

/*******************************************************************************

*函数名:

Ds18b20WriteByte

*函数功能:

向18B20写入一个字节

*输入:

com

*输出:

*******************************************************************************/

voidDs18b20WriteByte(unsignedchardat)

{

unsignedinti,j;

for(j=0;j<8;j++)

{

DSPORT=0;//每写入一位数据之前先把总线拉低1us

i++;

DSPORT=dat&0x01;//然后写入一个数据,从最低位开始

i=6;

while(i--);//延时68us,持续时间最少60us

DSPORT=1;//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值

dat>>=1;

}

}

/*******************************************************************************

*函数名:

Ds18b20ReadByte

*函数功能:

读取一个字节

*输入:

com

*输出:

*******************************************************************************/

unsignedcharDs18b20ReadByte()

{

unsignedcharbyte,bi;

unsignedinti,j;

for(j=8;j>0;j--)

{

DSPORT=0;//先将总线拉低1us

i++;

DSPORT=1;//然后释放总线

i++;

i++;//延时6us等待数据稳定

bi=DSPORT;//读取数据,从最低位开始读取

/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。

*/

byte=(byte>>1)|(bi<<7);

i=4;//读取完之后等待48us再接着读取下一个数

while(i--);

}

retu

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2