▲ PID控制框图
//pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]typedef struct PID{float kp;float ki;float kd;float ek; //当前误差float ek_1; //上一次误差float ek_sum; //误差总和float limit; //限幅}PID;static PID pid;void PID_Init(){pid.kp = 0.1;pid.ki = 0.2;pid.kd = 0.3;pid.limit = 1000;pid.ek = 0;pid.ek_1 = 0;pid.ek_sum = 0;}// 位置式PID控制float PID_Postion(int Encoder,int Target){float pwm = 0;pid.ek = Target - Encoder; // 计算当前误差pid.ek_sum += pid.ek; //求出偏差的积分pwm = pid.kp*pid.ek + pid.ki*pid.ek_sum +pid.kd*(pid.ek - pid.ek_1); //位置式PID控制器pid.ek_1 = pid.ek; //保存上一次偏差if(pwm > pid.limit){pwm = pid.limit;}else if(pwm < -pid.limit){pwm = -pid.limit;}return pwm;}
//根据增量式离散PID公式//pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]//e(k)代表本次偏差//e(k-1)代表上一次的偏差 以此类推//e(k-2)代表上上次的偏差//pwm代表增量输出typedef struct PID{float kp;float ki;float kd;float ek; //当前误差float ek_1; //上一次误差float ek_2; //上上一次误差float limit; //限幅}PID;static PID pid;void PID_Init(){pid.kp = 0.1;pid.ki = 0.2;pid.kd = 0.3;pid.limit = 1000;pid.ek = 0;pid.ek_1 = 0;pid.ek_2 = 0;}// 增量式PID控制float PID_Increase(int Encoder,int Target){float pwm = 0;pid.ek = Target - Encoder; // 计算当前误差pid.ek_sum += pid.ek; //求出偏差的积分pwm = pid.kp*(pid.ek - pid.ek_1) + pid.ki*pid.ek +pid.kd*(pid.ek - 2*pid.ek_1 + pid.ek_2); //增量式PID控制器pid.ek_1 = pid.ek; //保存上一次偏差pid.ek_2 = pid.ek_1; //保存上上一次的偏差if(pwm > pid.limit){pwm = pid.limit;}else if(pwm < -pid.limit){pwm = -pid.limit;}return pwm;}