当前位置:   article > 正文

FPGA实现电机位置环、速度环双闭环PID控制_基于fpga直流电机的速度闭环pid控制

基于fpga直流电机的速度闭环pid控制

一、设计思路

        主要设计思路就是根据之前写的一篇FPGA实现电机转速PID控制,前面已经实现了位置环的控制,思想就是通过电机编码器的当前位置值不断地修正PID去控制速度。

        那为了更好的实现控制,可以在位置环后加上速度环,实现电机位置环、速度环双闭环PID控制

        位置环作为外环,通过编码器计数通过PID输出速度;位置环输出的速度作为目标速度输入速度环,与编码器测速的当前速度进行PID计算,从而完成电机的双PID控制。

​​

       

二、位置环控制

位置环的控制在前面已经实现,再次不再赘述。

三、速度环控制

        速度环作为内环,目标值为位置环输出的速度,当前值为编码器测速的速度。        

        这里就有了一个问题,编码器怎么样才能测到电机速度?

        这就和电机的最大频率有关,编码器通过AB相位的波形去进行计数和正反转的判断,那么就需要知道电机转一圈所输出的脉冲个数以及空载最大转速,通过这两个参数计算出编码器的电机最大频率,即每秒会有多少个脉冲。因此要对时钟进行分频,这是对50MHZ时钟分频成100HZ,即时钟周期10ms进行一次PID输出。

  1. always @(posedge clk or negedge reset_n) begin
  2. if (~reset_n) begin
  3. clk100 <= 1'b0;
  4. clk_counter <= 32'd0;
  5. end else if (clk_counter == 32'd249999)begin
  6. //分频系数M=时钟输入频率/时钟输出频率,偶分频计数器值N=M/2;奇分频计数器值N=M-1/2
  7. clk100 <= ~clk100;
  8. clk_counter <= 32'd0;
  9. end else begin
  10. clk_counter <= clk_counter + 1;
  11. end
  12. end

速度环的PID计算同位置环一样

  1. always @(posedge clk100 or negedge reset_n) begin
  2. if (~reset_n) begin
  3. error <= 0;
  4. integral <= 0;
  5. prev_error <= 0;
  6. derivative <= 0;
  7. pidoutput <= 0;
  8. end else begin
  9. //target位置环输出的速度,current当前编码器值
  10. error <= target - current;
  11. // 将累积误差控制合理范围内
  12. integral <= integral + error;
  13. if(integral >= $signed(32'd500)) begin
  14. integral <= $signed(32'd500);
  15. end else if(integral <= $signed(-32'd500M)) begin
  16. integral <= $signed(-32'd500);
  17. end else begin
  18. integral <= integral;
  19. end
  20. derivative <= error - prev_error;
  21. // 计算PID输出
  22. p <= error * kp;
  23. i <= integral * ki;
  24. d <= derivative * kd;
  25. pidoutput <= (p + i + d) / 1000;
  26. end
  27. end

四、编码器测速

        编码器模块也需要加入测速代码,有两种测速方法:一种是两次位置值相减,得出电机速度;另一种是编码器计数,得出电机速度。

        这里用第二种编码器计数,在速度环中每10ms输出一次PID值,那么在测速模块就每10ms将速度编码器置零重新计数,因此可以根据速度环传入的清零信号clear进行清零,即clk100。当clk100状态发生变化时,clear信号为1,清零速度计数。

  1. always@(posedge clk or negedge reset_n) begin
  2. if(!reset_n) begin
  3. delay0 <= 1'b0;
  4. delay1 <= 1'b0;
  5. end else begin
  6. delay0 <= clk100;
  7. delay1 <= delay0;
  8. end
  9. end
  10. assign clear = (delay0 & (~delay1));
  11. always @(posedge clk or negedge reset_n) begin
  12. if (~reset_n) begin
  13. counter <= 0;
  14. end
  15. else if (clear) begin
  16. counter <= 0;
  17. end
  18. else if(pulse) begin
  19. if(direction) begin
  20. if(counter < $signed(32'h8000))
  21. counter <= counter + 1;
  22. end
  23. else if(!direction) begin
  24. if(counter > $signed(-32'h8000))
  25. counter <= counter - 1;
  26. end
  27. else begin
  28. counter <= 0;
  29. end
  30. end
  31. end

五、整体结构

 整体的RTL图如图所示。  

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/713162
推荐阅读
相关标签
  

闽ICP备14008679号