移植的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;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
1。首先让电机转起来,验证下你的速度读取函数是否有问题
2。如果不使能PID,电机刚开始的转速时怎样的?
3。按我的理解,PID过程应该是先走走看,然后再往目标上调
....待续
一周热门 更多>