DDC单回路PID闭环控制系统的设计及实时仿真课程设计.doc

上传人:仙人指路1688 文档编号:2931743 上传时间:2023-03-03 格式:DOC 页数:27 大小:160.50KB
返回 下载 相关 举报
DDC单回路PID闭环控制系统的设计及实时仿真课程设计.doc_第1页
第1页 / 共27页
DDC单回路PID闭环控制系统的设计及实时仿真课程设计.doc_第2页
第2页 / 共27页
DDC单回路PID闭环控制系统的设计及实时仿真课程设计.doc_第3页
第3页 / 共27页
DDC单回路PID闭环控制系统的设计及实时仿真课程设计.doc_第4页
第4页 / 共27页
DDC单回路PID闭环控制系统的设计及实时仿真课程设计.doc_第5页
第5页 / 共27页
点击查看更多>>
资源描述

《DDC单回路PID闭环控制系统的设计及实时仿真课程设计.doc》由会员分享,可在线阅读,更多相关《DDC单回路PID闭环控制系统的设计及实时仿真课程设计.doc(27页珍藏版)》请在三一办公上搜索。

1、课程设计(综合实验)报告( 2011- 2012 年度第 二学期)名 称: 过程计算机控制系统 题 目:DDC单回路PID闭环控制系统的设计及实时仿真院 系: 控制与计算机工程学院 班 级: 自动0905 学 号: 学生姓名: 指导教师: 朱耀春 设计周数: 一周 成 绩: 日期:2012 年 6 月 20 日一、 课程设计的目的与要求1.设计目的在计算机控制系统课程学习的基础上,加强学生的实际动手能力,通过对DDC直接数字闭环控制的仿真加深对课程内容的理解。2.设计要求本次课程设计通过多人合作完成DDC直接数字闭环控制的仿真设计,学会A/D、D/A转换模块的使用。通过手动编写PID运算式掌握

2、数字PID控制器的设计与整定的方法,并做出模拟计算机对象飞升特性曲线,熟练掌握DDC单回路控制程序编制及调试方法。二、 设计正文1.设计思想 本课程设计利用Turboc2.1开发环境,通过手动编写C语言程序完成PID控制器的设计,A/D、D/A转换,绘出PID阶跃响应曲线与被控对象动态特性曲线。整个设计程序模块包含了PID配置模块,PLCD-780定时采样、定时输出模块,PID手/自动切换模块(按键控制)及绘图显示模块。设计中,通过设定合理的PID 参数,控制PLCD-780完成模拟计算机所搭接二阶惯性环节数据的采集,并通过绘图程序获得对象阶跃响应曲线。 2. 设计步骤(1)前期准备工作 (1

3、.1)配备微型计算机一台,系统软件Windows 98或DOS (不使用无直接I/O能力的NT或XP系统), 内装Turbo C 2.0/3.0集成开发环境软件;(1.2)配备模拟计算机一台(XMN-1型), 通用数据采集控制板一块(PLCD-780型);(1.3)复习Turboc2.0并参照说明书学习PLCD-780的使用(2) PID的设计(2.1)PID的离散化理想微分PID算法的传递函数形式为:采用向后差分法对上式进行离散,得出其差分方程形式为:uk=uk-1+q0*e2+q1*e1+q2*e0;其中各项系数为:q0=kp*(1+T/Ti+Td/T); q1=-kp*(1+2*Td/T

4、); q2=kp*Td/T;实际微分PID算法的传递函数形式为:采用向后差分法对上式进行离散化,写成差分方程的形式为: uk=c0*(uk-1)+c1*ek+c2*ek-1+c3*ek-2+uk-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)|

