当前位置: 首页 > news >正文

STM32之28BYJ-48步进电机驱动

目录

一、引言

二、28BYJ-48步进电机简介

2.1  基本特性

2.2  内部结构

2.3  工作模式

2.4  驱动原理

2.5  性能特点

2.6  驱动方案

2.7  使用注意事项

三、ULN2003驱动板简介

3.1  基本概述

3.2  电路结构

3.3  驱动原理

3.4  接口定义

3.5  使用注意事项

四、硬件准备

五、硬件连接

5.1 接线示意图

5.2  电源注意事项

六、软件设计

6.1 开发环境配置

6.2 关键代码实现

6.2.1 引脚定义与初始化

6.2.2 步进序列定义

6.2.3 定时器配置(TIM4)

6.2.4 运动控制核心逻辑

七、功能实现

7.1  基本运动控制

7.2  速度控制

7.3  加减速控制

八、应用示例

8.1 简单测试程序

8.2 带加减速的位置控制

九、常见问题解决

十、总结


一、引言

        28BYJ-48步进电机因其价格低廉、控制简单等特点,在各类小型自动化项目中广泛应用。本文将详细介绍如何使用STM32F103C8T6单片机通过ULN2003驱动芯片控制这种步进电机,实现正反转、调速和精确位置控制。

二、28BYJ-48步进电机简介

2.1  基本特性

电机类型:

  • 永磁式步进电机(Unipolar)
  • 内置1:64减速齿轮箱

电气参数:

  • 额定电压:5V DC

  • 相电流:约100-120mA/相

  • 线圈电阻:50Ω/相

  • 驱动方式:单极性驱动(ULN2003驱动板兼容)

机械参数:

  • 步距角:5.625°(原始步距)

  • 减速后步距角:5.625°/64 ≈ 0.0879°

  • 输出轴转速范围:0-15 RPM(建议工作范围)

电机图片:

2.2  内部结构

电磁部分:

  • 4相8极绕组结构

  • 每组线圈中心抽头接正极

齿轮箱结构:

  • 四级行星齿轮减速

  • 总减速比1:64

  • 输出轴扭矩:≥34.3mN·m(5V时)

2.3  工作模式

模式步数/转步距角特点
全步(单相)64步5.625°低分辨率,振动较大
全步(双相)64步5.625°扭矩大,功耗高
半步128步2.8125°分辨率提高,运行更平稳
8步微步512步0.703°最高分辨率,需专用驱动

2.4  驱动原理

励磁顺序(以全步双相为例):

// 4相8拍驱动序列
const uint8_t seq[8] = {0b1000, // A0b1100, // A+B0b0100, // B0b0110, // B+C0b0010, // C0b0011, // C+D0b0001, // D0b1001  // D+A
};

转速计算: 

例:每秒683脉冲 → 10 RPM (转每分钟)

2.5  性能特点

优点

  • 价格低廉

  • 驱动电路简单(ULN2003即可)

  • 低速大扭矩输出

  • 保持转矩大(断电后能保持位置)

局限性

  • 最高转速较低(通常<15RPM)

  • 齿轮箱存在回程差(约3°)

  • 长时间工作可能发热

2.6  驱动方案

驱动方案对比:

驱动芯片最大电流特点
ULN2003500mA经济,适合低速应用
DRV88252.5A支持微步,精度高
A49882A带过热保护

2.7  使用注意事项

电气保护

  • 反接保护二极管必接

  • 避免长时间堵转(>2秒)

机械安装

  • 输出轴避免径向受力

  • 齿轮箱需定期润滑(硅脂)

        该电机特别适合学生项目和原型开发,其优异的性价比使其成为入门级运动控制的首选。实际使用时建议配合光电编码器实现闭环控制以提升精度。

三、ULN2003驱动板简介

3.1  基本概述

        ULN2003驱动板是专为28BYJ-48等小型步进电机设计的低成本驱动模块,核心采用ULN2003达林顿阵列芯片,具有以下特性:

关键参数

  • 工作电压:5-12V(与电机电压匹配)

  • 单路最大电流:500mA

  • 总功耗:1.5W(需配合散热片)

  • 输入兼容性:3.3V/5V逻辑电平

板载资源

  • 4路LED指示灯(显示相位状态)

  • 反接保护二极管

  • 电机接口防插反设计

  • 5.08mm间距接线端子

UNL2003驱动板示意图:

ULN2003原理图: 

3.2  电路结构

核心芯片

ULN2003包含7路达林顿管(实际使用4路)。

典型应用电路

3.3  驱动原理

相位控制真值表:

步序IN1IN2IN3IN4励磁相
11000A
21100AB
30100B
..................

