STM32驱动步进电机驱动(HAL库)

!!本文章给出了驱动源码,以及常见问题 注意是HAL库!!
支持正反转、刹车、代码均为宏定义方便后续添加到项目
电机每次转动时都会接着上一步进行

介绍

步进电机是一种特殊类型的电机,其运动是通过逐步地转动一定角度的步进角来实现的。步进电机的运动是以离散的步进方式进行的,每一步转动固定的角度,可以实现精确的位置控制。步进电机由一个固定数量的步进角、转子、绕组和驱动电路组成。步进电机通常有两种主要类型:单相步进电机和双相步进电机。每个类型又可以分为不同的变种,但它们的基本工作原理都是一样的。步进电机的工作原理基于电磁学和磁学的相互作用。它包含了一个旋转部件(通常称为转子)和一个定子。定子上的绕组会根据输入的电流产生磁场,而转子上则带有永久磁体。当电流通过定子绕组时,磁场会与转子上的永久磁体相互作用,导致转子发生旋转。步进电机的旋转是以步进角度为单位的,步进角度取决于电机的设计和构造。通过依次施加适当的电流脉冲,可以实现精确的旋转运动,同时可以控制电机的速度和位置。步进电机在很多应用中被广泛使用,特别是需要精确位置控制或者需要旋转到特定角度的场景,如打印机、数控机床、机器人、精密仪器等。
本文章用平时最常见也是最简单的28BYJ-48,这是一个五线四项电机。
在这里插入图片描述

原理

步进电机的工作原理基于电磁学和磁学的相互作用,它包含一个定子和一个转子,以及通过电流控制转子旋转的驱动电路。
定子和绕组:步进电机的定子通常包含若干个绕组,这些绕组被连接到电源上,通过流过绕组的电流可以在定子上产生磁场。这些绕组的排列方式和数量会影响步进电机的类型和特性。
转子和永磁磁铁:步进电机的转子上通常带有永磁磁铁,这些磁铁可以产生一个稳定的磁场。这个磁场与定子上产生的磁场相互作用,导致转子发生旋转。
步进角和步进运动:步进电机的旋转是以固定的步进角度为单位进行的。步进角是电机每接收一次脉冲时转动的角度,这个角度是由电机的机械设计和电气特性决定的。通过逐步地给电机施加脉冲信号,可以实现分步的旋转运动。步进角越小,电机的旋转精度越高。
驱动电路和脉冲控制:为了控制步进电机的旋转,需要一个驱动电路来产生适当的电流脉冲。驱动电路会根据输入的控制信号生成一系列脉冲,这些脉冲会依次流过步进电机的不同绕组,从而产生磁场和转动。控制脉冲的频率和脉冲数可以控制电机的旋转速度和旋转角度。
全步和半步模式:步进电机可以以全步模式或半步模式工作。在全步模式下,每个步进角会转动一个完整的步进角度。在半步模式下,每个步进角会转动一半的步进角度,因此可以实现更精细的控制和更平滑的运动。

半步模式

在这里插入图片描述

全步模式

在这里插入图片描述
由于单片机IO口输出电流过小,无法带动电机运行,因此我们需要另外加一个驱动板,用ULN2003就行,简单便宜。

实验代码

step_motor.h

/**
 ****************************************************************************************************
 * @file        step_motor.h
 * @author      Mr.wang
 * @version     V1.0
 * @date        2023-08-1
 * @brief       步进电机驱动代码
 ****************************************************************************************************
 */

#ifndef _STEP_MOTOR_H
#define _STEP_MOTOR_H
#include "./SYSTEM/sys/sys.h"
/******************************************************************************************/

//在这里配置引脚 A-D
#define MOTOR_GPIO_PORT                 GPIOB
#define MOTOR_GPIO_PIN_A                GPIO_PIN_3
#define MOTOR_GPIO_PIN_B                GPIO_PIN_4
#define MOTOR_GPIO_PIN_C                GPIO_PIN_5
#define MOTOR_GPIO_PIN_D                GPIO_PIN_6
#define MOTOR_GPIO_CLK_ENABLE()         do{
      
       __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   


#define GPIO_A_ON() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_A, GPIO_PIN_SET);
#define GPIO_A_OFF() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_A, GPIO_PIN_RESET);
#define GPIO_B_ON() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_B, GPIO_PIN_SET);
#define GPIO_B_OFF() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_B, GPIO_PIN_RESET);
#define GPIO_C_ON() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_C, GPIO_PIN_SET);
#define GPIO_C_OFF() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_C, GPIO_PIN_RESET);
#define GPIO_D_ON() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_D, GPIO_PIN_SET);
#define GPIO_D_OFF() HAL_GPIO_WritePin(MOTOR_GPIO_PORT, MOTOR_GPIO_PIN_D, GPIO_PIN_RESET);