5、C时,|e(k)|=|e(k)|; 当|e(k)|C时,|e(k)|=0 其中C代表不灵敏区值;(2.3) 手动/自动双向无扰切换自动切手动:系统处于自动时,手操器实时跟踪自动PID调节器的输出,切换瞬间由于手操器内部电路起保持作用,使得切换没有扰动产生,此时对象处于手操器的开环控制,调节器跟踪手操器的输出。手动切自动:手动到自动的切换过程主要由计算机软件实现,一方面PID调节器获得手操器输出,同时软件使得算法中的uk-1)、ek、ek-1、ek-2等历史状态清零。 程序中通过设置键盘,使的按下手动键H时,系统处于手动状态,按下自动键A时,系统处于自动状态。(3)硬件二阶惯性环节搭建利用模拟计

6、算机中的电容电阻及运算放大器,搭接二阶惯性环节,仿真一个被控对象。其传递函数为,硬件电路如下:图中各元件参数如下: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闭环控制系统,为通信做好准备。

7、(4)PID参数的整定运用过程控制中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.85=4,Ti=1.2tr=1.210=12 ,Td=0.4tr=0.410=4(5)实验结果输出通过在程序中编写相应的绘图模块子程序,在需要画图时调用相应的子程序实现曲线的绘制。同时在程序中,本小组采用按键实现了PID手自动切换,理想PID

8、与实际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伏左右负的阶跃信号,同时采集输入输出信号,得出仿真对象飞升特性曲线。程序中,通过按键实现模拟对象输入信

9、号的加减。当按下H按键时,且按下U键时,D/A输出一个1伏阶跃信号,再次按下按键时阶跃信号累加。每次按下D键时,D/A输出的阶跃信号递减1。(3)设定值r、控制量u和被控对象输出y的响应曲线:4.程序清单/*-头文件定义-*/ #include #include #include #include /*-定义绘图坐标-*/ #define ox 8 /*-原点横坐标-*/ #define oy 440 /*-原点纵坐标-*/ #define xx 620 /*-x轴顶点横坐标-*/ #define xy 440 /*-x轴顶点纵坐标-*/ #define lenx 580 #define le

10、ny 400 #define yx 8 /*-y轴顶点横坐标-*/ #define yy 15 /*-y轴顶点纵坐标-*/ /*-定义绘图区域-*/ #define left 20 #define top 20 #define right 620 #define bottom 460 /*-坐标轴注释-*/ #define xtext1x 550 #define xtext1y 450 #define ytext1x 10 #define ytext1y 60 #define xtext2x 610 #define xtext2y 450 #define ytext2x 10 #define

11、ytext2y 20/*-理想PID运算式-*/float lxpid(float kp,float td,float ti,float e3,float u1) int t=1; float u; float q0=kp*(1+t/ti+td/t); float q1=-kp*(1+2*td/t); float q2=kp*td/t; u=q0*e0+q1*e1+q2*e2+u1; return u; /*-实际PID运算式-*/float sjpid(float kp,float tf,float td,float ti,float e3,float du1,float u1) int t

12、=1,k=1000; float u2; float c1=tf/(t+tf); float c2=kp*t*(1+t/ti+td/t)/(t+tf); float c3=-kp*t*(1+2*td/t)/(t+tf); float c4=kp*td/(t+tf); u2=c1*du1+c2*e0+c3*e1+c4*e2+u1; return u2; /*-绘图初始化-*/void Initial_Sys(void) int GraphDriver; int GraphMode; detectgraph(&GraphDriver,&GraphMode); initgraph(&GraphDri

13、ver,&GraphMode,C:TC201EBGI); cleardevice(); /*-绘制坐标系-*/void DrawAxis(void) int i; 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;i51;i+) line(ox+10*i,oy,ox+

14、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,

15、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,

16、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,The output (Response); outtextxy(ytext2x,ytext2y,U(t)/V);main() float kp,t

17、i,td,tf,e3=0,ee3=0,u6=0,au1=0; int r=1,k=1; Initial_Sys(); DrawAxis(); while(k100) u0=lxpid(1,3.0,10,e,u1); e0=r; /*printf(%fn,u0);*/ u3=sjpid(1,5,3.0,10,ee,au1,u4); setcolor(5); line(k-1)*10,130-u1*100,k*10,130-u1*100); line(k*10,130-u1*100,k*10,130-u0*100); delay(10000); u2=u1; u1=u0; e2=e1; e1=e0

