|
这是一个C51的PID调节的源程序。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- #include <stdio.h>
- #include <math.h>
- #ifndef uchar
- #define uchar unsigned char
- #endif
- #ifndef uint
- #define uint unsigned int
- #endif
- #ifndef ulong
- #define ulong unsigned long
- #endif
- /*
- struct _pid{
- float SetSpeed; //定义设定值
- float ActualSpeed; //定义实际值
- float err; //定义偏差值
- float err_last; //定义上一个偏差值
- float Kp,Ki,Kd; //定义比例、积分、微分系数
- float voltage; //定义电压值(控制执行器的变量)
- float integral; //定义积分值
- float umax;
- float umin;
- }pid;
- void PID_init(){
- printf("PID_init begin \n");
- pid.SetSpeed=0.0;
- pid.ActualSpeed=0.0;
- pid.err=0.0;
- pid.err_last=0.0;
- pid.voltage=0.0;
- pid.integral=0.0;
- pid.Kp=0.4;
- pid.Ki=0.2; //注意,和上几次相比,这里加大了积分环节的值
- pid.Kd=0.2;
- pid.umax=400;
- pid.umin=-200;
- printf("PID_init end \n");
- }
- float PID_realize(float speed){
- int index;
- pid.SetSpeed=speed;
- pid.err=pid.SetSpeed-pid.ActualSpeed;
- if(pid.ActualSpeed>pid.umax) //灰色底色表示抗积分饱和的实现
- {
- if(abs(pid.err)>200) //蓝色标注为积分分离过程
- { index=0; }
- else{
- if(abs(pid.err)>180) {index=(200-abs(err))/20;}
- else{index=1;}
- if(pid.err<0)
- {
- pid.integral+=pid.err;
- }
- }
- }
- else
- if(pid.ActualSpeed<pid.umin)
- {
- if(abs(pid.err)>200) //积分分离过程
- { index=0; }
- else{
- if(abs(pid.err)>180) {index=(200-abs(err))/20;}
- else{index=1;}
- if(pid.err>0)
- {
- pid.integral+=pid.err;
- }
- }
- }
- else
- {
- if(abs(pid.err)>200) //积分分离过程
- { index=0; }
- else{
- if(abs(pid.err)>180) {index=(200-abs(err))/20;}
- else{index=1;}
- pid.integral+=pid.err;
- }
- }
- //pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
- //pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral/2+pid.Kd*(pid.err-pid.err_last); //梯形积分
- pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last); //
- pid.err_last=pid.err;
- pid.ActualSpeed=pid.voltage*1.0;
- return pid.ActualSpeed;
- }
- */
- void main()
- {
- uint idata count=0;
- int idata speed1,speed3=0;
- // uchar speed2;
- SCON=0x50;
- TMOD=0x20;
- TCON=0x40;
- TH1=0xe8;
- TL1=0xe8;
- TI=1;
- TR1=1;
- printf("System begin \n");
- PID_init();
- while(1)
- {
- if(count<100)
- {
- speed1 = PID_contral(250, speed3 );
- // printf("%f\n",speed);
- printf("%d\n",speed1);
- printf("%5d\n",speed3);
- // if(speed3<151){speed3 +=20;}
- // if((speed3>150)&&(speed3<181)){speed3 += 10;}
- // if((speed3>180)&&(speed3<191)){speed3 += 2;}
- if(speed3<250){speed3 += 10;}
- }
- if((count>99)&&(count<150))
- {
- speed1=PID_contral(200,speed3);
- printf("%d\n",speed1);
- printf("%5d\n",speed3);
- if(count<110) {speed3 -= 2;}
- if((count>119)&&(count<130)) {speed3 -= 1;}
- // else speed3 =202;
- }
- count++;
-
- if(count>150){break;}
-
- }
-
- }
复制代码
所有资料51hei提供下载:
pid抗饱和变积分.rar
(103.99 KB, 下载次数: 37)
|
评分
-
查看全部评分
|