最近在研究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源程序:
- /*----------------------------------------------------------------------------*/
- //版权信息: 无极电子工作室
- //文件名: s_curve.c
- //当前版本: 1.0
- //单片机型号: MB9BF322L
- //开发环境: IAR EWARM7.4
- //晶振频率: 4M
- //作者: paul
- //功能: s曲线计算文件
- //修订记录:
- //2015-09-28----创建
- /*----------------------------------------------------------------------------*/
- #include "s_curve.h"
- //s曲线加速度各段参数定义
- //起始速度
- const float f0 = 0;
- //加加速度与减减速度,
- float faa = 0;
- float frr = 0;
- //加速段三个时间
- const float taa = 0.1;
- const float tua = 0.2;
- const float tra = 0.1;
- //匀速段
- const float tuu = 5.0;
- //减速段
- const float tar = 0.1;
- const float tur = 0.2;
- const float trr = 0.1;
- unsigned int s_curve_table[TABLE_LEN]={0};
- static int S_curve_func(
- S_curve_params_struct *s_params,
- float t,
- float *freq,
- float *acc
- );
- void S_curve_gen(void)
- {
-
- unsigned int i,tint;
- float ti;
- float freq,freq_pre;
- float acc,acc_pre;
- float fi;
- S_curve_params_struct s_params;
- s_params.f0 = f0;
-
- s_params.taa = taa;
- s_params.tua = tua;
- s_params.tra = tra;
- s_params.tuu = tuu;
- s_params.tar = tar;
- s_params.tur = tur;
- s_params.trr = trr;
- s_params.faa = 2.0/(s_params.taa*(s_params.taa+s_params.tra+2*s_params.tua));
- s_params.frr = 2.0/(s_params.trr*(s_params.tar+s_params.trr+2*s_params.tur));
-
- for(i = 0;i < TABLE_LEN;i++)
- {
- fi = i*(taa+tua+tra+tuu+tar+tur+trr)/TABLE_LEN;
- S_curve_func(&s_params,fi,&freq,&acc);
-
-
- ti = TMAX - (TMAX - TMIN)*freq;
- tint = (unsigned int)ti;
- s_curve_table[i] = tint;
-
- }
-
- }
- static int S_curve_func(
- S_curve_params_struct *s_params,
- float t,
- float *freq,
- float *acc
- )
- {
- float A,B,C,D,E,F;
- float f1,f2,f3,f4,f5;
- float Ta,Tu,Tr;
- float fra,far;
- float f0,faa,frr;
- float taa,tua,tra,tuu,tar,tur,trr;
- faa = s_params->faa;
- frr = s_params->frr;
-
- taa = s_params->taa;
- tua = s_params->tua;
- tra = s_params->tra;
- tuu = s_params->tuu;
- tar = s_params->tar;
- tur = s_params->tur;
- trr = s_params->trr;
-
- f0 = s_params->f0;
- fra = faa*taa/tra;
- far = frr*trr/tar;
-
- Ta = taa + tua + tra;
- Tu = tuu;
- Tr = tar + tur + trr;
- A = f0;
- B = f0 - 0.5*faa*taa*taa;
- C = f0 + 0.5*faa*taa*taa + faa*taa*tua + 0.5*fra*(taa+tua)*(taa+tua) - fra*Ta*(taa+tua);
- f1 = f0 + 0.5*faa*taa*taa;
- f2 = f0 + 0.5*faa*taa*taa + faa*taa*tua;
- f3 = 0.5*fra*Ta*Ta + C;
- D = f3 - 0.5*far*(Ta+Tu)*(Ta+Tu);
- f4 = -far*0.5*(Ta+Tu+tar)*(Ta+Tu+tar) + far*(Ta+Tu)*(Ta+Tu+tar) + D;
- E = f4 + far*tar*(Ta+Tu+tar);
- f5 = -far*tar*(Ta+Tu+Tr-trr) + E;
- F = f5 + frr*(Ta+Tu+Tr)*(Ta+Tu+Tr-trr) - 0.5*frr*(Ta+Tu+Tr-trr)*(Ta+Tu+Tr-trr);
- if((t>=0) && (t<=Ta+Tu+Tr))
- {
- if((t>=0) && (t<=taa))
- {
- *freq = 0.5*faa*t*t + A;
- *acc = faa*t;
- }
- else if((t>=taa) && (t<=taa+tua))
- {
- *freq = faa*taa*t + B;
- *acc = faa*taa;
- }
- else if((t>=taa+tua) && (t<=taa+tua+tra))
-
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
资料下载:
s型加减速.rar
(1.97 MB, 下载次数: 773)
|