wenbo2005.online

学习记录 / STM32

直流电机 PID

STM322026-01-26
//开启定时器的编码模式

//模拟PID

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim==&htim6)
    {
        EncoderCount1=(short) (TIM3->CNT);
        EncoderCount2=(short) (TIM4->CNT);
        TIM3->CNT=0;
        TIM4->CNT=0;
        Motor1Speed=(float)EncoderCount1*100/30/13/4;//============10ms,所以乘以100
        Motor2Speed=(float)EncoderCount2*100/30/13/4;//速度获取,看后面的速度解释,这里可能不正确

          if(EncoderCount1<20) Motor1Pwm+=1;//控制在20%
          if(EncoderCount1>20) Motor1Pwm-=1;//模拟PID

      if(EncoderCount2<20) Motor2Pwm+=1;//控制在20%
          if(EncoderCount2>20) Motor2Pwm-=1;//模拟PID

          pwm_proc(Motor1Pwm,Motor2Pwm);
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////真实PID

调用PID.c,定义结构体调参即可

注意限幅函数的范围,结构体要初始化

///////////////////////////////////////////////////////////////////////////////////////////////////////速度获取解释

1.首先根据速度的计算公式本质就是:

                                                    v=s/t

已知的编码器计数周期(100ms),s:轮子在这个计数周期内走过的路程。

2.下面就是需要计算s。

我们知道,编码器采集的是单位时间内的脉冲个数,而且编码器的码盘安装在电机轴的末端,测的是电机输出轴的速度,电机轴还需要经过减速器才能和轮子相连。由此,我们可以先算出单位时间内,一个脉冲 轮子走过的距离

                                                l=2∗PI∗R/(4∗n∗i)

2 * PI *R 就是轮子周长,R是轮子半径(34mm),使用4倍频计数,n就是编码器的码盘转一圈的脉冲数(11),i就是电机的减速比(30)。

3.一个脉冲轮子走过的距离是可以直接手算出来的,那么我们再乘以编码器测量的脉冲个数就知道轮子在这个计数周期内走过的路程s了。因此,

s=m∗l

综上,

/**
  * @brief  编码器读数转换为轮子速度(mm/s)
  * @param encoder:编码器计数
  * @retval : Velocity 轮子速度
  */
int Get_Velocity_Form_Encoder(int encoder)
{  
    float Distance,Velocity;
    Distance= 2*3.14159*34/(4*11*30);//单位是mm  
    Velocity= encoder*Distance/0.1;    //单位是mm/s。0.1就是编码器计数周期100ms,0.1s

    return Velocity;//单位是mm/s
}