[i=s] 本帖最后由 无垠的广袤 于 2025-6-2 05:55 编辑 [/i]<br />
<br />
【AT-START-M412测评】步进电机的驱动与控制
本文介绍了雅特力 AT32M412 开发板实现 28BYJ-48 步进电机的驱动,以及旋转角度和速度的精确控制,并串口打印旋转状态的项目设计。
项目介绍
- AT32M412 开发板结合 ULN2003 步进电机驱动板实现 28BYJ-48 步进电机的转动;
- 通过 4 相 8 拍调节,实现步数与旋转角度的转换,进而精确控制步进电机的旋转角度和速度(相位切换延时);
- 串口打印步进电机的实时旋转状态。
硬件连接
AT32M412CBT7 |
ULN2003驱动板 |
28BYJ-48 步进电机 |
PA3 |
IN1 |
红 (A+) |
PA4 |
IN2 |
蓝 (A-) |
PA5 |
IN3 |
粉 (B+) |
PA6 |
IN4 |
黄 (B-) |
5V |
VCC |
电机电源正极 |
GND |
GND |
电机电源负极 |
工程创建
- 打开 AT32 Work Bench 软件,选择工作空间,选择目标芯片
AT32M412CBT7
,点击 新建
;
- 进入
外设
- GPIO
选项进行参数配置;
- 将引脚 PA3、PA4、PA5 和 PA6 配置为 GPIO 输出模式;

- 使能 USART1 选项,选择
异步模式
,配置 PA9 和 PA10 引脚为 USART1 模式;
- 进入 SYSTEM 模块,选择 USART1 串口打印;
- 其他参数均为默认,点击
生成代码
并打开项目。
流程图

工程代码
代码主要包括步进电机驱动函数、头文件、主函数三部分。
主函数
#include "at32m412_416_wk_config.h"
#include "wk_usart.h"
#include "wk_gpio.h"
#include "wk_system.h"
#include "step_motor.h"
int main(void)
{
wk_system_clock_config();
wk_periph_clock_config();
wk_nvic_config();
wk_timebase_init();
wk_gpio_config();
wk_usart1_init();
while(1)
{
float angle = 180;
int8_t speed = 10;
printf("Rotating %.0f degree clockwise...\r\n", angle);
Stepper_RotateAngle(angle, speed);
Stepper_ReleaseTorque();
wk_delay_ms(1000);
printf("Rotating %.0f degree counter-clockwise...\r\n", angle);
Stepper_RotateAngle(-angle, speed);
Stepper_ReleaseTorque();
wk_delay_ms(1000);
}
}
电机驱动代码
新建 step_motor.c
文件,添加如下代码
#include "step_motor.h"
#include <stdlib.h>
#include "wk_system.h"
const uint8_t phase_table[8][4] = {
{1, 0, 0, 0}, // A
{1, 1, 0, 0}, // A+B
{0, 1, 0, 0}, // B
{0, 1, 1, 0}, // B+C
{0, 0, 1, 0}, // C
{0, 0, 1, 1}, // C+D
{0, 0, 0, 1}, // D
{1, 0, 0, 1} // D+A
};
void Stepper_Init(void) {
gpio_init_type gpio_init_struct;
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
gpio_init_struct.gpio_pins = GPIO_PINS_3 | GPIO_PINS_4 | GPIO_PINS_5 | GPIO_PINS_6;
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init(GPIOA, &gpio_init_struct);
Stepper_ReleaseTorque();
}
void Stepper_Step(int32_t steps, uint16_t delay_ms)
{
uint8_t direction = (steps > 0) ? 1 : 0;
uint32_t step_count = abs(steps);
int i;
for (i = 0; i < step_count; i++)
{
static uint8_t phase = 0;
phase = direction ? (phase + 1) % 8 : (phase + 8 - 1) % 8;
GPIOA->odt = (GPIOA->odt & ~0x78) | // PA3-PA6
(phase_table[phase][0] << 3) | // PA3
(phase_table[phase][1] << 4) | // PA4
(phase_table[phase][2] << 5) | // PA5
(phase_table[phase][3] << 6); // PA6
wk_delay_ms(delay_ms);
}
}
void Stepper_RotateAngle(float angle, int8_t speed)
{
uint16_t ROUND_VALUE = 4096; // steps number for one round
int32_t steps = (int32_t)(ROUND_VALUE * angle / 360.0f);
float step_delay_ms;
if (speed < 0 || speed > 10)
{
printf("Error: Speed must be between 0 and 10.");
Stepper_ReleaseTorque();
return;
}
if (speed == 0)
{
Stepper_ReleaseTorque();
return;
}
step_delay_ms = (10 - 1) / 9 * (10 - speed) + 1;
Stepper_Step(steps, step_delay_ms);
}
void Stepper_ReleaseTorque(void)
{
GPIOA->odt &= ~(GPIO_PINS_3 | GPIO_PINS_4 | GPIO_PINS_5 | GPIO_PINS_6); // PA3~PA6
}
电机驱动头文件
新建 step_motor.h
文件,添加如下代码
#ifndef __STEP_MOTOR_H
#define __STEP_MOTOR_H
#include "at32m412_416.h"
void Stepper_Init(void);
void Stepper_Step(int32_t steps, uint16_t delay_ms);
void Stepper_RotateAngle(float angle, int8_t speed);
void Stepper_ReleaseTorque(void);
#endif
保存代码,重新构建工程,上传固件至板端,复位运行。
效果演示
正反各旋转 180 度,间隔 1 秒

同时串口打印旋转状态

总结
本文介绍了雅特力 AT32M412 开发板实现 28BYJ-48 步进电机驱动和旋转,并串口打印旋转状态,为 AT32M412 系列单片机的应用和快速开发提供了参考。