在我们做小项目的时候,PID和PWM总会扯上关系,如果理论知识不足便会含糊不清,不明白这些术语之间的关系。例如在PID电机调速模型中我们想要的控制量明明是转速,可为什么可以改变的只能是PWM值,PWM值和转速,PWM和PID又有什么关系呢?

什么是PID

PID控制框图

                                                               1-1  PID控制框图

        如图,这是一个典型的单环PID控制框图,所谓PID是一种通过反馈让控制量去逼近实际值的校正装置(算法),例如我们让电机输出20r/min,我们可能给一个合理的输入值也就是r(t),但输入后电机真能达到20r/min吗?不一定!可能是硬件,程序的不合理也可能是因为电磁干扰,一次手指在马达轴上的触动,便会产生误差。误差error为输出减去输入,简写为时域上的e(t)。

        PID控制器,是目前工业界常用的矫正装置,通过把比例,微分,积分的各种组合以及相互作用可以消除误差,让输入无限趋近于输出,理论部分我就不再赘述了。我们重点在于如何解析这个结构图,理清PID,PWM,转速之间的关系。

单环PID控制结构图的解析

        所谓的单环就是由输出反馈到输入的一个闭环,他像一个圆环一样将自己包裹起来形成一个典型的闭环结构。

        如图1-1的控制框图中有多个时域上可传递的变量分别是"输入r(t)","误差e(t)","经过PID控制器后输出的控制量u(t)","输出量c(t)",注意一点u(t)才是真正输入到执行机构的物理量,在我们编程时控制电机转速中u(t)是最直接输入给电机的PWM值

        让我们按照流程来梳理一下单片机是如何通过PID控制器来控制电机转速的。假设我们期望的电机转速是20rpm/min,你会在程序中输入一个期望转速转速r(t),并且期望电机输出的转速c(t)为20rpm/min,但我们通过编码器采集到的电机实际输出可能是21rpm/min或者是19rpm/min,这样我们的期望电机转速和实际电机转速之间就产生了误差e(t)。

        误差=期望值-实际值,在图中的表现为电机的输出c(t)引出一根线回到了输入处,在输入处有一个内部为X的圆圈,这个圆圈叫做比较点,比较点的上方是+号代表r(t)的符号是正的,比较点的下方是负号,表示c(t)的符号是负的这样就形成了一个负反馈结构,e(t)=r(t)-c(t)。在PID控制器的两端左边是e(t),右侧是u(t) ,而PID的作用是通过把误差加权得到一个新的量u(t)从而使我们的被控对象输出我们期望的值。通过一次又一次的调节便可以让误差减小到几乎为0。

PWM与转速的关系

        在我们以前的学习过程中我们知道可以调节PWM值来控制转速,占空比设置的大电机转的就快,占空比设置较小转速调节的就慢。那么PWM值和电机的转速应该有一个函数关系。这其实涉及到一个标度变换的概念。比如我们的电机到达额定电压的转速范围为0-128r,占空比的范围为0-100%,那么每增加1%的占空比就会变化1.28r的转速,但是受各种偏差影响变化1%的占空比不可能准确的变化1.28r,如果我们希望更精确的达到设定的转速比如我们希望达到20r/min,把实际转速控制在19.95-20.12r之间,我们可以去更改分辨率,来让占空比变化度更加微小比如每个单位只变化0.01%,这样更容易减小实际转速和理想转速的误差。

void TIM2_PWM_Init()
{  
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);   
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  

 
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    TIM_TimeBaseStructure.TIM_Period = 1000;
    TIM_TimeBaseStructure.TIM_Prescaler =72-1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); 
    
 
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High ; 
    TIM_OC1Init(TIM2, &TIM_OCInitStructure);  

    TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);  
 
    TIM_Cmd(TIM2, ENABLE);  
    TIM_SetCompare1(TIM2,0);
}

        我们以STM32的TIM2的PWM模式输出PWM举例如何更改分辨率,自动重装载值设定为1000,CCR1比较寄存器的值每增加1,就相当于占空比值增加了0.1%。如果自动重装载值设定为10000,那比较寄存器每增加1,就相当于占空比增加了0.01%这就起到了改变分辨率的作用。具体情况根据项目调试更改。

PID与PWM的关系

        在在上述部分讲述了转速和PWM的转化关系。在实际单片机控制电机转速的编程中,图1-1各个参量r(t),e(t),u(t),c(t)都需要转化成PWM值。还是电机达到20rpm/min转速的例子,开始我们给一个合理的PWM值,电机开始加速旋转,在它加速旋转的这段时间内,由编码器反馈的值(编码器反馈的是转速需要标度变换为PWM值)不断与上一次输入的PWM进行作差,得到的误差值(同样也是PWM值),进入PID控制器,PID控制器通过算法对误差值进行加权而后PID控制器输出的控制量,使得电机最终稳定在20rpm/附近。

更多推荐