当前位置:   article > 正文

FPGA学习笔记(5)——步进电机梯形加减速算法_fpga 步进电机加减速

fpga 步进电机加减速

使用加减速的目的是:防止步进电机的启动频率过快而无法正常启动,避免控制脉冲频率变化过大造成电机丢步或过冲。

空载启动频率,即步进电机在空载情况下能够正常启动的脉冲频率,如果脉冲频率高于该值,电机不能正常启动,可能发生丢步或堵转。在有负载的情况下,启动频率应更低。如果要使电机达到高速转动,脉冲频率应该有加速过程,即启动频率较低,然后按一定加速度升到所希望的高频(电机转速从低速升到高速)。

步进电机的基本概念及控制模式参考如下链接:

https://www.elecfans.com/d/1294049.html


通过梯形加减速要达到的效果:

  • 控制脉冲频率从0到期望速度有直线加减速的过程;
  • 电机运动结束能够到达指定的位置,即经过加减速曲线后能够准确在预期位置处停止。

梯形加减速的算法实现

梯形加减速的位移、速度、加速度曲线如图1所示,速度曲线分为加速、匀速、减速三个部分。

图1 梯形加减速示意图

    图2所示,对直线加速段进行离散,在0-ta之间插入若干中间速度值,控制速度从小到大取值,即可实现直线加速。本次设计采用对0-ta进行n等分,每一份的时间为t_s=ta/n,也是将期望速度(speed)进行n等分,即在加速段均匀插入n-1个中间速度值,每经过时间t_s,对当前速度加 speed/n ,直到达到期望速度speed。减速过程与之相反。

本次设计只实现图2所示的加减速情况,n=100。

图2 离散化后的直线加减速速度变化曲线


梯形加减速模块框图如图3所示

图3

功能说明:上位机传送电机目标位置、目标速度、加速时间、减速时间,经过加减速模块后,能够在目标位置准确停下。

引脚说明

Clk

系统时钟50MHz

Rst_n

复位信号,低电平有效

Step

电机目标位置,输入脉冲个数。示例代码中为64000

Speed

电机目标速度,输入脉冲频率(hz)。示例代码中为100khz

T_accel

加速时间(ms)。示例代码中为300ms

T_decel

减速时间(ms)。示例代码中为400ms

Pul

输出脉冲信号


各个模块定义

1. 定时计数模块

在加速或减速控制开启状态下启动该计数器,加速计数的时间为t_s=ta/n,减速计数的时间为

t_s=(tc-tb)/n

