1. /**************************************************************************
    2. 函数功能:位置式PID控制器
    3. 入口参数:编码器测量位置信息,目标位置
    4. 返回 值:电机PWM
    5. 根据位置式离散PID公式
    6. pwm=Kp*e(k)+Ki*∑e(k)+Kd[e(k)-e(k-1)]
    7. e(k)代表本次偏差
    8. e(k-1)代表上一次的偏差
    9. ∑e(k)代表e(k)以及之前的偏差的累积和;其中k为1,2,,k;
    10. pwm代表输出
    11. **************************************************************************/
    12. int Position_PID (int Encoder,int Target)
    13. {
    14. float Position_KP=80,Position_KI=0.1,Position_KD=500; //这里的PID参数需要调整
    15. static float Bias,Pwm,Integral_bias,Last_Bias;
    16. Bias=Encoder-Target; //求出速度偏差,由测量值减去目标值。
    17. Integral_bias+=Bias; //求出偏差的积分
    18. Pwm=Position_KP*Bias+Position_KI*Integral_bias+Position_KD*(Bias-Last_Bias); //位置式PID控制器
    19. Last_Bias=Bias; //保存上一次偏差
    20. return Pwm; //增量输出
    21. }

    其他函数:

    1. int Target_position=11000; //初始值是10000,目标值是11000
    2. int TIM3_IRQHandler(void)
    3. {
    4. if(TIM3->SR&0X0001)//10ms定时中断
    5. {
    6. TIM3->SR&=~(1<<0); //===清除定时器1中断标志位
    7. Encoder=Read_Encoder(2); //===读取编码器的位置数据 初始值是10000
    8. Led_Flash(100); //===LED闪烁;指示单片机正常运行
    9. Moto1=Position_PID(Encoder,Target_position); //===位置PID控制器
    10. Xianfu_Pwm(); //===PWM限幅
    11. Set_Pwm(Moto1); //===赋值给PWM寄存器
    12. }
    13. return 0;
    14. }