18、; ee0=r; setcolor(3); line(k-1)*10,150-u4*100,k*10,150-u4*100); line(k*10,150-u4*100,k*10,150-u3*100); delay(10000); u5=u4; u4=u3; ee2=ee1; ee1=ee0; au1=u4-u5; k+;/*-头文件定义-*/#include stdio.h#include math.h#include graphics.h/*for graph driver installing,only can be called in Turbo C*/#include string

19、.h#include dos.h#include bios.h#include conio.h/*for interrupt program 头文件定义* /#include stdlib.h#include io.h/*-按键地址区定义-*/*statements*/double key_ESC=0x011b;/*define can not suit the length of bioskey 键盘内存定义*/double key_E=0x1265;double key_A=0x1e61;double key_H=0x2368;double key_U=0x1675;double key_

20、D=0x2064;double key_I=0x1769;double key_P=0x1970;double key_up=0x4800;double key_down=0x5000;double key_left=0x4b00;double key_right=0x4d00;double key_pgup=0x4900;double key_pgdown=0x5100;/*-PLCD780基址定义-*/#define BASE 0x220/*-PCL812G need 16 addresses in a row,from 220H to 3F0H*/#define REG 0/*-定义绘图

21、坐标-*/#define ox 40/*-原点横坐标-*/#define oy 440 /*-原点纵坐标-*/#define xx 600/*-x轴顶点横坐标-*/#define xy 440/*-x轴顶点纵坐标-*/#define yx 40/*-y轴顶点横坐标-*/#define yy 40/*-y轴顶点纵坐标-*/*-PID参数定义-*/float Kp=1.0;float Ti=10.0;float Td=3.0;float Tf0=15.0;float Tf=0; float T=0.1; /*-采样时间-*/float ad,e,pv0;float u=0.0;float pv=0

22、.0;float sp=0.0;char A_H=H;char manu;int key=0;int time_counter=0;/*times of interrupt中断的次数*/int cj_counter=0;/*sampling counter采样次数*/int Q_counter=800;/* 采集步长 赋初始值*/int stepdata800;int slopedata800;int error800;/*-函数声明 -*/void interrupt (*fadd1C)(void); /*中断函数声明*/void loop(); /*定值采样输出程序声明*/float AD

23、(unsigned char channal);/*A/D*/void DA(float pv1);/*D/A*/void interrupt INT_1C(void);/*8259,reset interrupt controller*/int scankey();float DelayAction(float y0); /*延迟*/void PIDset(void);/*pid设置声明*/float PID(float sp1,float pv1,float Kp1,float Ti1,float Td1,float Tf1,char A_H1,float T1);/*pid计算声明*/f

24、loat Object(float u1,float T1); /*二阶惯性环节声明*/void Initial_Sys(void);/*Initiate graph display*/void axis(void);void Drawline(int cj,float pv1,float sp1,float u1,float e1);/*主函数*/void main(void)int i;for(i=0;i500;i+)stepdatai=10;slopedatai=i;errori=0; /* Set new INT_1C and save old */disable(); /*屏蔽中断*

25、/fadd1C=getvect(0x1C);/*1C为定时器控制的软中断,平均一秒发生18.2次,即周期为55ms 中断程序,getvect用于取得中断向量入口*/* 开启中断服务*/setvect(0x1C,INT_1C);/*设置中断矢量入口*/enable();axis(); /*画坐标轴*/loop(); /*定时采值输出程序*/*主函数结束 下面为定时采值输出程序*/void loop() doif(cj_counter*T)0)printf(Parallal,Mode:%c,sp=%.1f,pv=%2.1f,u=%.1f,error=%.1f,Kp=%.1f,Ti=%.1f,Td=

26、%.1ftr,A_H,sp,pv,u,e,Kp,Ti,Td);else printf(ttTf got a wrong value! Please exit and restart this program.r);cj_counter+;while(cj_counter500);disable();/* 恢复中断*/setvect(0x1C,fadd1C);enable();/*D/A conversion program,0 to 4095 - 0to +5*/float AD(unsigned char channal)float result=0;int i;unsigned char

