华北电力大学过程计算机控制课设DDC串级回路PID闭环_第1页
华北电力大学过程计算机控制课设DDC串级回路PID闭环_第2页
华北电力大学过程计算机控制课设DDC串级回路PID闭环_第3页
华北电力大学过程计算机控制课设DDC串级回路PID闭环_第4页
华北电力大学过程计算机控制课设DDC串级回路PID闭环_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、课程设计报告名称:过程计算机控制题目: DDC串级回路PID闭环控制系统的设计及实时仿真院系:控计班级: 学号: 学生姓名: 同组人: 指导教师:李明扬设计周数:一周一、设计目的1. 学习并了解用高级语言(C语言)实现数字PID控制算法模块程序的方法;2. 比较验证理想微分PID和实际微分PID控制算法阶跃响应,加深对上述两种算法各自特点的认识;3. 学习了解用模拟计算机使用方法;4. 学习掌握A/D、D/A转换接口板的使用方法;5. 了解一种微机中断定时的方法;6. 学习掌握通过A/D、D/A转换用计算机获取被控对象动态特性的方法;7 通过实时仿真实验掌握DDC单回路控制程序编制及调试方法。

2、二、实验仪器(1)微型计算机一台,系统软件Windows 98或DOS (不能使用无直接I/O能力的NT或XP系统), 内装Turbo C 2.0/3.0集成开发环境软件;(2)模拟计算机一台(XMN-1型);(3)通用数据采集控制板一块(PCL-812PG型)。三、PID的离散化理想微分PID算法的传递函数形式为:采用向后差分法对上式进行离散,得出其差分方程形式为:uk=uk-1+q0*e2+q1*e1+q2*e0;其中各项系数为:q0=kp*(1+T/Ti+Td/T); q1=-kp*(1+2*Td/T); q2=kp*Td/T;实际微分PID算法的传递函数形式为:采用向后差分法对上式进行

3、离散化,写成差分方程的形式为: 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);四、硬件二阶惯性环节搭建利用模拟计算机中的电容电阻及运算放大器,搭接二阶惯性环节,仿真一个被控对象。其传递函数为,硬件电路如下:图中各元件参数如下:R3=R2=510K;R1=R4=R5=R6=R7=1M ;C1=C2=C=4.7uF;则可得:K=(R5/R1)*(R6/R4)=1 T1=T2=R

4、5*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闭环控制系统,为通信做好准备。五、实验结果(1)理想和实际PID阶跃响应曲线(2)被控对象(实物搭建二阶惯性环节)阶跃响应曲线上图通过D/A输出一个1伏左右的信号输入模拟的被控对象(惯性环节),A/D采集对象的输入信号及其响应,再使D/A输出一个幅度为2伏左右的阶跃信号,同时采集输入输出信号。

5、然后,D/A再反向在输出一个幅度为2伏左右负的阶跃信号,同时采集输入输出信号,得出仿真对象飞升特性曲线。程序中,通过按键实现模拟对象输入信号的加减。当按下H按键时,且按下U键时,D/A输出一个1伏阶跃信号,再次按下按键时阶跃信号累加。每次按下D键时,D/A输出的阶跃信号递减1。(3)根据对象单位阶跃响应曲线求增益和惯性时间:利用切线法求对象的增益和用一阶等效的惯性时间:如上图所示做拐点切线,得对象增益和一阶等效惯性时间分别为: Ti13s(4)手自动切换:(5)设定值r、控制量u和被控对象输出的阶跃响应曲线:程序清单 /*-头文件定义-*/   

6、0;  #include<conio.h>      #include<graphics.h>      #include <stdio.h>      #include <dos.h>/*-定义绘图坐标-*/       #define ox

7、0;8       /*-原点横坐标-*/          #define oy 440                /*-原点纵坐标-*/       #define

8、0;xx 620                /*-x轴顶点横坐标-*/       #define xy 440                /*-x轴顶点纵坐标-*/

9、60;      #define lenx 580       #define leny 400       #define yx 8                 &

10、#160; /*-y轴顶点横坐标-*/       #define yy 15                 /*-y轴顶点纵坐标-*/*-定义绘图区域-*/       #define left 20   

11、    #define top 20       #define right 620       #define bottom 460 /*-坐标轴注释-*/       #define xtext1x 450    &

12、#160;  #define xtext1y 450       #define ytext1x 10       #define ytext1y 60       #define xtext2x 610       #

