STM32 PID速度环 PID输出的速度总是达不到我设定的速度值

2019-12-20 21:41发布

移植的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;                                                 
  
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
zhongsandaoren
1楼-- · 2019-12-21 13:52
whatcanitbe
2楼-- · 2019-12-21 16:32
本帖最后由 whatcanitbe 于 2018-3-22 06:51 编辑

1。首先让电机转起来,验证下你的速度读取函数是否有问题
2。如果不使能PID,电机刚开始的转速时怎样的?
3。按我的理解,PID过程应该是先走走看,然后再往目标上调
....待续
whatcanitbe
3楼-- · 2019-12-21 18:12
 精彩回答 2  元偷偷看……

一周热门 更多>