数字积分法DDA(实时步进电机梯形+S形加减速)实现方法 您所在的位置:网站首页 fpga程序实现脉冲输出的过程 数字积分法DDA(实时步进电机梯形+S形加减速)实现方法

数字积分法DDA(实时步进电机梯形+S形加减速)实现方法

2024-07-01 13:52| 来源: 网络整理| 查看: 265

在一般的单片机,或者STM32 ,如何才能实现实时的步进电机加减速脉冲输出呢?通过在网络上各种搜索学习,真正有实用价值的资料并不多,大多只是原理,然后是无限的公式公式公式。。。对于只有小学文化程度的我看得头都大了,看到了DDA插补的方式,只用到整数,通过加法积分,溢出就可以多轴直线插补,圆弧插补了,哪么DDA积分法能否实现加减速呢?在万能的网络上根本没有答案

然后翻出了女儿高中的物理书本学习研究速度相关的知识,得到的结论是

答案是肯定的

通过速度物理相关的知识,写了一个循环模拟定时器,循环执行了多次积分累加,验证确实是可以实现出来,要先通过移动速度,加速度,计算出速度因子,加速度积分因子,在每次循环累加只要溢出就输出一个脉冲,通过累加次数的不同而溢出产生的脉冲,等同于产生了不同频率,比如最大频率为100KHZ,哪么最大速度时每周期就是10微秒了,此时速度为100HZ的话,对应的周期时间为0.01秒,如果在一个定时器频率为100KH的中断里,要产生100HZ的频率,也就是0.01/0.00001=1000次累加,输出一个脉冲,不同的频率在这个100KHZ定时器中断时,以不同的累加次数产生即可

先拿几项参数来说明一下如何实现,速度30mm/s,加速度100mm/s,都以秒为单位,这里不提及角速度这样的单位,因为转换过来后是完全哪么一回事!反正怎么简单怎么来,也好理解,因为全后面全都转换为(步)作为单位,时间为(秒),每移动1mm对应的步数为640步,

step_mm = 640;

v_step =30*640;

a_step=100*640;

所以单位转换为步

v_step =19200;

a_step=64000;

首先计算出加速度所要的时间A_T=v_step/a_step=19200/64000=0.3秒

求出加速度所要的步数,通过面积公式s=v*t,由于加速度是一个斜坡,等同于一个三角形面积,即正方形面积的一半,所以公式为s=v*t*0.5 or s=v*v/a*0.5

A_S=v_step*A_T*0.5=19200*0.3*0.5=2880步

Timer_freq=100000; 定时器频率100KHZ,对的是固定频率,当然单片机性能高的还可以设定更高的频率

求出加速移动2880步所要的定时器次数,A_HZ=A_T*Timer_freq=0.3*100000=30000

积分因子使用32位整数

求出最大速度因子

Vmax_factor=0xFFFFFFFF*v_step/Timer_freq;

加速度因子

A_factor=Vmax_factor/A_HZ;

以上为计算这些参数的方法,然后接着看如何实现加速

整个加速过程所以要时间为0.3秒,对应定时器的频率100KHZ,要在定时器中断里中断30000次,每中断一次,累加器都与积分因子累加一次,累加器每溢出一次,输出一个脉冲,要使用到两个累加器,一个为速度累加器,一个为加速累加器

如下为一个循环执行的代码,循环30000次,模拟100KHZ定时器中断,即每循环一次理解为10微秒,实际要实现的代码是放定时器中断函数里执行的,现在只是意思意思,好理解和明白,实际上这方法超级简单,就是线性增量速度,把最大速度微分成30000份,再累积起来,这实际上与v=0.3*a是相关联的,因为累加次数等同于时间,即速度与时间和加速度的三者的关系

注:代码哪些数值都是按照前面所说的计算所得,要完整实用还是得要全补上计算的,由于只作验证测试用,所以代码里数值都直接写上了的,不要问这些数值怎么来了

void ACC() { int v_step =19200; int a_step=64000; int A_S=2880; int Timer_freq=100000; int A_HZ=30000; UINT32 Vmax_factor=(UINT32)(0xFFFFFFFF*(double)(v_step/Timer_freq)); UINT32 A_factor=Vmax_factor/A_HZ; UINT32 v_accumulator=0; UINT32 tmp=0; UINT32 v_factor_accumulator=A_factor; int move=0; for(int i=0;i0){ tmp = v_accumulator; v_accumulator += v_factor_accumulator; //积分 if(v_accumulator < tmp) //如果溢出 { move++; //输出脉冲 A_S--; } if(v_factor_accumulator=Vmax_factor) //判断是否进入恒速度 v_factor_accumulator = Vmax_factor; } }

从恒速度减速下来,其实就是v_factor_accumulator-=A_factor;具体实现还要相应的速度段判断

现在v_factor_accumulator的是以线性增量的,如果是以S形增量变化,哪就是S形的加速度斜坡了,原理实际上就变化的加速度值,但由于个人能力问题,尝试了许多种以DDA的方式,也无法以S形的方式准确的在相就的时间内移动相应的步数,即不准确,但加速度的S形是可以弄出来了,原因应该是加加速度时和减加速度时没弄准确,然后实际在相关的时间内移动步数和速度上都不能准确对应上,无法几者都与速度物理公式符合,反正现在是想不出来能准确实现的,要有能实现出S形DDA方式变化增量的通知一下哦!

另外最好使用32位数作为累加值,即以0xFFFFFFFF作为最大的溢出值,因为数值越大,等于把浮点数放大,会更精确

此方法没有复杂的计算过程,在中断里也就加加减减,也没有浮点运算,对于MCU的开销非常的小,通过几个参数就可以实时的加减速的脉冲输出了,其实某些FPGA的运动控制卡,也是DDA实现的,脉冲频率可以高达4M,对于FPGA也只是看过了一下介绍,本人也不懂

实际应用,还要有初速度因子,结束速度因子,因为G64连续模式里,有前瞻处理,会有进初速度,恒速度,结束速度(即下一路径的进入速度)

把输出脉冲按4毫秒采样写到一数组里,用电子表格显示加速度斜坡,以验证结果吧!

void ACC() { int v_step =19200; int a_step=64000; int A_S=2880; int Timer_freq=100000; int A_HZ=30000; UINT32 Vmax_factor=(UINT32)(0xFFFFFFFF*(double)(v_step/Timer_freq)); UINT32 A_factor=Vmax_factor/A_HZ; UINT32 v_accumulator=0; UINT32 tmp=0; UINT32 v_factor_accumulator=A_factor; //int move=0; int out[75]={0}; for(int n=0;n


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有