前言
pid是我们在学习单片机中首先要学会的控制算法,这篇文章主要介绍stm32如何编写pid的代码,没有对pid进行分析和解释,要想了解原理的可以参考这篇文章。
对于增量式pid和位置式pid可以查看
一、代码
本文是使用PI增量式控制 – 控制电机的转速。
对于增量式pid和位置式pid的区别可以查看这篇文章
1.pid
创建一个pid.c和pid.h文件
pid.c
#include "pid.h"
/**************************************************************************
函数功能:增量PI控制器
入口参数:编码器测量值,目标速度
返回 值:电机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)代表上一次的偏差 以此类推
pwm代表增量输出
在我们的速度控制闭环系统里面,只使用PI控制
pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)
**************************************************************************/
int Incremental_PI (int Encoder,int Target)
{
float Kp=50,Ki=10;
static int Bias,Pwm,Last_bias;
Bias=Target-Encoder; //计算偏差
Pwm+=Kp*(Bias-Last_bias)+Ki*Bias; //增量式PI控制器
Last_bias=Bias; //保存上一次偏差
return Pwm; //增量输出
}
/**************************************************************************
函数功能:限制PWM赋值
入口参数:无
返回 值:无
**************************************************************************/
int Xianfu_Pwm(int moto) //限制幅度的函数
{
int Amplitude=7000; //===PWM满幅是8400 限制7000
if(moto<-Amplitude) moto = -Amplitude;
if(moto>Amplitude) moto = Amplitude;
return moto;
}
pid.h
#ifndef __PID_H
#define __PID_H
#include "main.h"
#include "moto.h"
int Incremental_PI (int Encoder,int Target);
int Xianfu_Pwm(int moto) ;//限制幅度的函数
#endif
2. it.c文件
/* USER CODE BEGIN 1 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==(&htim9))//因为我采用的是定时器6
{
int setcc=50;
int Encoder;
int moto_pwm;
Encoder=Read_Encoder();
moto_pwm=Incremental_PI(Encoder,setcc);
moto_pwm=Xianfu_Pwm(moto_pwm);
Set_Pwm(moto_pwm);
printf("samples: %d ,%d ,%d\n",Encoder,setcc,moto_pwm);
}
}
/* USER CODE END 1 */
这里要注意我并未使用转/分钟作为pid输入的值,因为这样存在误差,不如直接使用编码器的值进行控制。