DDC单回路PID闭环控制系统的设计及实时仿真课程设计报告.docx
- 文档编号:7743155
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:25
- 大小:84.23KB
DDC单回路PID闭环控制系统的设计及实时仿真课程设计报告.docx
《DDC单回路PID闭环控制系统的设计及实时仿真课程设计报告.docx》由会员分享,可在线阅读,更多相关《DDC单回路PID闭环控制系统的设计及实时仿真课程设计报告.docx(25页珍藏版)》请在冰豆网上搜索。
DDC单回路PID闭环控制系统的设计及实时仿真课程设计报告
课程设计(综合实验)报告
(2011--2012年度第二学期)
名称:
过程计算机控制系统
题目:
DDC单回路PID闭环控制系统的设计及实时仿真
院系:
控制与计算机工程学院
班级:
学号:
学生姓名:
指导教师:
朱耀春
设计周数:
一周
成绩:
日期:
2012年6月20日
一、课程设计的目的与要求
1.设计目的
在计算机控制系统课程学习的基础上,加强学生的实际动手能力,通过对DDC直接数字闭环控制的仿真加深对课程内容的理解。
2.设计要求
本次课程设计通过多人合作完成DDC直接数字闭环控制的仿真设计,学会A/D、D/A转换模块的使用。
通过手动编写PID运算式掌握数字PID控制器的设计与整定的方法,并做出模拟计算机对象飞升特性曲线,熟练掌握DDC单回路控制程序编制及调试方法。
二、设计正文
1.设计思想
本课程设计利用Turboc2.1开发环境,通过手动编写C语言程序完成PID控制器的设计,A/D、D/A转换,绘出PID阶跃响应曲线与被控对象动态特性曲线。
整个设计程序模块包含了PID配置模块,PLCD-780定时采样、定时输出模块,PID手/自动切换模块(按键控制)及绘图显示模块。
设计中,通过设定合理的PID参数,控制PLCD-780完成模拟计算机所搭接二阶惯性环节数据的采集,并通过绘图程序获得对象阶跃响应曲线。
2.设计步骤
(1)前期准备工作
(1.1)配备微型计算机一台,系统软件Windows98或DOS(不使用无直接I/O能力的NT或XP系统),内装TurboC2.0/3.0集成开发环境软件;
(1.2)配备模拟计算机一台(XMN-1型),通用数据采集控制板一块(PLCD-780型);
(1.3)复习Turboc2.0并参照说明书学习PLCD-780的使用
(2)PID的设计
(2.1)PID的离散化
理想微分PID算法的传递函数形式为:
采用向后差分法对上式进行离散,得出其差分方程形式为:
u[k]=u[k-1]+q0*e[2]+q1*e[1]+q2*e[0];
其中各项系数为:
q0=kp*(1+T/Ti+Td/T);
q1=-kp*(1+2*Td/T);
q2=kp*Td/T;
实际微分PID算法的传递函数形式为:
采用向后差分法对上式进行离散化,写成差分方程的形式为:
u[k]=c0*(Δu[k-1])+c1*e[k]+c2*e[k-1]+c3*e[k-2]+u[k-1];
其中各项系数为:
c0=Tf/(T+Tf);
c1=kp*T/(T+Tf)*(1+T/Ti+Td/T);
c2=-kp*T/(T+Tf)*(1+2*Td/T);
c3=kp*Td/(T+Tf);
(2.2)数字PID算法的改进
积分分离算法
积分分离算法通过控制PID输入偏差e达到优化目的,当偏差较大时停止积分作用,只有当偏差较小时才投入积分,算法如下表示:
当|e(k)|>β时,采用PD控制;
当|e(k)|<β时,采用PID控制;
β的值根据具体对象及要求确定。
抗积分饱和算法
抗积分饱和算法依据控制系统最终的控制输出量u达到优化目的,当控制量u较大且超出执行机构与A/D转换范围时,控制器停止积分作用,保证输出超限时不积分;
带死区的数字PID算法
在实际控制系统中,计算机控制为了避免控制动作过于频繁,以消除系统振荡,就会采用带死区的PID算法。
该算法是在原PID算法前加一个不灵敏区来实现,即
当|e(k)|>C时,|e(k)|=|e(k)|;
当|e(k)| 其中C代表不灵敏区值; (2.3)手动/自动双向无扰切换 自动切手动: 系统处于自动时,手操器实时跟踪自动PID调节器的输出,切换瞬间由于手操器内部电路起保持作用,使得切换没有扰动产生,此时对象处于手操器的开环控制,调节器跟踪手操器的输出。 手动切自动: 手动到自动的切换过程主要由计算机软件实现,一方面PID调节器获得手操器输出,同时软件使得算法中的Δu[k-1])、e[k]、e[k-1]、e[k-2]等历史状态清零。 程序中通过设置键盘,使的按下手动键H时,系统处于手动状态,按下自动键A时,系统处于自动状态。 (3)硬件二阶惯性环节搭建 利用模拟计算机中的电容电阻及运算放大器,搭接二阶惯性环节,仿真一个被控对象。 其传递函数为 ,硬件电路如下: 图中各元件参数如下: R3=R2=510K;R1=R4=R5=R6=R7=1M;C1=C2=C=4.7uF; 则可得: K=(R5/R1)*(R6/R4)=1 T1=T2=R5*C1=R6*C2=1000000*0.0000047=4.7s 所以G(s)=1/(4.7s+1)*(4.7s+1) 搭建好硬件电路后,将PLCD-780插入IPC机箱插槽,用导线将PLCD-780中的A/D、D/A、电源的接线端子与所搭二阶惯性环节的输出、输入端口及机箱上的电源连接,组成一个完整的PID闭环控制系统,为通信做好准备。 (4)PID参数的整定8.75,6.6*1.2,6.6*04 运用过程控制中PID参数的工程整定方法,运用衰减曲线法对PID参数进行整定。 在matlab中,设置PID参数为Td=0,Ti= ,设置合适的比例带使得对象闭环阶跃响应曲线衰减率为0.9,从而确定PID的整定参数为: P=0.8 ,Ti=1.2tr,Td=0.4tr; matlab中对象响应曲线为: 由曲线可得PID参数为: P=0.8 =0.8×5=4,Ti=1.2tr=1.2×10=12,Td=0.4tr=0.4×10=4 (5)实验结果输出 通过在程序中编写相应的绘图模块子程序,在需要画图时调用相应的子程序实现曲线的绘制。 同时在程序中,本小组采用按键实现了PID手自动切换,理想PID与实际PID的切换,以及在手自动状态下由按键改变PID参数,使得调节方式更加的灵活。 3.设计结果 (1)PID阶跃响应曲线 调用程序,向PID模块输入一个阶跃信号,绘出PID阶跃响应曲线如下: (1.1)理想PID阶跃响应图: (1.2)实际PID阶跃响应图: (2)被控对象(惯性环节)阶跃响应曲线 上图通过D/A输出一个1伏左右的信号输入模拟的被控对象(惯性环节),A/D采集对象的输入信号及其响应,再使D/A输出一个幅度为2伏左右的阶跃信号,同时采集输入输出信号。 然后,D/A再反向在输出一个幅度为2伏左右负的阶跃信号,同时采集输入输出信号,得出仿真对象飞升特性曲线。 程序中,通过按键实现模拟对象输入信号的加减。 当按下H按键时,且按下U键时,D/A输出一个1伏阶跃信号,再次按下按键时阶跃信号累加。 每次按下D键时,D/A输出的阶跃信号递减1。 (3)设定值r、控制量u和被控对象输出y的响应曲线: 4.程序清单 /*---------------头文件定义---------------*/ #include #include #include #include /*---------------定义绘图坐标---------------*/ #defineox8/*-----原点横坐标-------*/ #defineoy440/*------原点纵坐标------*/ #definexx620/*------x轴顶点横坐标--*/ #definexy440/*-----x轴顶点纵坐标---*/ #definelenx580 #defineleny400 #defineyx8/*-----y轴顶点横坐标----*/ #defineyy15/*------y轴顶点纵坐标----*/ /*-----------------定义绘图区域----------------*/ #defineleft20 #definetop20 #defineright620 #definebottom460 /*----------------坐标轴注释---------------------*/ #definextext1x450 #definextext1y450 #defineytext1x10 #defineytext1y60 #definextext2x610 #definextext2y450 #defineytext2x10 #defineytext2y20 /*-------------------------理想PID运算式--------------------------*/ floatlxpid(floatkp,floattd,floatti,floate[3],floatu1) { intt=1; floatu; floatq0=kp*(1+t/ti+td/t); floatq1=-kp*(1+2*td/t); floatq2=kp*td/t; u=q0*e[0]+q1*e[1]+q2*e[2]+u1; returnu; } /*-------------------------实际PID运算式--------------------------*/ floatsjpid(floatkp,floattf,floattd,floatti,floate[3],floatdu1,floatu1) { intt=1,k=1000; floatu2; floatc1=tf/(t+tf); floatc2=kp*t*(1+t/ti+td/t)/(t+tf); floatc3=-kp*t*(1+2*td/t)/(t+tf); floatc4=kp*td/(t+tf); u2=c1*du1+c2*e[0]+c3*e[1]+c4*e[2]+u1; returnu2; } /*-------------------------绘图初始化--------------------------*/ voidInitial_Sys(void) { intGraphDriver; intGraphMode; detectgraph(&GraphDriver,&GraphMode); initgraph(&GraphDriver,&GraphMode,"C: \\TC201E\\BGI"); cleardevice(); } /*-------------------------绘制坐标系------------------*/ voidDrawAxis(void) { inti; setbkcolor(15); setcolor(5); line(ox,oy,xx,xy);/*x_axis*/ line(xx-5,xy-5,xx,xy); line(xx,xy,xx-5,xy+5); line(ox,oy,yx,yy);/*y_axis*/ line(yx-5,yy+10,yx,yy); line(yx+5,yy+10,yx,yy); for(i=0;i<51;i++) { line(ox+10*i,oy,ox+10*i,oy-10); line(ox+10*i+5,oy,ox+10*i+5,oy-5); } for(i=1;i<=8;i++) line(ox,oy-50*i,ox+10,oy-50*i); outtextxy(ox+50*0-7,oy+20,"0"); outtextxy(ox+50*1-7,oy+20,"5"); outtextxy(ox+50*2-7,oy+20,"10"); outtextxy(ox+50*3-7,oy+20,"15"); outtextxy(ox+50*4-7,oy+20,"20"); outtextxy(ox+50*5-7,oy+20,"25"); outtextxy(ox+50*6-7,oy+20,"30"); outtextxy(ox+50*7-7,oy+20,"35"); outtextxy(ox+50*8-7,oy+20,"40"); outtextxy(ox+50*9-7,oy+20,"45"); outtextxy(ox+50*10-7,oy+20,"50"); outtextxy(ox-10,oy-50*1,"1"); outtextxy(ox-10,oy-50*2,"2"); outtextxy(ox-10,oy-50*3,"3"); outtextxy(ox-10,oy-50*4,"4"); outtextxy(ox-10,oy-50*5,"5"); outtextxy(ox-10,oy-50*6,"6"); outtextxy(ox-10,oy-50*7,"7"); outtextxy(ox-10,oy-50*8,"8"); settextstyle(SMALL_FONT,HORIZ_DIR,5); outtextxy(xtext1x,xtext1y,"Time"); outtextxy(xtext2x,xtext2y,"t\/s"); settextstyle(SMALL_FONT,VERT_DIR,5); outtextxy(ytext1x,ytext1y,"Theoutput(Response)"); outtextxy(ytext2x,ytext2y,"U(t)\/V"); } main() { floatkp,ti,td,tf,e[3]={0},ee[3]={0},u[6]={0},au1=0; intr=1,k=1; Initial_Sys(); DrawAxis(); while(k<100) { u[0]=lxpid(1,3.0,10,e,u[1]); e[0]=r; /*printf("%f\n",u[0]);*/ u[3]=sjpid(1,5,3.0,10,ee,au1,u[4]); setcolor(5); line((k-1)*10,130-u[1]*100,k*10,130-u[1]*100); line(k*10,130-u[1]*100,k*10,130-u[0]*100); delay(10000); u[2]=u[1]; u[1]=u[0]; e[2]=e[1]; e[1]=e[0]; ee[0]=r; setcolor(3); line((k-1)*10,150-u[4]*100,k*10,150-u[4]*100); line(k*10,150-u[4]*100,k*10,150-u[3]*100); delay(10000); u[5]=u[4]; u[4]=u[3]; ee[2]=ee[1]; ee[1]=ee[0]; au1=u[4]-u[5]; k++; } } /*---------------头文件定义---------------*/ #include"stdio.h" #include"math.h" #include"graphics.h"/*forgraphdriverinstalling,onlycanbecalledinTurboC*/ #include"string.h" #include"dos.h" #include"bios.h" #include"conio.h"/*forinterruptprogram头文件定义*/ #include"stdlib.h" #include"io.h" /*--------------按键地址区定义--------------------*/ /*statements*/ doublekey_ESC=0x011b;/*definecannotsuitthelengthofbioskey键盘内存定义*/ doublekey_E=0x1265; doublekey_A=0x1e61; doublekey_H=0x2368; doublekey_U=0x1675; doublekey_D=0x2064; doublekey_I=0x1769; doublekey_P=0x1970; doublekey_up=0x4800; doublekey_down=0x5000; doublekey_left=0x4b00; doublekey_right=0x4d00; doublekey_pgup=0x4900; doublekey_pgdown=0x5100; /*--------------PLCD780基址定义--------------------*/ #defineBASE0x220/*------------PCL812Gneed16addressesinarow,from220Hto3F0H*/ #defineREG0 /*---------------定义绘图坐标---------------*/ #defineox40/*------------原点横坐标-------------*/ #defineoy440/*------------原点纵坐标------------*/ #definexx600/*------------x轴顶点横坐标--------*/ #definexy440/*------------x轴顶点纵坐标--------*/ #defineyx40/*------------y轴顶点横坐标--------*/ #defineyy40/*------------y轴顶点纵坐标---------*/ /*---------------PID参数定义---------------*/ floatKp=1.0; floatTi=10.0; floatTd=3.0; floatTf0=15.0; floatTf=0; floatT=0.1;/*---------------采样时间------------*/ floatad,e,pv0; floatu=0.0; floatpv=0.0; floatsp=0.0; charA_H='H'; charmanu; intkey=0; inttime_counter=0;/*timesofinterrupt*/ intcj_counter=0;/*samplingcounter*/ intQ_counter=800;/*采集步长赋初始值*/ intstepdata[800]; intslopedata[800]; interror[800]; /*--------------函数声明-----------------*/ voidinterrupt(*fadd1C)(void); voidloop(); floatAD(unsignedcharchannal);/*A/D*/ voidDA(floatpv1);/*D/A*/ voidinterruptINT_1C(void);/*8259,resetinterruptcontroller*/ intscankey(); floatDelayAction(floaty0); voidPIDset(void); floatPID(floatsp1,floatpv1,floatKp1,floatTi1,floatTd1,floatTf1,charA_H1,floatT1); floatObject(floatu1,floatT1); voidInitial_Sys(void);/*Initiategraphdisplay*/ voidaxis(void); voidDrawline(intcj,floatpv1,floatsp1,floatu1,floate1); /*主函数*/ voidmain(void) { inti; for(i=0;i<500;i++) {stepdata[i]=10;slopedata[i]=i;error[i]=0;} /*SetnewINT_1Candsaveold*/ disable(); fadd1C=getvect(0x1C);/*1C为定时器控制的软中断,平均一秒发生18.2次,即周期为55ms中断程序*/ /*开启中断服务*/ setvect(0x1C,INT_1C); enable(); axis(); loop(); } /*主函数结束下面为定时采值输出程序*/ voidloop() {do { if((cj_counter*T)<(time_counter/18.2)) { PIDset();/*Introduction: Exit-E/ESC,A_H-A/H,Ideal/ParallelPID,sp-U/D*/ u=PID(sp,pv,Kp,Ti,Td,Tf,A_H,T); /*DA(u);*/ pv=Object(u,T); /*ad=AD(O);*/ /*pv=DelayAction(u);*/ e=error[cj_counter]; Drawline(cj_counter,pv,sp,u,e); manu=0; /*statusbar,atthetopofthescreen--------------howtoexpress%.2f*/ if(Tf==0) printf("IdealPID,Mode: %c,sp=%.1f,pv=%2.1f,u=%.1f,error=%.1f,Kp=%.1f,Ti=%.1f,Td=%.1f\t\r",A_H,sp,pv,u,e,Kp,Ti,Td); elseif(Tf>0) printf("Parallal,Mode: %c,sp=%.1f,pv=%2.1f,u=%.1f,error=%.1f,Kp=%.1f,Ti=%.1f,Td=%.1f\t\r",A_H,sp,pv,u,e,Kp,Ti,Td); elseprintf("\t\tTfgotawrongvalue! Pleaseexitandrestartth
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DDC 回路 PID 闭环控制 系统 设计 实时 仿真 课程设计 报告