13、define xtext2y 450       #define ytext2x 10       #define ytext2y 20/*-理想PID运算式-*/ float lxpid(float kp,float td,float ti,float e3,float u1)    i

14、nt t=1;       float u;       float q0=kp*(1+t/ti+td/t);       float q1=-kp*(1+2*td/t);       float q2=kp*td/t;     

15、  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=1;       

16、; 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);     

17、60;  float c4=kp*td/(t+tf);        u2=c1*du1+c2*e0+c3*e1+c4*e2+u1;        return u2; /*-绘图初始化-*/ void Initial_Sys(void)      int GraphDriver; 

18、60;      int GraphMode;        detectgraph(&GraphDriver,&GraphMode);        initgraph(&GraphDriver,&GraphMode,"C:TC201EBGI");     

19、0;cleardevice();  /*-绘制坐标系-*/ void DrawAxis(void)       int i;      setbkcolor(15);      setcolor(5);      line(ox,oy,xx,xy);     

20、    /*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,y

21、y);line(yx+5,yy+10,yx,yy);    for(i=0;i<51;i+)       /*-x轴刻度-*/          line(ox+10*i,oy,ox+10*i,oy-10);          line(ox+10*i+5,oy,ox+10*i+5,oy-5)

22、;             for(i=1;i<=8;i+)  /*-y轴刻度-*/      line(ox,oy-50*i,ox+10,oy-50*i);       outtextxy(ox+50*0-7,oy+20,"0");      

23、; 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

24、+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&q

25、uot;);  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-

26、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");     &

27、#160; outtextxy(ox-10,oy-50*8,"8");   /*坐标轴刻度标识*/   settextstyle(SMALL_FONT,HORIZ_DIR,5);     /*坐标轴标示字体 方向 大小*/outtextxy(xtext1x,xtext1y,"Time");outtextxy(xtext2x,xtext2y,"t/s");     settextstyle

28、(SMALL_FONT,VERT_DIR,5);    outtextxy(ytext1x,ytext1y,"The output (Response)");    outtextxy(ytext2x,ytext2y,"U(t)/V"); main()       float kp,ti,td,tf,e3=0,ee3=0,u6=0,au1=0;  

29、    int r=1,k=1;      Initial_Sys();      DrawAxis();      while(k<100)                  u0=

30、lxpid(1,3.0,10,e,u1);            e0=r;             u3=sjpid(1,5,3.0,10,ee,au1,u4); setcolor(5);            line(k-1

31、)*10,130-u1*100,k*10,130-u1*100);            line(k*10,130-u1*100,k*10,130-u0*100);            delay(10000);            

32、        u1=u0;            e2=e1;            e1=e0;            ee0=r;  

33、          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);      

34、0;     u5=u4;            u4=u3;            ee2=ee1;            ee1=ee0;    

35、        au1=u4-u5;            k+;  /*-头文件定义-*/ #include "stdio.h"  #include "math.h" #include "graphics.h"  #include

36、0;"string.h" #include "dos.h" #include "bios.h" #include "conio.h"    /*中断程序头文件定义*/#include "stdlib.h" #include "io.h"/*-按键地址区定义-*/ /*statements*/ double key_ESC=0x0

37、11b;   /*退出*/double key_E=0x1265;  double key_A=0x1e61;  /*自动*/double key_H=0x2368;  /*手动*/double key_U=0x1675;  /*自动时增SP,手动时增手操器输出*/double key_D=0x2064;  /*自动时减SP,手动时增手操器输出*/double key_I=0x1769;  /*理想PID*/double key_P=0x1970

38、; /*实际PID*/ double key_up=0x4800;  /*手动时,增Kp*/double key_down=0x5000;  /*手动时,减Kp*/double key_left=0x4b00; /*手动时,减Ti*/ double key_right=0x4d00;  /*手动时,增Ti*/double key_pgup=0x4900; /*手动时,增Td*/ double key_pgdown=0x5100; /*手动时,减Td*/*-PLCD780基址定义-*/&

39、#160;#define BASE 0x220   /*-PCL812G need 16 addresses in a row,from  220H to 3F0H*/ #define REG 0/*-定义绘图坐标-*/ #define ox 40     /*-原点横坐标-*/ #define oy 440 

40、;      /*-原点纵坐标-*/ #define xx 600   /*-x轴顶点横坐标-*/ #define xy 440   /*-x轴顶点纵坐标-*/ #define yx 40     /*-y轴顶点横坐标-*/ #define yy 40   /*-y轴顶点纵坐标-

