目录
(学习自用,原理网上找的,侵权可删)
一.四相五线步进电机驱动原理
电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。
步进电机的主要特性:
1、 步进电机必须加驱动才可以运转, 驱动信号必须为脉冲信号,没有脉冲的时候,步进电机静止, 如果加入适当的脉冲信号, 就会以一定的角度(称为步角)转动。转动的速度和脉冲的频率成正比。
2、 黑金刚配套的是 28BYJ48 5V 驱动的 4 相 5 线的步进电机,而且是减速步进电机,减速比为 1:64,步进角为 5.625/64 度。如果需要转动 1 圈,那么需要360/5.625*64=4096 个脉冲信号。
采用八拍的方式进行驱动:AA AB BB BC CC CD DD DA
注意事项:
步进电机停止后需要使四个相位引脚都为高电平,否则步进电机会发热。因为不进电机公共端为高电平,所有引脚都为高电平就不会产生电流,就不会发热。
二.源码(HAL库)
驱动代码:
#include "./BSP/sun_motor/sun_motor.h"
int32_t location_now[ArrayCount(LINES_MOTOR_STEP)]; //the val of motor location now
int32_t location_aim[ArrayCount(LINES_MOTOR_STEP)]; //the val of motor location aim
StepMotorState motorState[ArrayCount(LINES_MOTOR_STEP)]; //mark the state of motor
void StepMotor_AA(uint8_t choose_motor)
{
PIN_OUT( LINES_MOTOR_STEP[choose_motor][0], LINE_ON);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][1], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][2], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][3], LINE_OFF);
}
void StepMotor_AB(uint8_t choose_motor)
{
PIN_OUT( LINES_MOTOR_STEP[choose_motor][0], LINE_ON);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][1], LINE_ON);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][2], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][3], LINE_OFF);
}
void StepMotor_BB(uint8_t choose_motor)
{
PIN_OUT( LINES_MOTOR_STEP[choose_motor][0], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][1], LINE_ON);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][2], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][3], LINE_OFF);
}
void StepMotor_BC(uint8_t choose_motor)
{
PIN_OUT( LINES_MOTOR_STEP[choose_motor][0], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][1], LINE_ON);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][2], LINE_ON);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][3], LINE_OFF);
}
void StepMotor_CC(uint8_t choose_motor)
{
PIN_OUT( LINES_MOTOR_STEP[choose_motor][0], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][1], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][2], LINE_ON);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][3], LINE_OFF);
}
void StepMotor_CD(uint8_t choose_motor)
{
PIN_OUT( LINES_MOTOR_STEP[choose_motor][0], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][1], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][2], LINE_ON);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][3], LINE_ON);
}
void StepMotor_DD(uint8_t choose_motor)
{
PIN_OUT( LINES_MOTOR_STEP[choose_motor][0], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][1], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][2], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][3], LINE_ON);
}
void StepMotor_DA(uint8_t choose_motor)
{
PIN_OUT( LINES_MOTOR_STEP[choose_motor][0], LINE_ON);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][1], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][2], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][3], LINE_ON);
}
void StepMotor_Stop(uint8_t choose_motor)
{
PIN_OUT( LINES_MOTOR_STEP[choose_motor][0], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][1], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][2], LINE_OFF);
PIN_OUT( LINES_MOTOR_STEP[choose_motor][3], LINE_OFF);
}
/*
@brief: Init the location and series of the stepmotor
@para: none
@retval: none
*/
void StepMotor_Init()
{
uint8_t flag;
uint8_t i;
GPIO_InitTypeDef motor_gpio_init_struct;
MOTOR_GPIO_CLK_ENABLE();
for(flag = 0;flag < ArrayCount(LINES_MOTOR_STEP); flag++)
{
for(i = 0; i < 4; i++)
{
motor_gpio_init_struct.Pin=LINES_MOTOR_STEP[flag][i];
motor_gpio_init_struct.Mode=GPIO_MODE_OUTPUT_PP;
motor_gpio_init_struct.Pull=GPIO_PULLUP;
}
StepMotor_AA(flag);
delay_ms(1);
StepMotor_AB(flag);
delay_ms(1);
StepMotor_BB(flag);
delay_ms(1);
StepMotor_BC(flag);
delay_ms(1);
StepMotor_BB(flag);
delay_ms(1);
StepMotor_AB(flag);
delay_ms(1);
StepMotor_AA(flag);
delay_ms(1);
StepMotor_Stop(flag);
delay_ms(1);
location_now[flag] = 0;
location_aim[flag] = 0;
motorState[flag] = StepMotor_Stop;
}
HAL_GPIO_Init(GPIOB, &motor_gpio_init_struct);
}
/*
@brief: motor walk one step
@para: choose motor
@retval: NULL
*/
void StepMotor_WalkOneStep(uint8_t choose_motor)
{
uint8_t state = 0;
//if the location now is the same with the location aim, step_motor will stop
if(location_now[choose_motor]==location_aim[choose_motor])
{
StepMotor_Stop(choose_motor);
motorState[flag] = StepMotor_Stop;
return;
}
//if the location now is not the same with the location aim, step_motor will stop
state = (location_now[choose_motor]%8 + 8)%8; //Calculate the current coil that needs to be connected
switch(state)
{
case 0:Step_AB(choose_motor);break;
case 1:Step_BB(choose_motor);break;
case 2:Step_BC(choose_motor);break;
case 3:Step_CC(choose_motor);break;
case 4:Step_CD(choose_motor);break;
case 5:Step_DD(choose_motor);break;
case 6:Step_DA(choose_motor);break;
case 7:Step_AA(choose_motor);break;
}
if(location_now[choose_motor] < location_aim[choose_motor] )//if now location less than aim location
{
location_now[choose_motor]++; //location_now add 1
}
}
头文件
#ifndef _sun_motor_H_
#define _sun_motor_H_
#include "./SYSTEM/sys/sys.h"
typedef enum
{
StepMotor_Backward=-1,
StepMotor_Stop=0,
StepMotor_Forward=1
}StepMotorState;
#define LINE_ON GPIO_PIN_SET
#define LINE_OFF GPIO_PIN_RESET
/******************************************************************************************/
/* 引脚 定义 */
#define MOTOR_GPIO_PORT GPIOB
#define MOTOR0_A_GPIO_PIN GPIO_PIN_0
#define MOTOR0_B_GPIO_PIN GPIO_PIN_1
#define MOTOR0_C_GPIO_PIN GPIO_PIN_8
#define MOTOR0_D_GPIO_PIN GPIO_PIN_3
#define PB0 MOTOR0_A_GPIO_PIN
#define PB1 MOTOR0_B_GPIO_PIN
#define PB8 MOTOR0_C_GPIO_PIN
#define PB3 MOTOR0_D_GPIO_PIN
#define MOTOR1_A_GPIO_PIN GPIO_PIN_4
#define MOTOR1_B_GPIO_PIN GPIO_PIN_5
#define MOTOR1_C_GPIO_PIN GPIO_PIN_6
#define MOTOR1_D_GPIO_PIN GPIO_PIN_7
#define PB4 MOTOR1_A_GPIO_PIN
#define PB5 MOTOR1_B_GPIO_PIN
#define PB6 MOTOR1_C_GPIO_PIN
#define PB7 MOTOR1_D_GPIO_PIN
static const uint16_t LINES_MOTOR_STEP[][4] = {{PB0,PB1,PB8,PB3},{PB4,PB5,PB6,PB7}};
#define MOTOR_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0) /* PB口时钟使能 */
#define PIN_OUT(uint16_t GPIO_Pin, GPIO_PinState PinState) HAL_GPIO_WritePin(GPIOB, uint16_t GPIO_Pin, GPIO_PinState PinState)
#endif