代码:

  1. assign T_clk = 26'd50_000_000;
  2. assign CNT_up = (t_accel*T_clk)/100000; //acc time;计数器的计数值
  3. assign CNT_dn = (t_decel*T_clk)/100000; //dec time
  4. always@(posedge clk or negedge rst_n)
  5. begin
  6. if (!rst_n)
  7. cnt_up <= 'b0;
  8. else if(cnt_up == CNT_up - 1'b1)
  9. cnt_up <= 'b0;
  10. else if(up_en)
  11. //加速使能有效时才开始计数,所以speed_current赋值条件为cnt_up == 0
  12. cnt_up <= cnt_up + 1'b1;
  13. end
  14. always@(posedge clk or negedge rst_n)
  15. begin
  16. if (!rst_n)
  17. cnt_dn <= 'b0;
  18. else if(cnt_dn == CNT_dn - 1'b1)
  19. cnt_dn <= 'b0;
  20. else if(down_en)
  21. cnt_dn <= cnt_dn + 1'b1;
  22. end

2. 加减速使能模块

通过比较当前脉冲数与加速阶段的总脉冲数和需要减速时的脉冲数,确定加速使能信号up_en和减速使能信号down_en。

图2所示,加速阶段的总脉冲数为红线下方的面积,即CNT_sup=1/2×Vt×(ta-ta/n)

注意单位转换:hz X s,得到的是脉冲数,减速阶段同理。

代码:

  1. assign CNT_con= step_target - speed_target*(t_decel-t_decel/100)/2000;
  2. //when dec time ,减速的时间点,总脉冲数减去加减速总共所需的脉冲数,hz x s,得出的才是脉冲个数
  3. assign CNT_sup= speed_target*(t_accel-t_accel/100)/2000;
  4. //加速阶段的脉冲总数
  5. always@(posedge clk or negedge rst_n) //加减速的使能条件要合理布置,用速度作为判断条件时容
  6. //易出错
  7. begin
  8. if(!rst_n) begin
  9. up_en <= 'b0;
  10. down_en <= 'b0;
  11. end
  12. else if (cnt_con <= CNT_sup) //当输出脉冲个数小于等于加速阶段的总脉冲数时,置一
  13. up_en <= 1'b1;
  14. else if (cnt_con > CNT_con && speed_current > 'b0)
  15. //when dec,当到达减速点时,给减速使能置一,同时条件还必须包括speed_current > 'b0,
  16. //减速到0时,该条件会永远满足,一直减速下去
  17. down_en <= 1'b1;
  18. else begin
  19. up_en <= 1'b0;
  20. down_en <= 1'b0;
  21. end
  22. end

3. 加减速变化模块

当加速使能信号up_en为真时,对当前速度加speed/n,当减速使能信号down_en为真时,对当前速度减speed/n

代码:

  1. always@(posedge clk or negedge rst_n)
  2. begin
  3. if(!rst_n)
  4. speed_current <= 'b0;
  5. else if(up_en && cnt_up == 0) //必须是在up_en刚刚有效时就进行加减速
  6. speed_current <= speed_current + speed_target/100;
  7. else if(down_en && cnt_dn == 0)
  8. speed_current <= speed_current - speed_target/100;
  9. else
  10. speed_current <= speed_current ;
  11. end

4. 脉冲输出模块

计算出当前速度对应的脉冲周期,进而计算出计数器计数到周期值所对应的计数值。

CNT_per= T_clk/speed_current;

代码:

  1. assign CNT_per= T_clk/speed_current; //pulse out,当前速度对应的脉冲周期的计数值
  2. always@(posedge clk or negedge rst_n) //输出脉冲的周期计数器
  3. begin
  4. if (!rst_n)
  5. cnt_per <= 'b0;
  6. else if(cnt_per == CNT_per - 1'b1 || cnt_up == CNT_up - 1'b1
  7. || cnt_dn == CNT_dn - 1'b1) //清零条件要加上 cnt_up和cnt_dn计数到最大值减一时,
  8. //因为下一段的速度值与前一段不同,速度变化后要重新开始
  9. //对输出脉冲周期的计数
  10. cnt_per <= 'b0;
  11. else cnt_per <= cnt_per + 1'b1;
  12. end
  13. //pulse out
  14. always@(posedge clk or negedge rst_n)
  15. begin
  16. if(!rst_n)
  17. pul <= 'b0;
  18. else if(cnt_per == CNT_per/2-1 || cnt_per == CNT_per-1) //脉冲输出,中间结束各翻转一次
  19. pul <= ~pul;
  20. else pul <= pul;
  21. end

5. 脉冲计数模块

记录输出脉冲的个数,且只能计数到目标位置。

  1. always@(posedge clk or negedge rst_n)
  2. begin
  3. if (!rst_n)
  4. cnt_con <= 'b0;
  5. else if(cnt_per == CNT_per - 1'b1 && cnt_con != step_target)
  6. // 脉冲周期计数器计满且输出脉冲个数不等于要求个数时才加1
  7. // 计数器只计数一次的写法
  8. cnt_con <= cnt_con + 1'b1;
  9. else cnt_con <= cnt_con;
  10. end


仿真结果

  • Speed_current的波形满足直线加减速曲线;
  • 实际加速时间是297ms,减速时间是396ms;
  • 在输出脉冲数为64000时,Speed_current正好减速到0,电机停止。

满足预期的功能要求。

图4 直线加减速仿真结果图


完整代码如下:

Rtl:

  1. module linear_acc_dec(
  2. input clk,
  3. input rst_n,
  4. input [15:0] step_target, // pulse_count
  5. input [16:0] speed_target, // hz
  6. input [8:0] t_accel, // ms
  7. input [8:0] t_decel,
  8. output reg pul
  9. );
  10. //0-speed_target Insert 100 intermediate values
  11. wire [33:0] CNT_up; //counter 3ms/20ns
  12. wire [34:0] CNT_dn; //声明位宽时,不能只看结果值,要能容下计算过程中的最大值
  13. reg [17:0] cnt_up;
  14. reg [17:0] cnt_dn;
  15. reg [16:0] speed_current;
  16. reg up_en;
  17. reg down_en;
  18. wire [15:0] CNT_per;
  19. reg [15:0] cnt_per; //T-pul period
  20. wire [15:0] CNT_con;
  21. reg [15:0] cnt_con; //pulse count
  22. wire [15:0] CNT_sup;
  23. wire [25:0] T_clk ;
  24. assign T_clk = 26'd50_000_000;
  25. assign CNT_up = (t_accel*T_clk)/100000; //acc time
  26. assign CNT_dn = (t_decel*T_clk)/100000; //dec time
  27. assign CNT_per= T_clk/speed_current; //pulse out
  28. assign CNT_con= step_target - speed_target*(t_decel-t_decel/100)/2000;
  29. //when dec time
  30. assign CNT_sup= speed_target*(t_accel-t_accel/100)/2000;
  31. always@(posedge clk or negedge rst_n)
  32. begin
  33. if (!rst_n)
  34. cnt_up <= 'b0;
  35. else if(cnt_up == CNT_up - 1'b1)
  36. cnt_up <= 'b0;
  37. else if(up_en)
  38. cnt_up <= cnt_up + 1'b1;
  39. end
  40. always@(posedge clk or negedge rst_n)
  41. begin
  42. if (!rst_n)
  43. cnt_dn <= 'b0;
  44. else if(cnt_dn == CNT_dn - 1'b1)
  45. cnt_dn <= 'b0;
  46. else if(down_en)
  47. cnt_dn <= cnt_dn + 1'b1;
  48. end
  49. //100 intermediate values
  50. always@(posedge clk or negedge rst_n)
  51. begin
  52. if(!rst_n)
  53. speed_current <= 'b0;
  54. else if(up_en && cnt_up == 0)
  55. speed_current <= speed_current + speed_target/100;
  56. else if(down_en && cnt_dn == 0)
  57. speed_current <= speed_current - speed_target/100;
  58. else
  59. speed_current <= speed_current ;
  60. end
  61. //up_en,down_en
  62. always@(posedge clk or negedge rst_n)
  63. begin
  64. if(!rst_n) begin
  65. up_en <= 'b0;
  66. down_en <= 'b0;
  67. end
  68. else if (cnt_con <= CNT_sup)
  69. up_en <= 1'b1;
  70. else if (cnt_con > CNT_con && speed_current > 'b0)//when dec
  71. down_en <= 1'b1;
  72. else begin
  73. up_en <= 1'b0;
  74. down_en <= 1'b0;
  75. end
  76. end
  77. //pulse count
  78. always@(posedge clk or negedge rst_n)
  79. begin
  80. if (!rst_n)
  81. cnt_con <= 'b0;
  82. else if(cnt_per == CNT_per - 1'b1 && cnt_con != step_target)
  83. cnt_con <= cnt_con + 1'b1;
  84. else cnt_con <= cnt_con;
  85. end
  86. //cnt_pulse out
  87. always@(posedge clk or negedge rst_n)
  88. begin
  89. if (!rst_n)
  90. cnt_per <= 'b0;
  91. else if(cnt_per == CNT_per - 1'b1 || cnt_up == CNT_up - 1'b1
  92. || cnt_dn == CNT_dn - 1'b1)
  93. cnt_per <= 'b0;
  94. else cnt_per <= cnt_per + 1'b1;
  95. end
  96. //pulse out
  97. always@(posedge clk or negedge rst_n)
  98. begin
  99. if(!rst_n)
  100. pul <= 'b0;
  101. else if(cnt_per == CNT_per/2-1 || cnt_per == CNT_per-1)
  102. pul <= ~pul;
  103. else pul <= pul;
  104. end
  105. endmodule

Tb:

  1. `timescale 1ns/1ns
  2. `define clk_period 20
  3. module tb();
  4. reg clk ;
  5. reg rst_n ;
  6. reg [15:0] step_target ;
  7. reg [16:0] speed_target ;
  8. reg [8:0] t_accel ;
  9. reg [8:0] t_decel ;
  10. wire pul ;
  11. initial begin
  12. clk <= 'b0;
  13. rst_n <= 'b0;
  14. #(`clk_period)
  15. rst_n <= 'b1;
  16. step_target <= 64000;
  17. speed_target<=100000;
  18. t_accel <= 300;
  19. t_decel <= 400;
  20. #(`clk_period*50000000)
  21. $stop ;
  22. end
  23. always #(`clk_period/2) clk<=~clk;
  24. linear_acc_dec
  25. u1
  26. (
  27. .clk (clk ),
  28. .rst_n (rst_n ),
  29. .step_target (step_target ),
  30. .speed_target (speed_target ),
  31. .t_accel (t_accel ),
  32. .t_decel (t_decel ),
  33. .pul (pul )
  34. );
  35. endmodule

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

闽ICP备14008679号