提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
根据调整步进电机的脉冲间隔来实现加减速
提示:以下是本篇文章正文内容,下面案例可供参考
一、什么是步进电机脉冲
步进电机脉冲就是驱动器输出的高低电平信号,一次高低电平为一次脉冲,通过脉冲信号来驱动步进电机。脉冲的时间间隔越小,步进电机转的越快,反之则慢。
二、加减速实现
1.改变脉冲间隔
假设延时最快是400us,最慢是2000us,在这个区间来回改变延时来实现加减速
总的脉冲数STEP=加速部分+平稳运行部分+减速部分
分段 S 曲线将加速和减速划分为多个阶段,使速度曲线呈 S 形。电机启动和停止更加平滑,适用于高精度控制和大负载的应用
详细步骤:
- 加速和减速的分段:将
curveSteps
分成加速、平稳和减速三个阶段。accelPhase
为加速分段长度,decelPhase
为减速分段起点。 - 分阶段加速和减速:
- 加速阶段:在
accelPhase
内,按线性减少currentDelay
的值,提升电机速度。 - 平稳阶段:在
curveSteps
的中间段,以稍小的变化进行加速。 - 减速阶段:从
decelPhase
到结束,每步按线性增加currentDelay
,使电机平滑减速。
- 加速阶段:在
- 发送脉冲控制:每次根据当前
currentDelay
的值进行脉冲控制,最终完成 S 曲线的平稳加减速。
注意:加减速脉冲部分不一定是要1/5,可以根据想要的效果调整,最快和最慢速度也是,这里用的是Delay延时。
void motorZ(int STEP)
{
int maxDelay = 2000; //最慢速度
int minDelay = 400; //最快速度 us
int curveSteps = STEP / 5; //加减速脉冲部分
int currentDelay =maxDelay; //启动时用最慢速度
int accelPhase = curveSteps / 2; // 三段加速
int decelPhase = steps - curveSteps / 2; // 三段减速
// 控制步进电机
for (int i = 0; i < STEP ; i++)
{
GPIO_SetBits(GPIOA,GPIO_Pin_0); //方向给定
GPIO_SetBits(GPIOA,GPIO_Pin_1); //高电平
Delay_us(currentDelay); //当前延时
GPIO_ResetBits(GPIOA,GPIO_Pin_1); //低电平
Delay_us(currentDelay); //当前延时
//根据阶段调整加减速
if (i < accelPhase) // 加速阶段
{
currentDelay -= (maxDelay - minDelay) / accelPhase;
}
// 平稳阶段
else if (i >= accelPhase && i < curveSteps)
{
currentDelay += (minDelay - maxDelay) / (curveSteps - accelPhase);
}
// 减速阶段
else if (i >= decelPhase)
{
currentDelay += (maxDelay - minDelay) / (steps - decelPhase);
}
}
2.完整代码
代码如下(示例):
我的驱动器用的是8细分所以脉冲会给多点
#include "stm32f10x.h" // Device header
void gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //¾Ö²¿±äÁ¿
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE); //ÍâÉèʱÖÓ¿ØÖÆ
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //ÉèÖÃÎªÍÆÍìÊä³ö
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_3; //³õʼ»¯IO¶Ë¿Ú
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //ʱÖÓÆµÂÊ50M
GPIO_Init(GPIOA, &GPIO_InitStructure); //GPIOA¶Ë¿Ú³õʼ»¯
}
void Delay_us(uint32_t xus)
{
SysTick->LOAD = 72 * xus; //¶¨Ê±Æ÷֨װֵ
SysTick->VAL = 0x00; //Çå¿Õµ±Ç°¼ÆÊýÖµ
SysTick->CTRL = 0x00000005; //ÉèÖÃʱÖÓÔ´HCLK,Æô¶¯¶¨Ê±Æ÷
while(!(SysTick->CTRL & 0x00010000)); //µÈ´ý¼ÆÊý0
SysTick->CTRL = 0x00000004; //¹Ø±Õ¶¨Ê±Æ÷
}
void Delay_ms(uint32_t xms)
{
while(xms--)
{
Delay_us(1000);
}
}
void motorZ(u32 STEP)
{
int maxDelay = 2000; //×îÂýÑÓʱ
int minDelay = 400; //×î¿ìÑÓʱ us
int curveSteps = STEP / 5; //¼Ó¼õËÙÂö³å²¿·Ö
int currentDelay =maxDelay; //Æô¶¯ÑÓʱ
int accelPhase = curveSteps / 2; //¼ÓËÙ½×¶Î
int decelPhase = STEP - curveSteps / 2; //¼õËÙ½áÊø½×¶Î
// ¿ØÖƲ½½øµç»ú
for (int i = 0; i < STEP ; i++)
{
GPIO_SetBits(GPIOA,GPIO_Pin_0); //·½Ïò¸ø¶¨
GPIO_SetBits(GPIOA,GPIO_Pin_1); // ¿ØÖƲ½½øµç»ú
Delay_us(currentDelay); //µ±Ç°ÑÓʱ
GPIO_ResetBits(GPIOA,GPIO_Pin_1); //Êä³öµÍµçƽ
Delay_us(currentDelay); //µ±Ç°ÑÓʱ
//¸ù¾Ý½×¶Îµ÷Õû¼ÓËÙ¡¢¼õËÙ
if (i < accelPhase) // ¼ÓËÙ½×¶Î
{
currentDelay -= (maxDelay - minDelay) / accelPhase;
}
// ƽÎȽ׶Î
else if (i >= accelPhase && i < curveSteps)
{
currentDelay += (minDelay - maxDelay) / (curveSteps - accelPhase);
}
// ¼õËÙ½×¶Î
else if (i >= decelPhase)
{
currentDelay += (maxDelay - minDelay) / (STEP - decelPhase);
}
}
}
int main()
{
gpio_init();
while(1)
{
motorZ(8000);//¸ù¾Ýϸ·Ö¸øÂö³åÊý
Delay_ms(150);
}
}
VID_20241104_185758_DOLBY
总结
将加减速分段,最平滑但计算复杂,适合高精度机械控制。