1. 项目背景与硬件选型28BYJ-48步进电机作为典型的4相5线减速电机因其低成本、易获取的特点成为入门级项目的首选。这款电机内部采用1:64的减速齿轮组虽然牺牲了转速但大幅提升了扭矩。实测空载转速约15RPM单步角度5.625°经过减速后实际步距角为0.0879°即4096步/转。ULN2003达林顿阵列芯片是驱动这类电机的经典方案其内部包含7组NPN达林顿管每组可承受500mA电流。驱动28BYJ-48时我们使用其中的4路剩余3路可留作其他外设控制。与专用驱动芯片如A4988相比ULN2003的优势在于无需复杂的细分控制逻辑内置续流二极管保护电路可直接兼容3.3V/5V逻辑电平硬件连接示意图STM32 GPIO - ULN2003 IN1~IN4 - ULN2003 COM端接5V电源 28BYJ-48 - ULN2003 OUT1~OUT4关键细节电机红线接5V其他四色线蓝/粉/黄/橙对应ULN2003输出端。若电机反转只需调换任意两相接线顺序。2. STM32开发环境配置推荐使用STM32CubeIDE进行开发其优势在于自动生成初始化代码可视化配置时钟树集成STM32CubeMX功能具体配置步骤新建工程时选择对应STM32型号如F103C8T6在Pinout视图中配置4个GPIO为推挽输出模式时钟树配置保持默认即可72MHz主频生成代码前勾选Generate peripheral initialization as a pair of .c/.h files关键代码片段以PA0~PA3为例// 在main.c的USER CODE BEGIN 2部分添加 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_RESET); // 电机相位定义 const uint16_t phase[8] { GPIO_PIN_0, // 相位1 GPIO_PIN_0|GPIO_PIN_1, // 相位2 GPIO_PIN_1, // 相位3 GPIO_PIN_1|GPIO_PIN_2, // 相位4 GPIO_PIN_2, // 相位5 GPIO_PIN_2|GPIO_PIN_3, // 相位6 GPIO_PIN_3, // 相位7 GPIO_PIN_3|GPIO_PIN_0 // 相位8 };3. 单步驱动算法实现28BYJ-48采用8拍驱动方式即8步完成一个完整周期相比4拍模式运行更平稳但扭矩略低。每个相位激活时电流约120mA因此需要注意时序控制void step_motor(int steps, uint32_t delay_ms) { static uint8_t phase_idx 0; int direction (steps 0) ? 1 : -1; while(steps ! 0) { phase_idx (phase_idx direction 8) % 8; GPIOA-ODR (GPIOA-ODR 0xFFF0) | phase[phase_idx]; HAL_Delay(delay_ms); steps - direction; } }速度控制要点最小延迟不应小于3ms防止线圈未充分励磁加速度控制建议采用S曲线算法急停时需保持最后相位通电防止失步实测数据对比延迟(ms)转速(RPM)扭矩(g·cm)3153001054505015004. 实用功能扩展4.1 按键控制实现通过外部中断实现正反转控制// 在stm32f1xx_it.c中添加 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin KEY1_PIN) { step_motor(512, 5); // 正转一圈 } else if(GPIO_Pin KEY2_PIN) { step_motor(-512, 5); // 反转一圈 } }4.2 串口指令控制添加HAL_UART_RxCpltCallback回调void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(rx_data[0] F) { step_motor(atoi(rx_data1), 3); } else if(rx_data[0] S) { current_delay atoi(rx_data1); } HAL_UART_Receive_IT(huart, rx_data, 1); }4.3 位置记忆功能利用STM32内部Flash实现#define POS_ADDR 0x0801F000 void save_position(int32_t pos) { HAL_FLASH_Unlock(); FLASH_EraseInitTypeDef erase { .TypeErase FLASH_TYPEERASE_PAGES, .PageAddress POS_ADDR, .NbPages 1 }; uint32_t err; HAL_FLASHEx_Erase(erase, err); HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, POS_ADDR, pos); HAL_FLASH_Lock(); }5. 常见问题排查电机抖动不转检查ULN2003的COM端是否接电源测量GPIO输出电平是否正常应有3.3V确认相位顺序是否正确可用万用表测量线圈通断发热严重降低驱动频率增加延迟时间添加散热片到ULN2003采用PWM方式降低平均电流定位不准检查机械结构是否有卡顿增加减速比物理减速或软件细分启用闭环控制需加装编码器实测中发现使用5V/1A电源时连续运行30分钟后ULN2003表面温度约65℃建议在长时间工作时将驱动电流降至80mA通过串联电阻采用间歇工作模式运行2分钟停10秒或者升级到DRV8825等专业驱动芯片