41、*/*-PID参数定义-*/float Kp=1.0; float Ti=10.0; float Td=3.0; float Tf0=15.0; float Tf=0;                            

42、60; float T=0.1;                     /*-采样时间-*/ float ad,e,pv0; float u=0.0; float pv=0.0; /*反馈值*/ float sp=0.0;  /*设定值*/char A_H='

43、H' /*手动-自动,开始为手动*/char manu; /*用于调节u_m的增减*/  int key=0; /*存键盘扫描结果*/ int time_counter=0;   /*中断计数*/ int cj_counter=0;   /*采样计数器*/ int Q_counter=800;  /* 采集步长   赋初始值*/ int stepdata800;

44、0;int slopedata800; int error800;/*-函数声明 -*/ void interrupt (*fadd1C)(void);  /*中断*/void loop();  /*主程序循环*/float AD(unsigned char channal);  /*A/D*/ void DA(float pv1); /*D/A*/ void interrupt

45、0;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 T

46、d1,float Tf1,char A_H1,float T1); float Object(float u1,float T1);   /*仿真对象*/void Initial_Sys(void);     /*初始化为图形模式*/void axis(void);  /*画坐标轴*/void Drawline(int cj,float pv1,float sp1,float 

47、u1,float e1); /*画线*/*主函数*/ void main(void)int i;  for(i=0;i<500;i+)  stepdatai=10; slopedatai=i; errori=0; /* Set new INT_1C  and save old   */   disable();  /*保存旧中断,设置新中断*/fadd1C=getvect

48、(0x1C);/*1C为定时器控制的软中断,平均一秒发生18.2次,即周期为55ms    中断程序*/  /* 开启中断服务*/  setvect(0x1C,INT_1C);  enable();  axis();  loop();  /*主函数结束  下面为定时采值输出程序*/void loop()  do     if(cj_cou

49、nter*T)<(time_counter/18.2)     ad=AD(0);  PIDset();     u=PID(sp,pv,Kp,Ti,Td,Tf,A_H,T);    DA(u);       pv=DelayAction(u); /*pv=Object(u,T);    */  e=errorcj_cou

50、nter;     Drawline(cj_counter,pv,sp,u,e);    manu=0; /*复位*/*status bar,at the top of the screen-how to express %.2f*/    if(Tf=0)printf("IdealPID,Mode:%c,sp=%.1f,pv=%2.1f,u=%.1f,error=%.1f,K

51、p=%.1f,Ti=%.1f,Td=%.1ftr",A_H,sp,pv,u,e,Kp,Ti,Td);    else if(Tf>0) printf("Parallal,Mode:%c,sp=%.1f,pv=%2.1f,u=%.1f,error=%.1f,Kp=%.1f,Ti=%.1f,Td=%.1ftr",A_H,sp,pv,u,e,Kp,Ti,Td);    else printf("ttTf got a 

52、wrong value! Please exit and restart this program.r");cj_counter+;   while(cj_counter<500);  /* 恢复中断*/  disable();  setvect(0x1C,fadd1C);  enable();  /*D/A conversion program,0&

53、#160;to 4095 - 0to +5*/ float AD(unsigned char channal)  float result=0;  int i;  unsigned char hb=0,lb=0,poll=0x10; outportb(BASE+11,REG);  /*软件程序触发*/ for(i=0;i<10000;i+);outportb(BASE+10,channal)

54、; /*进行通道设置.选择通道0*/  for(i=0;i<10000;i+);outportb(BASE+9,0);         /*设置增益通道增益*/  for(i=0;i<10000;i+); outportb(BASE+12,0);  /*触发A/D转换*/ for(i=0;i<10000;i+);  do   /*查询法读PV*/poll=in

55、portb(BASE+5);  while(poll&0x10);  hb=inportb(BASE+5); for(i=0;i<10000;i+);lb=inportb(BASE+4);  result = lb + (hb&0x0F)<<8);  /*0 to 4095*/  result=result*5/4096;  /*0 V to 

56、+5V*/  return result;    /*A/D conversion program,0 to +5 - 0 to 4095*/ void DA(float pv1)      int temp,i;     unsigned char hb,lb;  /

57、*限幅 */if (pv1>5)                    /* make the output real */                 pv1

58、=5;     else if (pv1<0)                 pv1=0;     temp=(int)(4095*pv1/5.0);     hb=temp<<8;     

