内容来源:STM32——PID恒温控制_stm32 pid pwm 温度-CSDN博客
致谢:浪客小子-CSDN博客
一,PID介绍
上式为PID的最终输出值
其中,OUT为PWM的脉宽;Kp、Ki、Kd为常数,我们所说的“PID调参”,就是修改这三个参数的值,使PID的输出值(OUT)更加接近于我们的期望值(我们的期望值(电机的转速,温度)是通过PWM波控制的);out0是一个常数,可设置为1,以避免Ek = 0时Out也等于0。
Ki=Kp(T/Ti) , Kd=Kp(Td/T) ;T为PID计算周期, Ti为积分时间,Td为微分时间(知道即可)。
PID的三个分式从左到右分别为,比例控制,积分控制,微分控制。
计算程序如下:
void PID_Calc()
{
float DelEk;
float ti,ki;
float td;
float kd;
float out;
if(pid.C1ms<(pid.T)) //计算周期未到
{
return ;
}
pid.Ek=pid.Sv-pid.Pv; //得到当前的偏差值
pid.Pout=pid.Kp*pid.Ek; //比例输出
pid.SEk+=pid.Ek; //历史偏差总和
DelEk=pid.Ek-pid.Ek_1; //最近两次偏差之差
ti=pid.T/pid.Ti;
ki=ti*pid.Kp;
pid.Iout=ki*pid.SEk; //积分输出
td=pid.Td/pid.T;
kd=pid.Kp*td;
pid.Dout=kd*DelEk; //微分输出
out= pid.Pout+ pid.Iout+ pid.Dout;
if(out>pid.pwmcycle)
{
pid.OUT=pid.pwmcycle;
}
else if(out<=0)
{
pid.OUT=pid.OUT0;
}
else
{
pid.OUT=out;
}
pid.Ek_1=pid.Ek; //更新偏差
pid.C1ms=0;
}
可调参数如下:
void PID_Init()
{
pid.Sv=38;//用户设定温度
pid.Kp=30;
pid.T=400;//PID计算周期
pid.Ti=4000000;//积分时间
pid.Td=1000;//微分时间
pid.pwmcycle=200;//pwm周期200 Freq=72M/(PSC+1)/(ARR+1)
pid.OUT0=1;
pid.C1ms=0;
}
结构体如下:
typedef struct Pid
{
float Sv;//用户设定值
float Pv;//测定温度
float Kp;
int T; //PID计算周期--采样周期
float Ti;
float Td;
float Ek; //本次偏差
float Ek_1;//上次偏差
float SEk; //历史偏差之和
float Iout;
float Pout;
float Dout;
float OUT0;
float OUT;
int C1ms;
int pwmcycle;//pwm周期
int times;
}PID;
使用案例(STM32F103C4):
PID_Calc();
num=(((pid.OUT*PERIOD)/pid.pwmcycle)-1);
IM_SetCompare2(TIM3,num);
如有错误,欢迎指正