当前位置:文档之家› 《计算机控制技术》课程结业论文

《计算机控制技术》课程结业论文

《计算机控制技术》课程结业论文专业:电气工程及自动化年级:2009级班级:电气5班姓名:余刚学号:200940735252012年06月21 日摘要采用AT89S51单片机作为控制核心,将增量式PID算法和PWM脉宽调制技术相结合,通过光耦控制双向晶闸管导通角的大小实现热水器的恒温控制。

解决了传统的电热水器用冷热水闸门调节温度出现的温度不稳定,不易调节的缺点。

关键词:PID算法单片机脉宽调制电热水器目录摘要 (I)1引言 (1)2 系统的硬件组成与设计 (2)2.1系统的硬件组成 (2)2.2系统硬件设计 (2)3 系统软件设计 (4)3.1增量式PID控制算法 (4)3.2软件设计 (4)结论 (5)参考文献 (6)致谢 (7)附录 (8)1引言在工程实际中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。

PID控制器问世至今已有近70年历史,它以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。

当被控对象的结构和参数不能完全掌握,或得不到精确的数学模型时,控制理论的其它技术难以采用时,系统控制器的结构和参数必须依靠经验和现场调试来确定,这时应用PID控制技术最为方便。

即当我们不完全了解一个系统和被控对象,或不能通过有效的测量手段来获得系统参数时,最适合用PID控制技术。

PID控制,实际中也有PI和PD控制。

PID控制器就是根据系统的误差,利用比例、积分、微分计算出控制量进行控制的。

针对传统的电热水器用冷热水闸门调节温度出现的温度不稳定,不易调节的缺点,本文设计了以AT89S51单片机作为控制核心,将PID算法和PWM脉宽调制技术相结合,通过光耦来控制双向可控硅导通角的大小来实现热水器的恒温控制的控制系统。

2 系统的硬件组成与设计2.1系统的硬件组成本系统由单片机控制系统、前向通道、后向通道、人机对话通道4个主要的功能模块组成,总体框图如图1所示。

2.2系统硬件设计2.2.1前向通道设计前向通道是信息采集的通道,主要包括温度传感器、信号放大、A/D 转换电路组成的信号采集电路和以单片机为核心的信号处理电路。

水温经温度传感器和信号放大电路产生0~5V 的模拟电压信号送入A/D 转换器,将模拟量转换为数字量通过系统总线送入单片机进行运算处理,电路原理图分别如图2、图3所示。

图1 本系统的总体功能结构图AD581图中温度传感器采用AD590将温度变换为电流,与运算放大器OP07和电阻R1、VRl、R2、VR2组成信号转换与放大电路,将温度转换为电压信号。

采用ADC0804把电压信号转换为数字信号输送到单片机。

2.2.2后向通道设计后向通道是控制信号的输出通道,主要由功率放大电路、光电耦合电路、双向晶闸管、电热装置等组成,原理图如图4所示。

单片机输出的控制信号经光偶MOC3041控制双向可控硅BTA12的导通时间,从而实温度控制图4 后项通道原理图3 系统软件设计3.1增量式PID控制算法增量式PID控制算式为:Δu(k) = u(k) - u(k-1)= KC[e(k) - e(k-1)] + K1e(k) + KD[e(k) - 2e(k-1) + e(k-2)]= KCΔe(k) + K1e(k) + KDΔ2e(k)3.2软件设计系统软件由主程序、PID子程序、中断服务子程序、PWM波子程序组成。

主程序主要完成初始化、温度采集、处理和发送、PID子程序的调用。

PID算法子程序的作用为根据设定温度、实测温度和调节器系数KP、KI、KD计算变换量△Ui,并将变换量按比例转换为PWM波的时间来控制可控硅导通时间。

当键盘显示模块发送过来设定温度时,本模块能够进入串行口中断子程序,从而把设定温度保存起来。

PWM波输出子程序按PID运算结果,软件编写完成控制双向晶闸管的导通时间。

结论本文利用PID算法实现对电热水器的自动控制,温度分辨力可达0.1℃,具有自动化、智能化、易于操作、控制精度高、性价比高等特点。

参考文献[1] 吴麒.自动控制原理[M].北京:清华大学出版社,1997.[2] 张毅刚.51单片机应用设计I-M-t.哈尔滨:哈工大出版社,1990.[3] 何小艇.电子系统设计[M].杭州:浙江大学出版社,2004.[4] 韩志军.单片机应用系统设计[M].北京:机械工业出版社,2005.致谢论文的设计过程中,我查阅了许多有关温度控制系统设计方面的文献资料,使我对温度控制的设计和使用有了更深的认识。

从论文选题到完成论文,老师付出了大量的时间和心血,在设计过程中,老师从多方面进行指导,不断对论文提出修改意见。

在此,我要由衷地感谢……同时,我也要感谢给予我帮助的同学,在不懂的环节为我努力探讨。

论文的完成,不仅是我计算机控制知识积累的体现,而且也是信息技术学院所有老师悉心教导的结果,感谢他们让我掌握了一定的专业知识,专业技能和一些为人处世的道理。

最要感激父母,是他们给我学习的机会,并且在学业期间给我大力支持和为我付出。