59、;lb=temp-(hb<<8);outportb(BASE,1);    /*启动DA转换*/  for(i=0;i<10000;i+);    outportb(BASE+4,lb);        /* low 8 */     for(i=0;i<10000;i+);    o

60、utportb(BASE+5,hb);        /* high 4 */ /*00-中断子程序-*/void interrupt INT_1C(void)   time_counter+;  outportb(0x20,0x20);   /*键盘控制*/ int scankey(void)    int key0

61、;   /*扫描键盘,判断是否有建按下*/ key0=bioskey(1);  /*1:无键按下则返回0 */ if(key0!=0)   key0=bioskey(0); /*0:返回按下的键*/  return key0; /*DelayAction*/ /*tao=(int)(18.2*2) Delay action=2 seconds*/ float DelayAction(fl

62、oat y0) /*软件延迟*/   float y_out;static float y_old36=0;  /*将ad延迟2s作为PV,T=0.2s,于是延迟36步*/int cyc;  y_out=y_old36-1;  for(cyc=1;cyc<36;cyc+)   y_old36-cyc=y_old36-cyc-1;  y_old0=y0;  return y

63、_out; /*PID 主程序*/ void PIDset(void)  /*PID设置*/   key=scankey();  /*扫描键盘,并将按键存为key*/ if(A_H='H')  /*手动状态*/   if(key=key_up)    Kp+=0.2;   else if(key=key_down)   &

64、#160;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.

65、2;else if(key=key_U)    /*控制u_m增减*/manu='+'  else if(key=key_D)   manu='-'    if(A_H='A')   /*自动状态*/    if(key=key_U)     /*设定值增减*/sp+=10;  &

66、#160;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='H'  if(key=key_I) &

67、#160; /*理想PID*/Tf=0;  if(key=key_P)   /*实际PID*/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

68、_u,u0,e,C1,C2,C3,C4;   /*离散化后PID参数 当前时刻,u0为返回值*/static float e1,e2,u1,delta_u1;  /*前一时刻的值*/  if(Kp1<0) printf("Kp becomes a negative number,please restart."); else if(Ti1<0)  printf("Ti bec

69、omes a negative number,please press restart."); else if(Td1<0)  printf("Td becomes a negative number,please press restart.");  else    C1=Tf1/(T1+Tf1);  C2=Kp1*T1*(1+T1/Ti1

70、+Td1/T1)/(T1+Tf1);  C3=-Kp1*T1*(1+2*Td1/T1)/(T1+Tf1);  C4=Kp1*Td1/(T1+Tf1);  /*自动控制*/  if(A_H1='A')    e=sp1-pv1; delta_u=C1*delta_u1+C2*e+C3*e1+C4*e2;  /*delta_u1是delta_u前一时刻的值*/ u0=u1+delta_u;  /*当前时刻控制器输出*/ &#

71、160;    e2=e1;   e1=e;   delta_u1=delta_u;   u1=u0;  /*自动时,手操器输出跟踪自动输出*/  errorcj_counter=sp1-pv1;   return u0;/*手动控制*/  else if(A_H1='H')      

72、60;if(manu='+')     /*调节手操器输出*/u+=10;   if(manu='-')    u-=10;   sp1=pv1;   u1=u;  sp=pv1; /*sp跟踪pv保证偏差e为0*/  e1=0; e2=0;   delta_u1=0;     /*将前

73、两时刻的偏差赋值为0*/   errorcj_counter=sp1-pv1;   return u;      /*显示与画图*/*初始化 CRT*/ void Initial_Sys(void)   int GraphDriver;     int GraphMode;     det

74、ectgraph(&GraphDriver,&GraphMode);     initgraph(&GraphDriver,&GraphMode,"C:TC201EBGI");  /*draw basic coordinate axis*/ void axis(void)   int i;Initial_Sys();  setbkcolor(15); &#

75、160;  /*white0/black15*/  setcolor(9); /*linght blue*/  rectangle(10,20,630,470); /*zone of drawing*/  line(ox,oy,xx,xy);   /*axis and arrow*/  line(xx-5,xy-5,xx,xy);  line(xx,xy,xx-5,xy+5);

76、  line(ox,oy,yx,yy);  line(yx-5,yy+5,yx,yy);  line(yx+5,yy+5,yx,yy);  settextstyle(2,1,5);  /*Small font,vert,5 times bigger*/  outtextxy(20,100,"The Output (Response)");  outtextxy(20,40,"U(t)");  

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论