标题:
51单片机PID抗饱和积分程序+Proteus仿真
[打印本页]
作者:
nhwdb
时间:
2019-9-25 15:51
标题:
51单片机PID抗饱和积分程序+Proteus仿真
这是一个C51的PID调节的源程序。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png
(11.32 KB, 下载次数: 68)
下载附件
2019-9-25 16:01 上传
单片机源程序如下:
#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;}
}
}
复制代码
0.png
(9.17 KB, 下载次数: 73)
下载附件
2019-9-25 16:02 上传
所有资料51hei提供下载:
pid抗饱和变积分.rar
(103.99 KB, 下载次数: 37)
2019-9-25 15:49 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
高德辛
时间:
2019-9-27 16:02
keil编译不通过,提供的仿真一直发送“览”,你告诉我你干啥呢?
作者:
jnshuhe
时间:
2019-9-28 07:38
这里高手真多,学习了,谢谢楼主!
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1