/******************************************************************************************/
/* 外部接口函数*/
void step_motor_init(void);
void Move_StopNow(void);
void stepMotor_8(uint8_t dir);
void Move_Step_8(uint8_t dir, uint16_t Step);

#endif

step_motor.c

/**
 ****************************************************************************************************
 * @file        step_motor.c
 * @author      Mr.wang
 * @version     V1.0
 * @date        2023-08-1
 * @brief       步进电机驱动代码
 ****************************************************************************************************
 */

#include "./BSP/LED/step_motor.h"
#include "./SYSTEM/delay/delay.h"


uint8_t motorSequence_8[] = {
    
    0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09};   // 步进电机八拍序列
uint16_t currentStep_8 = 0; // 目前处于哪一拍
uint8_t stepx = 0;
uint8_t step = 0;

/**
 * @brief       步进电机初始化
 * @param       无
 * @retval      无
 */
void step_motor_init(void)
{
    
    
    GPIO_InitTypeDef GPIO_InitStruct;
    MOTOR_GPIO_CLK_ENABLE();

    GPIO_InitStruct.Pin = MOTOR_GPIO_PIN_A | MOTOR_GPIO_PIN_B | MOTOR_GPIO_PIN_C | MOTOR_GPIO_PIN_D; //  选择引脚
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出模式
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速输出
    HAL_GPIO_Init(MOTOR_GPIO_PORT, &GPIO_InitStruct);
}



/**
 * @brief       刹车
 * @param       无
 * @retval      无
 */
void Move_StopNow(void)
{
    
    
    uint8_t stop = 0x0F;
    if (stop & 0x01)
    {
    
    
        GPIO_A_ON();
    }
    else
    {
    
    
        GPIO_A_OFF();
    }
    if (stop & 0x02)
    {
    
    
        GPIO_B_ON();
    }
    else
    {
    
    
        GPIO_B_OFF();
    }
    if (stop & 0x04)
    {
    
    
        GPIO_C_ON();
    }
    else
    {
    
    
        GPIO_C_OFF();
    }
    if (stop & 0x08)
    {
    
    
        GPIO_D_ON();
    }
    else
    {
    
    
        GPIO_D_OFF();
    }
}
/**
 * @brief       步进电机转动 连续转动没有抖动
 * @param       dir 方向 1是正向 0是反向
 * @retval      无
 */
void stepMotor_8(uint8_t dir)
{
    
    
		if (dir == 1)
				stepx = (stepx + 1) % 8;
    else if (dir == 0)
        stepx = (stepx + 7) % 8;
    step = motorSequence_8[stepx];
    if (step & 0x01)
    {
    
    	
				GPIO_A_ON();
    }
    else
    {
    
    
        GPIO_A_OFF();
    }
    if (step & 0x02)
    {
    
    
        GPIO_B_ON();
    }
    else
    {
    
    
        GPIO_B_OFF();
    }
    if (step & 0x04)
    {
    
    
        GPIO_C_ON();
    }
    else
    {
    
    
        GPIO_C_OFF();
    }
    if (step & 0x08)
    {
    
    
        GPIO_D_ON();
    }
    else
    {
    
    
				GPIO_D_OFF();
    }
}
/**
 * @brief       步进电机转动 连续转动没有抖动
 * @param       dir 方向  方向 1是正向 0是反向
 * @param       Step 步数
 * @retval      里面用到了delay_ms阻塞函数
 */
void Move_Step_8(uint8_t dir, uint16_t Step)
{
    
    
    uint16_t Count = Step; // 步数
    while (Count--)
    {
    
    
        stepMotor_8(dir);
        delay_ms(1);
    }
}

main.c测试

int main(void)
{
    
    
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    step_motor_init();                          /* 初始化步进电机 */
    while(1)
    {
    
    
				Move_Step_8(1, 2500); //步进电机正转2500步
        delay_ms(500);
				Move_Step_8(0, 2500); //步进电机反转2500步
        delay_ms(500);
    }
}

在这里插入图片描述

问题总结

1.若出现问题请检查引脚定义 引脚时钟定义 以及组定义.

//在这里配置引脚 A-D
#define MOTOR_GPIO_PORT                 GPIOB
#define MOTOR_GPIO_PIN_A                GPIO_PIN_3
#define MOTOR_GPIO_PIN_B                GPIO_PIN_4
#define MOTOR_GPIO_PIN_C                GPIO_PIN_5
#define MOTOR_GPIO_PIN_D                GPIO_PIN_6
#define MOTOR_GPIO_CLK_ENABLE()         do{
      
       __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) 

2.若电机出现抖动 直接更改延迟将其增大或减小即可.

void Move_Step_8(uint8_t dir, uint16_t Step)
{
    
    
    uint16_t Count = Step; // 步数
    while (Count--)
    {
    
    
        stepMotor_8(dir);
        delay_ms(1);    <--------更改这里
    }
}
``

猜你喜欢

转载自blog.csdn.net/Systemmax20/article/details/132251981