计算机控制课设串级回路,华北电力大学过程计算机控制课设DDC串级回路PID闭环.doc...

这篇课程设计报告详细介绍了使用C语言实现DDC串级回路PID闭环控制算法的过程。实验中,通过模拟计算机搭建了二阶惯性环节作为被控对象,采用理想微分PID和实际微分PID算法进行控制,并进行了实时仿真。报告包含了硬件搭建、算法离散化、系统实验结果和手动自动切换功能的实现,同时展示了PID参数对系统响应的影响。
摘要由CSDN通过智能技术生成

《华北电力大学过程计算机控制课设DDC串级回路PID闭环.doc》由会员分享,提供在线免费全文阅读可下载,此文档格式为doc,更多相关《华北电力大学过程计算机控制课设DDC串级回路PID闭环.doc》文档请在天天文库搜索。

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

2、(XMN-1型);(3)通用数据采集控制板一块(PCL-812PG型)。三、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);四、硬件二阶惯性环节搭建利用模拟计算机中的电。

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

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

5、绘图坐标---------------*/       #define ox 8       /*-原点横坐标-------*/          #define oy 440                /*------原点纵坐标------*/       #define xx 620                /*------x轴顶点横坐标--*/       #define xy 440                /*-----x轴顶点纵坐标---*/       #define lenx 580       #define leny 400       #define yx 8                   /*-----y轴顶点横坐标----*/       #define yy 15                 /*------y轴顶点纵坐标----*//。

6、*-----------------定义绘图区域----------------*/       #define left 20       #define top 20       #define right 620       #define bottom 460 /*----------------坐标轴注释---------------------*/       #define xtext1x 450       #define xtext1y 450       #define ytext1x 10       #define ytext1y 60       #define xtext2x 610       #define xtext2y 450       #define ytext2x 10       #define ytext2y 20/*-------------。

7、-理想PID运算式----------*/ float lxpid(float kp,float td,float ti,float e[3],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*e[0]+q1*e[1]+q2*e[2]+u1;       return u;  }/*-------------------------实际PID运算式--------------------------*/ float sjpid(float kp,float tf,float td,float ti,float e[3],float du1,float u1) { int。

8、 t=1;        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*e[0]+c3*e[1]+c4*e[2]+u1;        return u2; }/*-------------------------绘图初始化--------------------------*/ void Initial_Sys(void) {     int GraphDriver;        int GraphMode;        detectgraph(&GraphDriver,&GraphMode)。

9、;        initgraph(&GraphDriver,&GraphMode,"C:\\TC201E\\BGI");      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);。

10、    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);      }       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");       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");      。

11、 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");       outtextx。

