分享一個STM32F4的源程序,主要分享PI環的編寫,單片機的源程序如下:
#include "pid.h"
void pid_param_init(pid_control * pid, float target,float kp, float ki, float kd) //初始化 由.h可知PID_TypeDef可以用pid_control表示
{
pid->target = target;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->output = 0;
}
void pid_reset(pid_control * pid, float kp, float ki, float kd) //更新
{
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
}
float pid_calculate(pid_control* pid, float measure)
{
pid->measure = measure;//測量值?
pid->last_err = pid->err;//更新前一次誤差
pid->last_output = pid->output;
pid->err = pid->target - pid->measure;//計算當前誤差
//計算三個輸出
pid->pout = pid->kp * pid->err;
pid->iout += (pid->ki * pid->err);
pid->dout = pid->kd * (pid->err - pid->last_err);
//限幅
if(pid->iout>100) pid->iout=100;//因為PWM最大值為100 ARR
else if(pid->iout<-100) pid->iout=-100;//有可能會向下積分
//計算輸出值
pid->output = pid->pout + pid->iout + pid->dout;
//輸出限幅
if(pid->output>90) pid->output=90;
else if(pid->output<10) pid->output=10;
return pid->output;
}
void pid_init(pid_control* pid)
{
pid->f_param_init = pid_param_init;//表示.h里的指針函數可以用上述的函數表示
pid->f_pid_reset = pid_reset;
pid->f_cal_pid = pid_calculate;
}
#ifndef __PID_H
#define __PID_H
#include "sys.h"
typedef struct PID_TypeDef
{
float target; //目標值
float kp;//比例
float ki;//積分
float kd;//微分
float measure; //測量值
float err; //誤差
float last_err; //上次誤差
float pout; //比例項
float iout; //積分項
float dout; //微分項
float output; //本次輸出
float last_output;//上次輸出
//以下的會在.c中聲明
void (*f_param_init)(struct PID_TypeDef *pid,float target,float kp,float ki,float kd);//參數初始化
void (*f_pid_reset)(struct PID_TypeDef *pid, float kp,float ki, float kd);//參數修改
float (*f_cal_pid)(struct PID_TypeDef *pid, float measure);//pid計算
}pid_control;
void pid_init(pid_control* pid);
#endif
|