标题: 步进电机加减速算法设计总结 附stm32单片机控制小车加减速源程序 超详细 [打印本页]

作者: qixing    时间: 2017-4-11 15:49
标题: 步进电机加减速算法设计总结 附stm32单片机控制小车加减速源程序 超详细
最近在研究stm32单片机控制小车加减速,写了一些东西,教程和源程序都有:


步进电机加减速算法设计总结
步进电机已经广泛地应用于工业自动化行业。目前常用的步进电机驱动器接受两个光电耦合信号输入,一个为脉冲,另一个为方向。步进电机驱动器内部不对电机的加减速作任何假设,它根据输入脉冲的频率来控制电机的转速。
在行业应用中,对于执行机构的启动与停止阶段,是有一定要求的。最基本的,要求速度连续,也就是加速度无跳变。因为,加速度与执行机构的出力是成正比的,加速度上的跳变,造就了出力的突变,直接影响就是在机构运行过程中产生冲击。不但在工作过程中有噪音,更大的危害在于缩短了机构的使用寿命。
因此,有必要针对步进电机开发一套合适的加减速算法,来确保电机的速度曲线连续。
本节推到线性速度实现过程中的几个基本关系式。
2.1 步进电机运行基本公式
步进电机驱动器接受脉冲信号,转换为步进电机的转角,一个脉冲转过的角度称为步距角。因此,脉冲的总数决定了一次运动过程中电机的转角,脉冲的频率决定了步进电机的速度。图1表示脉冲出现的时刻,时间t0,t1,t2之间的间隔分别是基础时钟的整数倍,分别为c0和c1
如果定时器的时钟基础频率为ft,那么有
如果步进电机的步距角为alpha,那么可以求出瞬时速度为
同时,步进电机转过的角度为
其中,步距角与步进电机每圈对应的脉冲数有关
Spr就是每圈对应的脉冲数,steps per round
要实现线性速度,需要速度随着时间均匀变化,根据匀加速计算公式有
合并后得到
从该公式中可以得出一个重要结论,那就是当速度一定的时候,步进电机加速度与所需的步数成反比。如果所示
因此,对于给定的总步数以及加速度,减速度,加速的步数与减速的步数是确定的
2.2 线性加减速切换步数
线性加减速的参数包括,最大速度,加速度,减速度,总步数四个。根据参数间的约束关系,分为两种情况,一种是可以到达最大速度运行,另外一种没到达。判定的标准是max_s_lim与accel_lim的大小,max_s_lim是达到最大速度所需的步数,accel_lim是根据给定的加速度与减速度,减速开始所需的步数。
两者的计算方法如下
2.2.1 可以到达最大速度

那么,减速开始的步数为

2.2.2 不能达到最大速度
减速开始的步数为
根据算法原理分析,可以得知,线性加减速算法的核心在于定期改变脉冲的间隔。因此,需要在定时器溢出的时候改变下次溢出时间。
为了区分不同的速度轮廓,需要对给定的运动参数做判别,这个步骤可以在主函数中进行。如果实际运行的过程中,不改变参数,那么固定后可以获得更高的效率。此外,采用定点数来替换浮点运算,加快计算过程。使得该算法可以方便移植到更低端的16位乃至8位单片机上。
3.1 电机运行状态机
为了跟踪电机速度轮廓的各个状态,设计了一个状态机,分别为停止态,加速态,运行态,减速态。各个状态的切换关系如图所示

3.2 主要数据结构
3.2.1 速度轮廓数据SPEED_RAMP_DATA
结构体成员的含义如下
run_state,用来指示电机运行状态
dir 电机运行方向
step_delay 以定时器周期为基数的延时数
decel_start 减速开始对应的步数
decel_val 减速度
min_delay 运行态对应的延时数
accel_count 加速与减速段对应的步数,是个累计值,在加速段从0开始,在减速段以0结束

3.2.2 电机运行标志GLOBAL_FLAGS
running,表示电机是否在运动,一个轴的运动完成以前不允许第二次运动
cmd,表示是否接到了一个运动命令,该变量保留作为上下位机交互调试使用

3.2.3 宏定义
有一些与电机参数有关的宏定义
T1_FREQ 定时器运行频率
SPR 步进电机每转对应的脉冲数
ALPHA 步距角
此外,为了简化计算,以及支持定点运算,定义了一些中间常量,如
A_T_x100
T1_FREQ_148
A_SQ
A_x20000

