上星期写了一篇STM32——使用PWM+DMA实现脉冲发送精确控制
今天想起来了,就在之前的基础上写了步进电机的加速曲线控制,其实也没多难,如果看过上一篇的小伙伴也许会记得,代码中有一个核心数组send_buf
,今天要说的梯形速度控制其实就是按照梯形加速的方式配置send_buf
send_buf
中填写的是PWM的ARR
值,我们知道ARR
的值可以决定PWM的频率
下面这个代码是为了验证效果,在VS里写的一个demo
void config_buf(long steps, long Fpwm, int cmd)
这个函数是梯形加速曲线实现的核心,输入参数steps
、Fpwm
和 cmd
steps
是想要发送的脉冲数
Fpwm
是想要发送的脉冲频率,是加速过程的最大值,也就是匀速阶段的频率值。
cmd
是一个选择加速或者不加速的参数,1
为使用加速曲线;0
为不采用加速曲线,则全程匀速。
#include <stdio.h>
#define default_size 10000
#define default_arr 599
#define default_psc 719
#define default_size 10000
#define init_arr 999
#define Fmax 10000
int send_buf[default_size];
void config_buf(long steps, long Fpwm, int cmd)
{
if (steps > 0 && steps <= default_size && Fpwm <= Fmax) /* 判断参数合法性 */
{
long arr_goal = (long)(100000 / Fpwm) - 1; /* 计算arr目标值 */
long default_a = (long)((init_arr - arr_goal) / (steps / 4)); /* 计算加速度 */
if (cmd == 1) /* 使用加速曲线 */
{
long counter; /* 计数 */
long flag = 0; /* 标记分界点 */
long arr_temp = init_arr;
for (counter = 0; (init_arr - default_a * counter) > arr_goal; ++counter)
{
arr_temp = init_arr - default_a * counter;
send_buf[counter] = arr_temp;
}
if ((init_arr - default_a * counter) <= arr_goal) /* 开始匀速阶段 */
{
flag = counter; /* 分界点 */
long m;
for (m = flag; m < steps - flag; ++m)
{
send_buf[m] = arr_goal;
counter = m; /* 计数 */
}
}
long j;
for (j = counter + 1; arr_goal + default_a * (j - (steps - flag) + 1) < init_arr; ++j) /* 开始减速阶段 */
{
send_buf[j] = arr_goal + default_a * (j - (steps - flag) + 1);
}
if (arr_goal + default_a * (j - (steps - flag) + 1) >= init_arr)
{
send_buf[j] = arr_goal + default_a * (j - (steps - flag) + 1);
}
}
else if (cmd == 0) /* 全程匀速 */
{
long n;
for (n = 0; n < steps; ++n)
{
send_buf[n] = arr_goal;
}
}
}
}
int main()
{
config_buf(1000, 1000, 1);
for (int a = 0; a<default_size;++a)
{
printf("%d \n", send_buf[a]);
if (send_buf[a] == 0)
break;
}
getchar();
return 0;
}
在VS里跑的效果就像下面这样
为了更加直观地看出数据的特征,我把数据在Excel里做了一张图表,如下。
可以看到纵轴是ARR
的值,横轴是脉冲数,一共发送1000个脉冲,第1001个位是0。所以会看到图表最后有一个巨大的跳变。由于ARR
越大,PWM的频率就越低,所以图表上看见的内容就是一个PWM频率由低到高 -> 保持不变 -> 由高到低的过程。
应用到步进电机上就是一个匀加速 -> 匀速 -> 匀减速的过程