我们这次推荐使用的是seeed的步进电机驱动套件,齿轮步进电机驱动套件包括一个步进电机和一个电机驱动板。这是一款四相八步步进电机,可以通过驱动板轻松控制该步进电机,内置齿轮箱。
基本参数如下:硬件概览
引脚图


步进电机控制也是为我们进行AI训练准备的,这里我们实现两种分类模式的4种状态,但时候传感器数据采集就这几种状态来进行,并训练,后续也是使用这样的控制方式来进行验证,我们加了一个开发板进行步进电机的控制:

主要是4个输入通道的控制,配置了4个引脚:

static const uint8_t halfstep_seq[8][4] = {
{0, 1, 1, 1}, /* step 0: A */
{0, 0, 1, 1}, /* step 1: A + B */
{1, 0, 1, 1}, /* step 2: B */
{1, 0, 0, 1}, /* step 3: B + C */
{1, 1, 0, 1}, /* step 4: C */
{1, 1, 0, 0}, /* step 5: C + D */
{1, 1, 1, 0}, /* step 6: D */
{0, 1, 1, 0} /* step 7: D + A */
};
/* Step interval (ms) per state. Index 0 (STOP) is unused. */
static const uint16_t step_interval_ms[4] = {0, 3, 2, 1};
/* LED blink half-period (ms) per state. 0 means "solid on"; STOP forces off
* inside Tick regardless of table value. */
static const uint16_t led_blink_period_ms[4] = {0, 0, 500, 150};
/* Debounce window for the user button (ms). */
#define BUTTON_DEBOUNCE_MS 200U
static volatile StepMotor_State_t motor_state = STATE_STOP;
static volatile uint8_t phase_index = 0;
static volatile uint32_t last_step_tick = 0;
static volatile uint32_t last_btn_tick = 0;
static volatile uint32_t last_led_tick = 0;
/* Private function prototypes -----------------------------------------------*/
static void apply_phase(uint8_t i);
static void coils_off(void);
static void apply_phase(uint8_t i)
{
GPIO_PinState s;
s = (halfstep_seq[i][0] != 0) ? GPIO_PIN_SET : GPIO_PIN_RESET;
HAL_GPIO_WritePin(IN1_GPIO_Port, IN1_Pin, s);
s = (halfstep_seq[i][1] != 0) ? GPIO_PIN_SET : GPIO_PIN_RESET;
HAL_GPIO_WritePin(IN2_GPIO_Port, IN2_Pin, s);
s = (halfstep_seq[i][2] != 0) ? GPIO_PIN_SET : GPIO_PIN_RESET;
HAL_GPIO_WritePin(IN3_GPIO_Port, IN3_Pin, s);
s = (halfstep_seq[i][3] != 0) ? GPIO_PIN_SET : GPIO_PIN_RESET;
HAL_GPIO_WritePin(IN4_GPIO_Port, IN4_Pin, s);
}
static void coils_off(void)
{
HAL_GPIO_WritePin(IN1_GPIO_Port, IN1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(IN2_GPIO_Port, IN2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(IN3_GPIO_Port, IN3_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(IN4_GPIO_Port, IN4_Pin, GPIO_PIN_SET);
}
void StepMotor_Init(void)
{
motor_state = STATE_STOP;
phase_index = 0;
last_step_tick = HAL_GetTick();
last_btn_tick = 0;
last_led_tick = HAL_GetTick();
coils_off();
BSP_LED_Off(LED_GREEN);
}
void StepMotor_Tick(void)
{
uint32_t now = HAL_GetTick();
StepMotor_State_t st = motor_state; /* single read snapshot */
/* --- LED heartbeat --------------------------------------------------- */
if (st == STATE_STOP) {
BSP_LED_Off(LED_GREEN);
} else if (st == STATE_RUN_SLOW) {
BSP_LED_On(LED_GREEN);
} else {
/* RUN_MED / RUN_FAST: blink at led_blink_period_ms[st] half-period. */
uint16_t period = led_blink_period_ms[st];
if (period > 0 && (uint32_t)(now - last_led_tick) >= period) {
last_led_tick = now;
BSP_LED_Toggle(LED_GREEN);
}
}
/* --- Stepping (only in RUN states) ---------------------------------- */
if (st == STATE_STOP) {
return;
}
uint16_t interval = step_interval_ms[st];
if ((uint32_t)(now - last_step_tick) >= interval) {
last_step_tick = now;
phase_index = (uint8_t)((phase_index + 1U) & 0x07U);
apply_phase(phase_index);
}
}
void StepMotor_ButtonHandler(void)
{
uint32_t now = HAL_GetTick();
/* Debounce: ignore presses within BUTTON_DEBOUNCE_MS of the last one. */
if ((uint32_t)(now - last_btn_tick) < BUTTON_DEBOUNCE_MS) {
return;
}
last_btn_tick = now;
/* Round-robin: STOP -> SLOW -> MED -> FAST -> STOP -> ... */
motor_state = (StepMotor_State_t)(((uint32_t)motor_state + 1U) & 0x03U);
if (motor_state == STATE_STOP) {
coils_off();
BSP_LED_Off(LED_GREEN);
} else {
/* Reset stepping so the sequence starts cleanly from phase 0 and the
* first step fires ~one interval later, not immediately on entry. */
phase_index = 0;
last_step_tick = HAL_GetTick();
last_led_tick = HAL_GetTick();
BSP_LED_Off(LED_GREEN); /* let Tick flip it on the next pass */
}
}主要实现的功能,是通过按键控制电机的状态的切换,同时使用LED进行状态指示。
我要赚赏金