附录PID部分程序:#include <reg52.h>#include <intrins.h>typedef unsigned char uint8;typedef unsigned int uint16;typedef unsigned long int uint32;/**********函数声明************/void PIDOutput();void PIDOperation();/*****************************/typedef struct PIDValue{uint32 Ek_Uint32[3]; //差值保存,给定和反馈的差值uint8 EkFlag_Uint8[3]; //符号,1负数,0正数uint8 KP_Uint8;uint8 KI_Uint8;uint8 KD_Uint8;uint16 Uk_Uint16; //上一时刻的控制电压uint16 RK_Uint16; //设定值uint16 CK_Uint16; //实际值}PIDValueStr;PIDValueStr PID;uint8 out ; // 加热输出uint8 count; // 输出时间单位计数器/*********************************PID = Uk + KP*[E(k)-E(k-1)]+KI*E(k)+KD*[E(k)-2E(k-1)+E(k-2)];(增量型PID算式)函数入口: RK(设定值),CK(实际值),KP,KI,KD函数出口: U(K)//PID运算函数********************************/void PIDOperation(void){uint32 Temp[3]; //中间临时变量uint32 PostSum; //正数和uint32 NegSum; //负数和Temp[0] = 0;Temp[1] = 0;Temp[2] = 0;PostSum = 0;NegSum = 0;if (PID.RK_Uint16 > PID.RK_Uint16) //设定值大于实际值否?{if (PID.RK_Uint16 - PID.RK_Uint16 > 10) //偏差大于10否?{_Uint16 = 100; //偏差大于10为上限幅值输出}else{Temp[0] = PID.RK_Uint16 - PID.CK_Uint16;//偏差<=10,计算E(k)PID.EkFlag_Uint8[1] = 0; //E(k)为正数PID.Ek_Uint32[2] = PID.Ek_Uint32[1]; //数值移位PID.Ek_Uint32[1] = PID.Ek_Uint32[0];PID.Ek_Uint32[0] = Temp[0];/****************************************/if (PID.Ek_Uint32[0] > PID.Ek_Uint32[1])//E(k)>E(k-1)否?{Temp[0] = PID.Ek_Uint32[0] - PID.Ek_Uint32[1];//E(k)>E(k-1)PID.EkFlag_Uint8[0] = 0;//E(k)-E(k-1)为正数}else{Temp[0] = PID.Ek_Uint32[0] - PID.Ek_Uint32[1];PID.EkFlag_Uint8[0] = 1; //E(k)-E(k-1)为负数}/****************************************/Temp[2] = PID.Ek_Uint32[1] * 2 ; // 2E(k-1)//E(k-2)+E(k)>2E(k-1)否?if ((PID.Ek_Uint32[0] + PID.Ek_Uint32[2]) > Temp[2]) {Temp[2] = (PID.Ek_Uint32[0]+ PID.Ek_Uint32[2]) - Temp[2];//E(k-2)+E(k)>2E(k-1)PID.EkFlag_Uint8[2] = 0;//E(k-2)+E(k)-2E(k-1)为正数}else{Temp[2] = Temp[2] - (PID.Ek_Uint32[0]+ PID.Ek_Uint32[2]);//E(k-2)+E(k)<2E(k-1)PID.EkFlag_Uint8[2] = 1;//E(k-2)+E(k)-2E(k-1)为负数}/****************************************/ Temp[0] = (uint32)PID.KP_Uint8 * Temp[0];Temp[1] = (uint32)PID.KI_Uint8 * PID.Ek_Uint32[0];// KI*E(k)Temp[2] = (uint32)PID.KD_Uint8 * Temp[2];// KD*[E(k-2)+E(k)-2E(k-1)]/*以下部分代码是讲所有的正数项叠加,负数项叠加*//**********KP*[E(k)-E(k-1)]**********/if (PID.EkFlag_Uint8[0] == 0){PostSum += Temp[0]; //正数和}else{NegSum += Temp[0]; //负数和}/********* KI*E(k)****************/if (PID.EkFlag_Uint8[1] == 0){PostSum += Temp[1]; //正数和}else{nop_(); //空操作,E(K)>0}/****KD*[E(k-2)+E(k)-2E(k-1)]****/if (PID.EkFlag_Uint8[2] == 0){PostSum += Temp[2]; //正数和}else{NegSum += Temp[2]; //负数和}/***************U(K)***************/PostSum += (uint32)_Uint16;if (PostSum > NegSum) // 是否控制量为正数{Temp[0] = PostSum - NegSum;if (Temp[0] < 100){_Uint16 = (uint16)Temp[0];//小于上限幅值则为计算值输出}else{_Uint16 = 100;//否则为上限幅值输出}}else{_Uint16 = 0;//控制量输出为负数,则输出0(下限幅值输出)}}}else{_Uint16 = 0;}}/*********************************函数入口: U(K)函数出口: out(加热输出)//PID运算植输出函数********************************/void PIDOutput(void){static int i;i = _Uint16;if (i == 0){out = 1;}else{out = 0;}if ((count++) == 5)//如定时中断为40MS,40MS*5=0.2S(输出时间单位),周期20S(100等份) {//每20S PID运算一次count = 0;i--;}}。

相关主题