移植的PID算法,现在遇到一个砍了,我是首次接触PID,本着敬畏的态度来学习。关于STM32采用PID算法控制直流有刷电机有几个疑问,希望前辈们能屈尊给新人一些建议。
疑问1:STM32 PID速度环中使用编码器来获取速度的速度单位是什么?(并且这个编码器每次中断服务程序中是什么含义?)关于编码器取到的速度如何使用再PID算法上?
编码器相关代码:
typedef struct
{
unsigned short V; //speed
unsigned short cnt;
unsigned short rcnt;
unsigned short CNT;
}EncoderType;
void TIM3_ENC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_WriteBit(GPIOA, GPIO_Pin_6,Bit_SET);
GPIO_WriteBit(GPIOA, GPIO_Pin_7,Bit_SET);
TIM_TimeBaseStructure.TIM_Period = 20000;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
//?????3?????? IT1 IT2??????
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12,TIM_ICPolarity_BothEdge,TIM_ICPolarity_BothEdge);
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_ICFilter = 6;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
TIM3->CNT = 0;
TIM_Cmd(TIM3, ENABLE);
}
void TIM3_IRQHandler(void)
{
if (TIM3 -> CR1 & 0X0010)
{
GetEncoder.rcnt -= 1;
}
else GetEncoder.rcnt += 1;
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
void Get_Encoder(void)
{
s32 CNT3_temp,CNT3_last;
GetEncoder.cnt = TIM3 -> CNT;
CNT3_last = GetEncoder.CNT;
CNT3_temp = GetEncoder.rcnt * 2000 + GetEncoder.cnt; // #define prd ECDPeriod
GetEncoder.V = CNT3_temp - CNT3_last;
while ((int)(GetEncoder.V)>1000)
{
GetEncoder.rcnt--;
CNT3_temp = GetEncoder.rcnt * 2000 + GetEncoder.cnt;
GetEncoder.V = CNT3_temp - CNT3_last;
}
while ((int)(GetEncoder.V)<-1000) //Vbreak ECDPeriod/2
{
GetEncoder.rcnt++;
CNT3_temp = GetEncoder.rcnt * 2000 + GetEncoder.cnt;
GetEncoder.V = CNT3_temp - CNT3_last;
}
GetEncoder.CNT = CNT3_temp;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
float RM_Kp=4;
float RM_Ki=0;
float RM_Kd=0;
float RM_Lim=100.0;
typedef struct
{
float kp;
float ki;
float kd;
float errILim;
float errNow;
float ctrOut;
float errOld;
float errP;
float errI;
float errD;
}PID_AbsoluteType;
void PID_AbsoluteMode(PID_AbsoluteType* PID)
{
if(PID->kp < 0.0) PID->kp = -PID->kp;
if(PID->ki < 0.0) PID->ki = -PID->ki;
if(PID->kd < 0.0) PID->kd = -PID->kd;
if(PID->errILim < 0.0) PID->errILim = -PID->errILim;
PID->errP = PID->errNow;
PID->errI += PID->errNow;
if(PID->errILim != 0)
{
if( PID->errI > PID->errILim) PID->errI = PID->errILim;
else if(PID->errI < -PID->errILim) PID->errI = -PID->errILim;
}
PID->errD = PID->errNow - PID->errOld;
PID->errOld = PID->errNow;
PID->ctrOut = PID->kp * PID->errP + PID->ki * PID->errI + PID->kd * PID->errD;
}
void PidSpeedControl(int Speed) //入口参数 设定的速度值 100
{
SpeedNow = GetEncoder.V; //get Encoder speed it is real speed
SpeedTag = Speed; //this speed is set speed
PidSpeedType.errNow = SpeedTag - SpeedNow; //get speed Difference
PidSpeedType.kp =RM_Kp; //get main.c RM_Kp value
PidSpeedType.ki = RM_Ki; //get main.c RM_Ki value
PidSpeedType.kd =RM_Kd; //get main.c RM_Kd value
PidSpeedType.errILim = RM_Lim; //get main.c RM_Lim value
PID_AbsoluteMode(&PidSpeedType);
SpeedControl = PidSpeedType.ctrOut; //输出速度值
printf("%d ",SpeedControl );
MotorSpeedSet(SpeedControl); // PWM占空比 = SpeedControl / ARR (ARR=719) PWM 频率14Khz
}
谢谢前辈,PID速度调总是有振荡。我这里还有一个疑问就是为什么我的速度不是从零开始的,而是从KP*100(100为我设定的速度的值)往下降呢?
一周热门 更多>