电流路径(以A相为例):

5V -> 线圈A -> ULN2003_OUT1 -> 达林顿管 -> GND

3.4  接口定义

引脚标号功能说明连接目标
IN1-IN4相位控制输入MCU GPIO
VCC逻辑电源(可选)MCU 5V
GND公共地电源地
A-D电机相线输出28BYJ-48对应相线

3.5  使用注意事项

电源配置

当电机电压>5V时,建议:

  •     逻辑电源(VCC)接MCU
  •     5V电机电源单独供电

保护措施

  • 电机断电时产生的反电动势可能达30V,必须保留板载续流二极管

  • 长时间工作需监测芯片温度(>70℃应停止使用)

典型问题处理

  • 电机抖动不转:检查相位顺序是否正确

  • 驱动芯片发烫:

        (1)降低PWM频率(建议<2kHz)

        (2)增加散热片

四、硬件准备

所需材料:

  • STM32F103C8T6最小系统板

  • 28BYJ-48步进电机(带ULN2003驱动板)

  • 杜邦线若干

  • USB转TTL模块(用于程序下载)

  • 电源(5V/2A)

五、硬件连接

5.1 接线示意图

STM32F103C8T6ULN2003驱动板
PB6IN1
PB7IN2
PB8IN3
PB9IN4
GNDGND
5VVCC 

5.2  电源注意事项

建议为电机驱动单独供电,避免单片机电源受干扰。

六、软件设计

6.1 开发环境配置

  1. 安装Keil MDK-ARM

  2. 安装STM32标准外设库

  3. 配置工程包含必要头文件

6.2 关键代码实现

6.2.1 引脚定义与初始化

// 引脚定义
#define IN1_PIN    GPIO_Pin_6
#define IN2_PIN    GPIO_Pin_7
#define IN3_PIN    GPIO_Pin_8
#define IN4_PIN    GPIO_Pin_9
#define MOTOR_PORT GPIOB// GPIO初始化
void GPIO_Init(void) {GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStruct.GPIO_Pin = IN1_PIN | IN2_PIN | IN3_PIN | IN4_PIN;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(MOTOR_PORT, &GPIO_InitStruct);
}

6.2.2 步进序列定义

// 8步驱动序列(更高精度)
const uint8_t stepSequence[8] = {0b1000,  // A0b1100,  // AB0b0100,  // B0b0110,  // BC0b0010,  // C0b0011,  // CD0b0001,  // D0b1001   // DA
};

6.2.3 定时器配置(TIM4)

void TIM4_Init(void) {TIM_TimeBaseInitTypeDef TIM_InitStruct;NVIC_InitTypeDef NVIC_InitStruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);// 1MHz计数频率(1μs分辨率)TIM_InitStruct.TIM_Period = 1000;  // 初始ARR值TIM_InitStruct.TIM_Prescaler = SystemCoreClock/1000000 - 1;TIM_InitStruct.TIM_ClockDivision = 0;TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM4, &TIM_InitStruct);TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);NVIC_InitStruct.NVIC_IRQChannel = TIM4_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct);TIM_Cmd(TIM4, ENABLE);
}

6.2.4 运动控制核心逻辑

