华北电力大学过程计算机控制课设DDC串级回路PID闭环.docx
- 文档编号:27429222
- 上传时间:2023-06-30
- 格式:DOCX
- 页数:25
- 大小:429.44KB
华北电力大学过程计算机控制课设DDC串级回路PID闭环.docx
《华北电力大学过程计算机控制课设DDC串级回路PID闭环.docx》由会员分享,可在线阅读,更多相关《华北电力大学过程计算机控制课设DDC串级回路PID闭环.docx(25页珍藏版)》请在冰豆网上搜索。
华北电力大学过程计算机控制课设DDC串级回路PID闭环
课程设计报告
名称:
过程计算机控制
题目:
DDC串级回路PID闭环
控制系统的设计及实时仿真
院系:
控计
班级:
学号:
学生:
同组人:
指导教师:
明扬
设计周数:
一周
一、设计目的
1.学习并了解用高级语言(C语言)实现数字PID控制算法模块程序的方法;
2.比较验证理想微分PID和实际微分PID控制算法阶跃响应,加深对上述两种算法各自特点的认识;
3.学习了解用模拟计算机使用方法;
4.学习掌握A/D、D/A转换接口板的使用方法;
5.了解一种微机中断定时的方法;
6.学习掌握通过A/D、D/A转换用计算机获取被控对象动态特性的方法;
7.通过实时仿真实验掌握DDC单回路控制程序编制及调试方法。
二、实验仪器
(1)微型计算机一台,系统软件Windows98或DOS(不能使用无直接I/O能力的NT或XP系统),装TurboC2.0/3.0集成开发环境软件;
(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);
四、硬件二阶惯性环节搭建
利用模拟计算机中的电容电阻及运算放大器,搭接二阶惯性环节,仿真一个被控对象。
其传递函数为
,硬件电路如下:
图中各元件参数如下:
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输出一个幅度为2伏左右的阶跃信号,同时采集输入输出信号。
然后,D/A再反向在输出一个幅度为2伏左右负的阶跃信号,同时采集输入输出信号,得出仿真对象飞升特性曲线。
程序中,通过按键实现模拟对象输入信号的加减。
当按下H按键时,且按下U键时,D/A输出一个1伏阶跃信号,再次按下按键时阶跃信号累加。
每次按下D键时,D/A输出的阶跃信号递减1。
(3)根据对象单位阶跃响应曲线求增益和惯性时间:
利用切线法求对象的增益和用一阶等效的惯性时间:
如上图所示做拐点切线,得对象增益和一阶等效惯性时间分别为:
(4)手自动切换:
(5)设定值r、控制量u和被控对象输出的阶跃响应曲线:
程序清单
/*---------------头文件定义---------------*/
#include
#include
#include
#include
/*---------------定义绘图坐标---------------*/
#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轴顶点纵坐标----*/
/*-----------------定义绘图区域----------------*/
#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
/*--------------理想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 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);
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);
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");
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,"The output (Response)");
outtextxy(ytext2x,ytext2y,"U(t)\/V");
}
}
main()
{
float kp,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);
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"
#include "string.h"
#include "dos.h"
#include "bios.h"
#include "conio.h" /*中断程序头文件定义*/
#include "stdlib.h"
#include "io.h"
/*--------------按键地址区定义--------------------*/
/*statements*/
double key_ESC=0x011b; /*退出*/
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;/*实际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基址定义--------------------*/
#define BASE 0x220 /*------------PCL812G need 16 addresses in a row,from 220H to 3F0H*/
#define REG 0
/*---------------定义绘图坐标---------------*/
#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.0;/*反馈值*/
float sp=0.0; /*设定值*/
char A_H='H';/*手动-自动,开始为手动*/
char manu;/*用于调节u_m的增减*/
int key=0;/*存键盘扫描结果*/
int time_counter=0; /*中断计数*/
int cj_counter=0; /*采样计数器*/
int Q_counter=800; /* 采集步长 赋初始值*/
int stepdata[800];
int slopedata[800];
int error[800];
/*--------------函数声明 -----------------*/
void interrupt (*fadd1C)(void); /*中断*/
void loop(); /*主程序循环*/
float AD(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);
float Object(float u1,float T1); /*仿真对象*/
void Initial_Sys(void); /*初始化为图形模式*/
void axis(void); /*画坐标轴*/
void Drawline(int cj,float pv1,float sp1,float u1,float e1);/*画线*/
/*主函数*/ void main(void)
{
int i;
for(i=0;i<500;i++)
{stepdata[i]=10;slopedata[i]=i;error[i]=0;}
/* Set new INT_1C and save old */
disable(); /*保存旧中断,设置新中断*/
fadd1C=getvect(0x1C);/*1C为定时器控制的软中断,平均一秒发生18.2次,即周期为55ms 中断程序*/
/* 开启中断服务*/
setvect(0x1C,INT_1C);
enable();
axis();
loop();
}
/*主函数结束 下面为定时采值输出程序*/
void loop()
{ do
{
if((cj_counter*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=error[cj_counter];
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,Kp=%.1f,Ti=%.1f,Td=%.1f\t\r",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=%.1f\t\r",A_H,sp,pv,u,e,Kp,Ti,Td);
else printf("\t\tTf got a 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 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); /*进行通道设置.选择通道0*/
for(i=0;i<10000;i++);
outportb(BASE
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 华北电力 大学 过程 计算机控制 DDC 回路 PID 闭环