# include <dos.h>
# include <stdio.h>
# include <stdlib.h>
# include <graphics.h>
# include <conio.h> //conio.h 用于DOS窗输出输入
#define Num 250 //信号采集
void Draw_curve(char symbal,int i,char color);
void draw_ordinate(int x,int y);
int x=50;
int y=440;
float AD,e[Num],Y[Num],u[Num],Du[Num];
float X,Y,Z,Kp,Ki,Kd,T,k,R,uk;
void init()
{
int driver=DETECT,mode;
mode=0;
initgraph(&driver,&mode,"c:\\tc\\bgi");
}
void main()
{
int i,j,lb,hb;
int flag=0,m=0,n=0,t=0;
long int rk;
float tp,ct,max,tr,ts,ec;
FILE *fp;
char *strKp=NULL;
char *strKi=NULL;
char *strKd=NULL;
char *strSampleTime = NULL;
int DAout(float uk);
/* char *string;*/
init();
fp=fopen("pid.dat","w");
printf("*****hahaha*****PID control real-time simulation****hahaha******\n\n");
printf ("please input the data(Kp Ki Kd):");
scanf ("%f %f %f",&Kp,&Ki,&Kd);
printf("please assign the input voltage R:");
scanf("%f",&R);
cleardevice();
draw_ordinate(x,y);
T=1.0; //周期
X=Kp+T*Ki+Kd/T;
Y=Kp+2*Kd/T;
Z=Kd/T;
/*initial the 8253 */ //定时器
outportb(0x284,0x03); //选8253控制寄存器地址
outportb(0x287,0x74); //写1计数器控制字
outportb(0x284,0x01); //选1计数器地址
outportb(0x287,0xf4);
outportb(0x287,0x01);
outportb(0x284,0x03); //选8253控制寄存器地址
outportb(0x287,0xb4); //写1计数器控制字
outportb(0x284,0x02); //选2计数器地址
outportb(0x287,0x90);
outportb(0x287,0x01); //选AD转换1#通道
outportb(0x280,0x00); //
outportb(0x284,0x04); //定时器允许
DAout(0.0); //DA编程
for(i=0;i<=Num-1;i++)
{ lb=0;hb=0;
while((inportb(0x281)&128)==0); //AD转换是否结束
lb=inportb(0x282);
hb=inportb(0x283)&0x0f;
rk=hb*256+lb;
AD=((rk-2047.0)/4096.0)*10;
Y[i]=AD;
Y[0]=0;
e[i]= R-Y[i];
if(i==0) Du[0]=A*e[0];
else if(i==1) Du[1]=A*e[1]-B*e[0];
else Du[i]=A*e[i]-B*e[i-1]+C*e[i-2];
u[i]=(i==0)? Du[0]: u[i-1]+Du[i];
k=u[i]*409.6+2047;
hb=k/256;
lb=k-hb*256;
outportb(0x282,lb);
outportb(0x283,hb);
Draw_curve('Y',i,RED); //画图
fprintf(fp,"%f\n",Y[i]);
} /*outportb(0x284,0);*/ //定时器禁止
DAout(0.0);
DAout(0.0);
max=Y[0];
for(i=1;i<Num;i++)
{
if(Y[i]>=max)
{
max=Y[i];
flag=i;
}
}
for(j=Num-1;j>1;j--)
{ ec=Y[j]-R;
if((ec<=0.05*R)&&(ec>=-0.05*R))
{
n=j;
}
else break;
}
for(i=1;i<Num;i++)
{
if(Y[i]<=0.9*R)
{
m=i;
}
else break;
}
for(i=1;i<Num;i++)
{
if(Y[i]>=0.1*R)
{
t=i;
}
else break;
}
tr=T*(m-t); //上升时间
ts=T*n; // 调节时间
tp=T*flag; //峰值时间
ct=((max-R)/R)*100; //超调
settextstyle(1,0,1); //文本属性
outtextxy(120,44,"峰值时间tp="); //在指定位置显示一字符串
/*string=fcvt(tp,1,0,0);*/
outtextxy(150,44,fcvt(tp,0,0,0));
outtextxy(190,44,"s");
outtextxy(220,44,"上升时间tr=");
outtextxy(250,44,fcvt(tr,0,0,0));
outtextxy(290,44,"s");
outtextxy(320,44,"调节时间ts=");
outtextxy(350,44,fcvt(ts,0,0,0));
outtextxy(390,44,"s");
outtextxy(420,44,"超调Ct=");
outtextxy(460,44,fcvt(ctl,0,0,0));
outtextxy(490,44," %");
sprintf(strKp,"%6.2f",Kp);
outtextxy(120,54,"Kp=");
outtextxy(140,54,strKp);
sprintf(strKi,"%6.2f",Ki);
outtextxy(200,54,"Ki=");
outtextxy(220,54,strKi);
sprintf(strKd,"%6.2f",Kd);
outtextxy(280,54,"Kd=");
outtextxy(300,54,strKd);
sprintf(strSampleTime,"%6.2f",T);
outtextxy(370,54,"sample Time=");
outtextxy(450,54,strSampleTime);
getch();
fclose(fp);
closegraph();
}
void Draw_curve(char symbal,int i,char color)
{ setcolor(color);
setlinestyle(SOLID_LINE,0,1);//设置当前画线宽度和类型
if(symbal=='Y') line(x+i*2,y-(int)(Y[i-1]*75),x+(i+1)*2,y-(int)(Y[i]*75));
}
void draw_ordinate(int x,int y)
{ int i;
char ch[10];
char *strKp,*strKi,*strKd;
int dec, sign, ndig = 3;
strKp = fcvt(Kp, ndig, &dec, &sign);
for(i=5;i>dec;i--)
line(x,y,x+550,y);
line(x,y,x,y-400);
line(x,y,x,y);
line(x,y-400,x-5,y-400+10);
line(x,y-400,x+5,y-400+10);
line(x+550,y,x+550-10,y-5);
line(x+550,y,x+550-10,y+5);
outtextxy(x-10,y+20,"0");
outtextxy(x+545,y+20,"T/0.1s");//需改变
outtextxy(x-40,y-400,"V(v)");
setcolor(DARKGRAY);
line(x,y,x,y);
setlinestyle(DASHED_LINE,0,1);
for(i=1;i<6;i++)
{ itoa(i*5,ch,10);
setcolor(DARKGRAY);
line(x+i*100,y,x+i*100,y-375);
setcolor(WHITE);
outtextxy(x+i*100-5,y+10,ch);
setcolor(DARKGRAY);
line(x,y-i*75,x+500,y-i*75);
itoa(i,ch,10);
setcolor(WHITE);
outtextxy(x-15,y-i*75-5,ch);
}
setcolor(RED);
settextstyle(1,HORIZ_DIR, 3);
outtextxy(x+130,y-445,"PID Control Curve");
}
int DAout(float uk)
{
int lb,hb;
float k;
k=uk*409.6+2047;
hb=k/256;
lb=k-hb*256;
outportb(0x282,lb);
outportb(0x283,hb);
return 0;
}
评论0