27、hb=0,lb=0,ok=0x10;/*12bit AD/high 4 bits and low 8 bits*/outportb(BASE+11,REG);/*软件程序触发*/delay(10); /*here,delay(int ms) is used long before,and we just need some time for hardware working*/outportb(BASE+10,channal);/*进行通道设置.选择通道0*/delay(10);outportb(BASE+9,1); /*设置增益通道增益*/delay(10);outportb(BASE+12

28、,0);/*触发A/D转换*/delay(10); dook=inportb(BASE+5);while(ok&0x10);hb=inportb(BASE+5);delay(10);lb=inportb(BASE+4);result = lb + (hb&0x0F)5) /* make the output real */ pv1=5; else if (pv10) pv1=0; temp=(int)(4095*pv1/5.0); hb=temp8; lb=temp-(hb8); outportb(BASE,1); delay(10); outportb(BASE+4,lb); /* low

29、8 */ delay(10); outportb(BASE+5,hb); /* high 4 */void interrupt INT_1C(void)time_counter+;outportb(0x20,0x20); /*键盘控制*/int scankey(void)int key0;key0=bioskey(1);/* function 1 returns 0 until a key is pressed */if(key0!=0)key0=bioskey(0);/* function 0 returns the key that is waiting */return key0;/*D

30、elayAction*/*tao=(int)(18.2*2) Delay action=2 seconds*/float DelayAction(float y0)float y_out;static float y_old36=0;int cyc;y_out=y_old36-1;for(cyc=1;cyc36;cyc+)y_old36-cyc=y_old36-cyc-1;y_old0=y0;return y_out;/*PID 主程序*/void PIDset(void)key=scankey();if(A_H=H)if(key=key_up)Kp+=0.2;else if(key=key_

31、down)Kp-=0.2;else if(key=key_left)Ti-=0.2;else if(key=key_right)Ti+=0.2;else if(key=key_pgup)Td+=0.2;else if(key=key_pgdown)Td-=0.2;else if(key=key_U)manu=+;else if(key=key_D)manu=-;if(A_H=A)if(key=key_U)sp+=10;if(key=key_D)sp-=10;if(key=key_E|key=key_ESC)exit(1);if(key=key_A)A_H=A;if(key=key_H)A_H=

32、H;if(key=key_I)Tf=0;if(key=key_P)Tf=Tf0;/*PID-default:IdealPID*/float PID(float sp1,float pv1,float Kp1,float Ti1,float Td1,float Tf1,char A_H1,float T1)float delta_u,u0,e,C1,C2,C3,C4;static float e1,e2,u1,delta_u1;/*here,u1 stands for the previous value of u*/if(Kp10)printf(Kp becomes a negative nu

33、mber,please restart.);else if(Ti10) printf(Ti becomes a negative number,please press restart.);else if(Td10) printf(Td becomes a negative number,please press restart.);elseC1=Tf1/(T1+Tf1);C2=Kp1*T1*(1+T1/Ti1+Td1/T1)/(T1+Tf1);C3=-Kp1*T1*(1+2*Td1/T1)/(T1+Tf1);C4=Kp1*Td1/(T1+Tf1);/*自动控制*/if(A_H1=A)e=sp

34、1-pv1;delta_u=C1*delta_u1+C2*e+C3*e1+C4*e2;/*here,delta_u1 stands for the previous value of delta_u*/u0=u1+delta_u; e2=e1;e1=e;delta_u1=delta_u;u1=u0;errorcj_counter=sp1-pv1;return u0;/*手动控制*/else if(A_H1=H)if(manu=+)u+=10;if(manu=-)u-=10;sp1=pv1;u1=u;sp=pv1;e1=0;e2=0;delta_u1=0;errorcj_counter=sp1-pv1;return u;/*object:二阶惯性环节*/float Obje

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

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号