3.2.4 运动参数MOVE_PARAMS
包含有
              int16_t steps;
              uint16_t accel;
              uint16_t decel;
              uint16_t omega;


1. 梯形加减速算法
这个算法最大的优势在于,不借用任何表格,在每个中断中计算下一个中断发生的时刻,因此节约了大量的内存,给资源紧缺的单机,特别是8bit单片机带来了福音。不过,这个算法在代码上有几个缺陷。
1,采用的是PWM输出引脚。对于步进电机来说,不需要采用PWM,而且一般单片机的PWM脚是硬件绑定的,不灵活。
2,在周期计算函数中,不应该每个中断都更新定时器的预设值,这样就无法得到50%的占空比。
3,代码在波形配置寄存器上少写了一句关键的代码。
4. 算法采用了定点算术,导致数据都偏大,其中某个预定义的宏,编译器提示溢出。
5,如果要进一步增大加速度和速度,不进行特殊处理,会造成32位的数据溢出。
6,对于整形运算中的%,使用了编译器相关的特性,因此会有移植性问题。
诸如此类,不一而足,在向32bit的单片机移植过程中,本工作室对问题都做了修复,确保算法的正确性和适应性。

2. 任意形状的S形加减速
如果从加速度轮廓上看,梯形加减速的加速度是矩形的,而且在速度切换点,加速度从正一下子变为负,会有明显的响声,因此,有必要开发更为平滑的算法。那就是S形加减速。针对S形加减速,具体做法有很多,比较简单的做法是采用sigmoid函数,一切有S形状的函数都可以拿来做基础S函数,比如log函数的变形,sin函数。不过,这些函数在S曲线的计算公式上虽然简单了,但是由于可调参数太少,导致了无法根据现实情况随意更改S曲线形式,缺少灵活性。为此,本工作室在理论推导的基础上推出任意形状的S形曲线算法。具体来说,首先规划运动的加速度,然后积分得到速度轮廓,进而转换为步进电机的频率轮廓。

3. 拟合电机矩频特性加减速
该算法充分利用所选的步进电机特性曲线来选择加减速轮廓,具有最大化电机能力的优点,而且算法占用的空间少,对于特定的步进电机具有带载能力最大化的优点,在小负载测试中发现,使用梯形加减速算法可以在3s内完成无丢步的运动,换为该算法,可以实现2.2s无丢步加减速。