// 全局变量
volatile int32_t stepPosition = 0;
volatile int32_t targetSteps = 0;
volatile uint32_t stepDelay = 2000;  // 初始延迟2000μs
volatile int8_t direction = 1;// 设置电机相位
void SetMotorPhase(uint8_t phase) {GPIO_WriteBit(MOTOR_PORT, IN1_PIN, (phase & 0x08) ? Bit_SET : Bit_RESET);GPIO_WriteBit(MOTOR_PORT, IN2_PIN, (phase & 0x04) ? Bit_SET : Bit_RESET);GPIO_WriteBit(MOTOR_PORT, IN3_PIN, (phase & 0x02) ? Bit_SET : Bit_RESET);GPIO_WriteBit(MOTOR_PORT, IN4_PIN, (phase & 0x01) ? Bit_SET : Bit_RESET);
}// 定时器中断服务函数
void TIM4_IRQHandler(void) {static uint8_t currentPhase = 0;if (TIM_GetITStatus(TIM4, TIM_IT_Update)) {TIM_ClearITPendingBit(TIM4, TIM_IT_Update);if ((direction > 0 && stepPosition < targetSteps) || (direction < 0 && stepPosition > targetSteps)) {currentPhase = (currentPhase + direction + 8) % 8;SetMotorPhase(stepSequence[currentPhase]);stepPosition += direction;// 更新定时器TIM_SetAutoreload(TIM4, stepDelay);TIM_SetCounter(TIM4, 0);} else {SetMotorPhase(0x00);  // 停止电机}}
}

七、功能实现

7.1  基本运动控制

// 相对移动
void MoveSteps(int32_t steps) {targetSteps = stepPosition + steps;direction = (steps > 0) ? 1 : -1;
}// 绝对移动
void MoveToPosition(int32_t position) {targetSteps = position;direction = (position > stepPosition) ? 1 : -1;
}

7.2  速度控制

// 设置转速(RPM)
void SetSpeed(float rpm) {// RPM转步进延迟(μs)uint32_t delay = (60 * 1000000) / (4096 * rpm);// 限制在合理范围if (delay < 800) delay = 800;    // 最大约15RPMif (delay > 10000) delay = 10000; // 最小约1.46RPMstepDelay = delay;
}

7.3  加减速控制

// 梯形加减速控制
void UpdateSpeed(void) {static uint32_t acceleration = 100; // 加速度步/秒²int32_t remainingSteps = abs(targetSteps - stepPosition);// 加速阶段(前1/3路程)if (remainingSteps > (2 * totalSteps / 3)) {if (stepDelay > minDelay + acceleration) {stepDelay -= acceleration;}} // 减速阶段(后1/3路程)else if (remainingSteps < (totalSteps / 3)) {if (stepDelay < maxDelay - acceleration) {stepDelay += acceleration;}}
}

八、应用示例

8.1 简单测试程序

实现正转一圈然后反转一圈循环。

int main(void) {SystemInit();GPIO_Init();TIM4_Init();// 设置转速为10RPMSetSpeed(10.0);while(1) {// 正转1圈MoveSteps(4096);while(stepPosition < targetSteps);Delay_ms(1000);// 反转1圈MoveSteps(-4096);while(stepPosition > targetSteps);Delay_ms(1000);}
}

8.2 带加减速的位置控制

可设置目标位置以及速度。

void ControlledMove(int32_t target, float speed) {SetSpeed(speed);MoveToPosition(target);while(stepPosition != target) {UpdateSpeed();  // 实时更新速度Delay_ms(1);}
}

九、常见问题解决

电机抖动但不转动:

  1. 检查电源是否充足(≥5V/1A)
  2. 验证步进序列是否正确

  3. 确保接线牢固

转速达不到预期:

  1. 适当减小minDelay
  2. 检查ULN2003是否过热

  3. 确认电机负载是否过大

位置控制不准确:

  1. 增加减速阶段时间
  2. 考虑使用闭环控制(如加装编码器)

优化建议:

  1. 微步驱动:通过PWM实现更精细的256微步控制

  2. 闭环控制:增加编码器反馈实现真正的位置闭环

  3. 电流控制:动态调整相电流以降低发热

十、总结

        本文详细介绍了使用STM32F103C8T6控制28BYJ-48步进电机的完整方案,包括硬件连接、软件实现和运动控制算法。通过合理设置参数,可以实现精确的位置控制和速度调节,满足大多数小型自动化项目的需求。

http://www.lryc.cn/news/577105.html

相关文章:

  • stm32 USART串口协议与外设(程序)——江协教程踩坑经验分享
  • SRS流媒体服务器之本地测试rtc推流bug
  • 【系统分析师】高分论文:论软件开发模型及应用
  • 2025.6.29总结
  • MySQL的调控按钮
  • Java面试宝典:基础三
  • FPGA实现CameraLink视频解码,基于Xilinx ISERDES2原语,提供4套工程源码和技术支持
  • 应用层网络编程范式
  • 基于Java+Springboot的宠物健康咨询系统
  • 数据分析标普500
  • Linux下基于C++11的socket网络编程(基础)个人总结版
  • 数据库 DML 语句详解:语法与注意事项
  • 训练营总结
  • C++高效结合主流工具:现代系统底层动力
  • 浅谈AI大模型-MCP
  • 基于SSM + JSP 的宿舍管理系统
  • JVM基础--JVM的组成
  • AlpineLinux安装部署elasticsearch
  • STM32——HAL库总结
  • 详解快速排序
  • http相关网络问题面试怎么答
  • 矩阵的逆 线性代数
  • Vue中keep-alive结合router实现部分页面缓存
  • 【NLP 实战】蒙古语情感分析:从 CNN 架构设计到模型训练的全流程解析(内附项目源码及模型成果)
  • 【Flask开发】嘿马文学web完整flask项目第2篇:2.用户认证,Json Web Token(JWT)【附代码文档】
  • Nginx漏洞处理指南
  • python pyecharts 数据分析及可视化(2)
  • Prompt工程标准化在多模型协同中的作用
  • swift-19-从OC到Swift、函数式编程
  • 设计模式 | 过滤器模式