12、y(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,"The output (Response)");    outtextxy(ytext2x,ytext2y,"U(t)\/V"); }}main() {      float kp,。

13、ti,td,tf,e[3]={0},ee[3]={0},u[6]={0},au1=0;      int r=1,k=1;      Initial_Sys();      DrawAxis();      while(k<100)      {            u[0]=lxpid(1,3.0,10,e,u[1]);            e[0]=r;             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);                 。

14、   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]。省略部分。ortb(BASE+11,REG);  /*软件程序触发*/ for(i=0;i<10000;i++);outportb(BASE+10,channal); /*进行通道设置.。

15、选择通道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=inportb(BASE+5);  }while(poll&0x10);  hb=inportb(BASE+5); for(i=0;i<10000;i++);lb=inportb(BASE+4);  result = lb + ((hb&0x0F)<5)                    /* make the output real */                 pv1=5;     else if (pv1。

16、<0)                 pv1=0;     temp=(int)(4095*pv1/5.0);     hb=temp<<8;     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++);    outportb(BASE+5,hb);        /* high 4 */ }/*00----------------------------中断子程序-------------------------*/void interrupt INT_1C(void) {  time_counter++;  outpo。

17、rtb(0x20,0x20);  } /*键盘控制*/ int scankey(void)  {  int key0;   /*扫描键盘,判断是否有建按下*/ 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(float y0) /*软件延迟*/ {  float y_out;static float y_old[36]={0};  /*将ad延迟2s作为PV,T=0.2s,于是延迟36步*/int cyc;  y_out=y_old[36-1];  for(cyc=1;cyc<36;cyc++。

18、)   y_old[36-cyc]=y_old[36-cyc-1];  y_old[0]=y0;  return y_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)    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。

19、)    /*控制u_m增减*/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='H';  if(key==key_I)   /*理想PID*/Tf=0;  if(key==key_P)   /*实际PID*/Tf=Tf0; }/*PID-default:IdealPID*/ float PID(float sp1,float pv1,。

20、float Kp1,float Ti1,float Td1,float Tf1,char A_H1,float T1) {    float delta_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 becomes a negative number,please press restart."); else if(Td1<0)  printf("Td becomes a negative number,please press restart."); 。

21、 else  {  C1=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=sp1-pv1; delta_u=C1*delta_u1+C2*e+C3*e1+C4*e2;  /*delta_u1是delta_u前一时刻的值*/ u0=u1+delta_u;  /*当前时刻控制器输出*/      e2=e1;   e1=e;   delta_u1=delta_u;   u1=u0;  /*自动时,手操器输出跟踪自动输出*/  error[cj_counter]=sp1-pv1;   return u0;}/*手动控制*/  else if(A_H1=='H')  。

22、  {   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;     /*将前两时刻的偏差赋值为0*/   error[cj_counter]=sp1-pv1;   return u;  }  } } /*显示与画图*//*初始化 CRT*/ void Initial_Sys(void) {  int GraphDriver;     int GraphMode;     detectgraph(&GraphDriver,&GraphMode);     initgraph(&GraphDriver,&GraphMode,"C:\\TC201E\\BGI"); } /*dr。

23、aw basic coordinate axis*/ void axis(void) {  int i;Initial_Sys();  setbkcolor(15);    /*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);  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*/  o。

24、uttextxy(20,100,"The Output (Response)");  outtextxy(20,40,"U(t)");  settextstyle(2,0,5);  /*Small font,horiz,5 times bigger*/  outtextxy(300,455,"Time");  outtextxy(590,455,"t/sec");    setlinestyle(1,0,1);   /*dot line,none,width*/  for(i=1;i<4;i++)  /*each inport starting position*/    line(ox,oy-100*i,ox+500,oy-100*i);  outtextxy(ox-16,oy-100*0,"0");  outtextxy(ox-16,oy-100*1,"1");  outtext。

25、xy(ox-16,oy-100*2,"2");  outtextxy(ox-16,oy-100*3,"3");  for(i=1;i<=500/50;i++)   /*scale*/  {   line(ox+50*i,oy,ox+50*i,oy-400);   /*1/T=10,that is 10px=1sec*/   line(ox+50*i-25,oy,ox+50*i-25,oy-10);  }  setlinestyle(0,0,1);  /*real line,none,width*/ outtextxy(ox-4+50,oy+2,"5");outtextxy(ox-8+100,oy+2,"10");  outtextxy(ox-8+150,oy+2,"15");  outtextxy(ox-8+200,oy+2,"20");  outtextxy(ox-8+250,oy。

26、+2,"25");  outtextxy(ox-8+300,oy+2,"30");  outtextxy(ox-8+350,oy+2,"35");  outtextxy(ox-8+400,oy+2,"40");  outtextxy(ox-8+450,oy+2,"45");  outtextxy(ox-8+500,oy+2,"50"); } /*line-drawing and notes*/ void Drawline(int cj1,float pv1,float sp1,float u1,float e1)  /*画线*/ {  static int cj_0=0,cj_1=0,pv_0=0.0,pv_1=0.0,sp_0=0.0,sp_1=0.0,u_0=0.0,u_1=0.0,e_0=0.0,e_1=0.0;  cj_1=cj1;   /*X coordinate*/  pv_1。

27、=(int)(pv1*10);  sp_1=(int)(sp1*10);  u_1=(int)(u1*10);  e_1=(int)(e1*10);  setcolor(2); /*green*/  line(ox+cj_0,oy-pv_0,ox+cj_1,oy-pv_1);  outtextxy(590,30,"pv");  setcolor(8); /*dark gray*/  line(ox+cj_0,oy-sp_0,ox+cj_1,oy-sp_1);  outtextxy(590,45,"sp");  setcolor(3); /*cyan*/  line(ox+cj_0,oy-u_0,ox+cj_1,oy-u_1);  outtextxy(590,60,"u");  setcolor(4); /*red*/  line(ox+cj_0,oy-e_0,ox+cj_1,oy-e_1);  outtextxy(590,75,"error"); cj_0=cj_1;  pv_0=pv_1;  sp_0=sp_1;  u_0=u_1;  e_0=e_1; }.。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值