stm32源程序:
  1. /*----------------------------------------------------------------------------*/
  2. //版权信息:    无极电子工作室
  3. //文件名:      s_curve.c
  4. //当前版本:    1.0
  5. //单片机型号:  MB9BF322L
  6. //开发环境:    IAR EWARM7.4
  7. //晶振频率:    4M
  8. //作者:        paul
  9. //功能:        s曲线计算文件
  10. //修订记录:   
  11. //2015-09-28----创建
  12. /*----------------------------------------------------------------------------*/



  13. #include "s_curve.h"



  14. //s曲线加速度各段参数定义
  15. //起始速度
  16. const float f0 = 0;

  17. //加加速度与减减速度,
  18. float faa = 0;
  19. float frr = 0;

  20. //加速段三个时间        
  21. const float taa = 0.1;
  22. const float tua = 0.2;
  23. const float tra = 0.1;

  24. //匀速段        
  25. const float tuu = 5.0;

  26. //减速段        
  27. const float tar = 0.1;
  28. const float tur = 0.2;
  29. const float trr = 0.1;

  30. unsigned int s_curve_table[TABLE_LEN]={0};




  31. static int S_curve_func(
  32.                         S_curve_params_struct *s_params,
  33.                         float t,
  34.                         float *freq,
  35.                         float *acc
  36.                         );









  37. void S_curve_gen(void)
  38. {
  39.                
  40.         unsigned int i,tint;
  41.         float ti;
  42.         float freq,freq_pre;
  43.         float acc,acc_pre;
  44.         float fi;
  45.         S_curve_params_struct s_params;

  46.         s_params.f0 = f0;
  47.         
  48.         s_params.taa = taa;
  49.         s_params.tua = tua;
  50.         s_params.tra = tra;
  51.         s_params.tuu = tuu;
  52.         s_params.tar = tar;
  53.         s_params.tur = tur;
  54.         s_params.trr = trr;


  55.         s_params.faa = 2.0/(s_params.taa*(s_params.taa+s_params.tra+2*s_params.tua));
  56.         s_params.frr = 2.0/(s_params.trr*(s_params.tar+s_params.trr+2*s_params.tur));
  57.         
  58.         for(i = 0;i < TABLE_LEN;i++)
  59.         {
  60.                 fi = i*(taa+tua+tra+tuu+tar+tur+trr)/TABLE_LEN;
  61.                 S_curve_func(&s_params,fi,&freq,&acc);
  62.                
  63.                
  64.                 ti = TMAX - (TMAX - TMIN)*freq;
  65.                 tint = (unsigned int)ti;

  66.                 s_curve_table[i] = tint;
  67.                
  68.         }
  69.         
  70. }

  71. static int S_curve_func(
  72.                         S_curve_params_struct *s_params,
  73.                         float t,
  74.                         float *freq,
  75.                         float *acc
  76.                         )
  77. {
  78.         float A,B,C,D,E,F;
  79.         float f1,f2,f3,f4,f5;
  80.         float Ta,Tu,Tr;
  81.         float fra,far;
  82.         float f0,faa,frr;
  83.         float taa,tua,tra,tuu,tar,tur,trr;

  84.         faa = s_params->faa;
  85.         frr = s_params->frr;
  86.         
  87.         taa = s_params->taa;
  88.         tua = s_params->tua;
  89.         tra = s_params->tra;
  90.         tuu = s_params->tuu;
  91.         tar = s_params->tar;
  92.         tur = s_params->tur;
  93.         trr = s_params->trr;
  94.         
  95.         f0 = s_params->f0;

  96.         fra = faa*taa/tra;
  97.         far = frr*trr/tar;
  98.         
  99.         Ta = taa + tua + tra;
  100.         Tu = tuu;
  101.         Tr = tar + tur + trr;

  102.         A = f0;
  103.         B = f0 - 0.5*faa*taa*taa;
  104.         C = f0 + 0.5*faa*taa*taa + faa*taa*tua + 0.5*fra*(taa+tua)*(taa+tua) - fra*Ta*(taa+tua);

  105.         f1 = f0 + 0.5*faa*taa*taa;
  106.         f2 = f0 + 0.5*faa*taa*taa + faa*taa*tua;
  107.         f3 = 0.5*fra*Ta*Ta + C;

  108.         D = f3 - 0.5*far*(Ta+Tu)*(Ta+Tu);
  109.         f4 = -far*0.5*(Ta+Tu+tar)*(Ta+Tu+tar) + far*(Ta+Tu)*(Ta+Tu+tar) + D;

  110.         E = f4 + far*tar*(Ta+Tu+tar);
  111.         f5 = -far*tar*(Ta+Tu+Tr-trr) + E;

  112.         F = f5 + frr*(Ta+Tu+Tr)*(Ta+Tu+Tr-trr) - 0.5*frr*(Ta+Tu+Tr-trr)*(Ta+Tu+Tr-trr);

  113.         if((t>=0) && (t<=Ta+Tu+Tr))
  114.         {
  115.                 if((t>=0) && (t<=taa))
  116.                 {
  117.                         *freq = 0.5*faa*t*t + A;
  118.                         *acc = faa*t;
  119.                 }
  120.                 else if((t>=taa) && (t<=taa+tua))
  121.                 {
  122.                         *freq = faa*taa*t + B;
  123.                         *acc = faa*taa;
  124.                 }
  125.                 else if((t>=taa+tua) && (t<=taa+tua+tra))
  126.   

  127. …………限于本文篇幅 余下代码请从51黑下载附件…………

复制代码


资料下载:
s型加减速.rar (1.97 MB, 下载次数: 859)



作者: cm7626    时间: 2017-4-17 16:36
很难得的好资料 下载了
作者: qq2512262471    时间: 2017-4-19 00:20
感谢分享!
作者: crazyboytu    时间: 2017-7-11 10:29
请问楼主,程序里面的参数怎么来的啊?有算法解析吗?
作者: donydong    时间: 2017-7-31 12:34
非常好,下来学习一下
作者: 维超    时间: 2017-7-31 23:02
非常好的资料。感谢楼主分享
作者: roguebear    时间: 2017-8-17 21:09
这个不就是抄的AN446的嘛
作者: amos235    时间: 2017-8-20 16:44
谢谢谢 好资料,51黑有你更精彩!!!

作者: sddzycnq    时间: 2017-11-24 09:21
感谢分享,但黑币不够。汗。
作者: 穿山跃海    时间: 2017-11-28 11:01
AVR446的算法,赞!
作者: wuxishun    时间: 2017-11-29 18:36
下载学习了
作者: a274    时间: 2017-12-25 22:08
很难得的好资料,只能看
作者: 摩卡馍馍123    时间: 2017-12-28 14:03
谢谢分享
作者: 摩卡馍馍123    时间: 2017-12-28 14:23
非常谢谢
作者: 摩卡馍馍123    时间: 2017-12-28 14:23
谢谢!谢谢!谢谢!
作者: zyw20012    时间: 2018-1-2 21:40
楼主,怎么样才能联系到你,我的扣扣179687307求联系
作者: soul85    时间: 2018-1-4 15:10
niu
正好在研究 算法很复杂
作者: ycgxy1650601    时间: 2018-2-6 15:07
谢谢分享
作者: nmvxcsdf    时间: 2018-3-19 17:27
谢谢分享
作者: zhouke    时间: 2018-3-20 07:56
谢谢分享
作者: yun_2106118    时间: 2018-4-10 17:47
多谢楼主好东东
作者: yun_2106118    时间: 2018-4-10 17:48
多谢楼主的资料,值得参考
作者: 圣诞树枝    时间: 2018-4-17 16:14
很棒的资料,正有需要
作者: deanj123    时间: 2018-4-19 08:37
谢谢分享
作者: Wilson_Chen    时间: 2018-4-22 12:02
不是很明白,顶一下
作者: 烟花绽放    时间: 2018-4-23 11:35
先下载学习一下,谢谢楼主分享
作者: yhummqj    时间: 2018-4-23 14:41

谢谢分享
作者: yanzy_002    时间: 2018-4-23 14:59
正好在使用步进电机梯形算法,换向时冲击力较大,希望此算法能解决这个问题
作者: jianshijie    时间: 2018-4-24 09:56
谢谢分享,要慢慢看啊,希望能搞懂
作者: zhwtang123    时间: 2018-4-25 17:20
很棒的资料,正有需要
作者: zhwtang123    时间: 2018-4-25 17:21
很棒的资料,正有需要
作者: zhwtang123    时间: 2018-4-25 17:49
正是我所需要的,多谢分享
作者: Eleven_1ing    时间: 2018-4-25 20:36
感谢分享,51黑电子有你更精彩
作者: caibihui163    时间: 2018-4-25 20:50
好资料,点个赞!
作者: wwchang    时间: 2018-4-26 12:33
好东西啊,正需要
作者: tiansa521    时间: 2018-4-26 14:40
学习中,多谢楼主
作者: wwchang    时间: 2018-4-26 19:37
楼主做得很详细,很到位。正需要呢
作者: 喜欢就Mark    时间: 2018-5-2 14:45
分析得很到位,最近正缺这一理论知识引导~
作者: kh99827765    时间: 2018-5-3 15:49
多谢楼主分享,正在学习这块。。。
作者: 389056325    时间: 2018-5-7 10:30

多谢楼主分享,正在学习这块。。。
作者: 年少有点狂    时间: 2018-5-13 12:23
学习学习
作者: 摸两摸    时间: 2018-5-14 08:53
正好需要,谢谢楼主的分析分享

作者: xiaozhi0725    时间: 2018-5-16 14:43
谢谢楼主的分享
作者: xiaozhi0725    时间: 2018-5-16 14:44
谢谢楼主的分享
作者: _风云无忌_    时间: 2018-5-23 11:26
点赞!
作者: 12345666ii    时间: 2018-5-24 15:24
高手  谢谢分享!!
作者: xode    时间: 2018-5-24 16:13
很专业,谢谢分享
作者: ffww123    时间: 2018-5-27 22:42
很好,分不够
作者: jiaogn    时间: 2018-5-28 02:16
分不够,等攒分哦。   
作者: 竹鼠商    时间: 2018-5-28 09:37
感谢分享,下载了以后说不定用得到
作者: qq799225734    时间: 2018-5-30 21:22
谢谢大佬分享,学习学习~~~~~~~~
作者: xode    时间: 2018-6-3 21:58
谢谢分享
作者: tdi110    时间: 2018-6-5 22:44
非常好,下来学习一下
作者: asd18989199010    时间: 2018-6-6 23:24
非常感谢,正需要这东西
作者: YQ_S    时间: 2018-6-19 09:45
有谁正常使用了么?为什么我的并不能使用
作者: wcyingdream    时间: 2018-6-26 17:14
好东西,下载下来学习下
作者: cccccccccccccc    时间: 2018-7-16 15:10
东西是好东西,可惜。大哥一点点注解都没有,读起来想扔掉
作者: lingaoxun    时间: 2018-7-26 15:40
很棒的资料,正有需要
作者: 泡泡无敌    时间: 2018-7-27 09:54
非常常用步进电机S曲线算法控制,感谢楼主的无私分享
作者: calvinxxw    时间: 2018-8-2 18:23
难得的好资料。
作者: qjw    时间: 2018-8-6 11:24
感谢分享
作者: zjg0123    时间: 2018-8-8 17:53
感谢楼主,最近正好在研究步进电机控制方面的问题
作者: onono    时间: 2018-8-9 11:34
最近正在学习步进电机调速,还有595级联。感谢分享~
作者: cjk_623256405    时间: 2018-8-9 13:59
很给力,谢谢楼主!!
作者: yang_2018    时间: 2018-8-23 14:37
感谢分享 学习了
作者: yang_2018    时间: 2018-8-23 15:10
非常感谢
学习了
作者: xode    时间: 2018-8-26 19:37
很好,值得研究研究
作者: 路人停下    时间: 2018-9-6 14:39
多谢楼主分享!!
作者: cooldog123pp    时间: 2018-9-10 14:07
学习了,
作者: 上善若水123456    时间: 2018-9-10 16:19
谢谢楼主分享!
作者: 悲天悯人    时间: 2018-10-12 13:24
感谢分享,下载学习一下
作者: blk26782    时间: 2018-12-4 18:19
楼主厉害,顶顶-----顶
作者: blk26782    时间: 2018-12-4 18:20
腻害!!!
作者: ancle520    时间: 2018-12-19 16:11
多谢分享,学习学习
作者: bucker    时间: 2018-12-21 21:51
学习了
作者: 温宝愉    时间: 2019-6-6 23:03
谢谢楼主的分享!
作者: 温宝愉    时间: 2019-6-8 11:41
所以这个程序里边对应的管脚输出除了有GPIOA.2(控制LED的输出)?还有哪些管脚的输出是用来控制步进电机加减速呢,求解答!
作者: 鹏博士PBs    时间: 2019-6-11 08:02
不错的资源 值得分享
作者: lsf1949    时间: 2019-6-19 12:11
非常好
作者: 鹏博士PBs    时间: 2019-6-19 19:36
涨知识了
作者: q779883414    时间: 2019-7-9 16:11
谢谢分享,看不懂!
作者: 鹏博士PBs    时间: 2019-7-10 09:43
感谢楼主的分享 受益匪浅
作者: slg17    时间: 2019-7-11 20:55
想用一下
作者: xiaozhong1314    时间: 2019-7-14 09:25
学习中,算法很复杂啊
作者: dasdad    时间: 2019-7-14 15:29
赞一个
作者: dasdad    时间: 2019-7-14 15:30
非常好的资料
作者: 流222    时间: 2019-8-16 19:33
很给力

作者: 鹏博士PBs    时间: 2019-8-17 00:52
参数怎么调试啊
作者: wdliming    时间: 2019-9-14 16:33
真的很想看。
作者: calvinxxw    时间: 2019-9-28 10:29
谢谢分享
作者: _少年放肆的梦    时间: 2019-10-24 15:18
nice,资料给力
作者: ashamed    时间: 2019-10-24 20:36

感谢分享
作者: 卡修达    时间: 2020-1-6 11:23
嗯嗯  很不错的资料
作者: hellowC8051    时间: 2020-1-10 09:00
多谢楼主分享,可以少走弯路
作者: khjkhjhkj    时间: 2021-8-2 15:45
请问axis和step代表什么
作者: lengrudie    时间: 2021-10-29 16:53
是不是运算太多了,这么多浮点运算,感觉不实用
作者: li64331218    时间: 2023-3-20 22:11
顶起,时时刻刻都要回看。才知道哪里可以改进。学习了
作者: STM32Study1    时间: 2023-3-31 10:27
对原作者的文档理解十分到位,通透,赞一个
作者: huaishang    时间: 2024-7-22 17:08
非常好的资料。感谢楼主分享
作者: huaishang    时间: 2024-8-28 14:38
非常好的资料。感谢楼主分享!




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1