【STM32】控制28BYJ48 步进电机

一、28BYJ48步进电机

28BYJ48是一款乘速步进电机,常用于小型自动化设备和教育学习中。这种电机配合ULN2003驱动板,可以通过单片机进行简单控制。控制步进电机有三种模式,Wave Drive(波形驱动),Full Step Drive(全步驱动)和Half Step Drive(半步驱动),波形驱动和全步驱动的效果差不多,所以本文主要介绍全步驱动和半步驱动。

28BYJ48的主要参数:

  • 单步角度:5.625°

  • 减速比:64

  • 每周步数:4096步 

  • 电压:5V

  • 全步模式(每圈32步)

    在全步模式下,每步激励一个线圈,完整驱动一个电机周期需要 32 步。结合减速比,计算实际输出轴的步距角:

    计算公式:

    将数据代入:

  • 全步模式下,输出轴每步的旋转角度为 0.1758°(约 0.176°)。

  • 半步模式(每圈64步)

    在半步模式下,每步激励一相或两相线圈,完整驱动一个周期需要 64 步,所以输出轴的步距角会更小:

    计算公式:

    将数据代入:

  • 半步模式下,输出轴每步的旋转角度为 0.08789°(约 0.088°)。
  • 二、驱动步进电机

    步进电机的每一小步都由四个控制信号来决定。这些控制信号通常是按特定顺序切换的。例如,对于 28BYJ-48 步进电机,有三种控制方式

    全步驱动:

    波形驱动:

    半步驱动:

    我们只需要单片机的四个GPIO就可以通过ULN2003驱动步进电机

    三、程序设计(源码)

    StepMotor.c

    #include "stm32f10x.h"                  // Device header
    #include "StepMotor.h"
    #include "Delay.h"
    
    // 记录步进电机的当前位置
    int32_t current_position = 0;
    int32_t Target_step;
    int32_t Current_step;
    
    // 全步模式控制序列
    uint8_t full_step[4][4] = {
        {1, 0, 0, 0},
        {0, 1, 0, 0},
        {0, 0, 1, 0},
        {0, 0, 0, 1}
    };
    
    // 半步模式控制序列
    uint8_t half_step[8][4] = {
        {1, 0, 0, 0},
        {1, 1, 0, 0},
        {0, 1, 0, 0},
        {0, 1, 1, 0},
        {0, 0, 1, 0},
        {0, 0, 1, 1},
        {0, 0, 0, 1},
        {1, 0, 0, 1}
    };
    
    // 设置引脚电平
    void set_step(uint8_t a, uint8_t b, uint8_t c, uint8_t d) 
    {
    	GPIO_WriteBit(GPIOB, GPIO_Pin_14, a ? Bit_SET : Bit_RESET);
        GPIO_WriteBit(GPIOB, GPIO_Pin_15, b ? Bit_SET : Bit_RESET);		
        GPIO_WriteBit(GPIOB, GPIO_Pin_12, c ? Bit_SET : Bit_RESET);
        GPIO_WriteBit(GPIOB, GPIO_Pin_13, d ? Bit_SET : Bit_RESET);	
    }
    
    void step_motor(uint16_t steps, uint16_t delay) 
    {
        for (uint16_t i = 0; i < steps; i++) 
    	{
            for (uint8_t j = 0; j < 8; j++) 
    		{
                set_step(half_step[j][0], half_step[j][1], half_step[j][2], half_step[j][3]);
                Delay_ms(delay); // 步间延时
            }
        }
    }
    
    // 控制步进电机转到指定的目标位置,4096步为一圈
    void StepMotor_SetTarget(int32_t target_position, uint16_t delay) 
    {
        // 计算需要移动的步数
        int32_t steps_to_move = target_position - current_position;
    
        // 确定方向,1 表示正方向,-1 表示反方向
        int8_t direction = (steps_to_move > 0) ? 1 : -1;
    
        // 取绝对步数
        steps_to_move = (steps_to_move > 0) ? steps_to_move : -steps_to_move;
    
        static uint8_t step_index = 0;
    
        for (uint32_t i = 0; i < steps_to_move; i++) 	// 执行步进
    	{
            if (direction == 1) 
    		{
                step_index = (step_index + 1) % 8; // 顺时针
            } 
    		else 
    		{
                step_index = (step_index == 0) ? 7 : (step_index - 1); // 逆时针
            }
            set_step(half_step[step_index][0], half_step[step_index][1], half_step[step_index][2], half_step[step_index][3]);
            Current_step += direction;        // 更新当前步数
            Delay_ms(delay);
        }
    
        // 更新当前位置
        current_position = target_position;
    }
    
    void StepMotor_Init(void)
    {
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    	
    	GPIO_InitTypeDef GPIO_InitStructure;
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOB, &GPIO_InitStructure);
    }
    
    
    

    StepMotor.h

    #ifndef __STEPMOTOR_H__
    #define __STEPMOTOR_H__
    
    extern int32_t Current_step;
    extern int32_t Target_step;
    
    void StepMotor_Init(void);
    void set_step(uint8_t a, uint8_t b, uint8_t c, uint8_t d);
    void step_motor(uint16_t steps, uint16_t delay);
    void StepMotor_SetTarget(int32_t target_position, uint16_t delay); 
    
    #endif
    

    四、补充说明

    以上使用了stm32的PB12,13,14,15控制步进电机,以全步模式为例,依次给这四个引脚1000,0100,0010,0001中间在加上步进延时就可以控制步进电机了,通过增加或减少步进延时的长度就可以控制步进电机运行的速度,但是需要注意的是,步进延时不能小于1-2ms,不然会出现丢步现象,步进电机不像舵机一样可以指哪儿到哪儿,它是通过步来确定位置。步进电机使用半步模式走一圈是64步,经过1:64的减速比之后是走一圈4096步,也就是4096步对应着360度,通过控制步进电机走的步数就可以间接控制角度,但是以上代码是用过延时来控制步进电机走一步的频率,对程序的连续性很不友好,后面会再尝试使用定时器中断+状态机实现控制步进电机,可以关注一下~~

    作者:A-pezer

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【STM32】控制28BYJ48 步进电机

    发表回复