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.pswp.cn/news/912883.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912883.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TDSQL如何查出某一列中的逗号数量

在 TDSQL 中&#xff0c;要统计某一列里逗号的数量&#xff0c;可借助字符串函数来实现。下面为你介绍具体的实现方法&#xff1a; sql SELECT your_column,LENGTH(your_column) - LENGTH(REPLACE(your_column, ,, )) AS comma_count FROM your_table;下面对这段 SQL 进行详细…

如何避免服务器出现故障情况?

服务器作为存储数据信息的重要网络设备&#xff0c;能够保护企业重要数据的安全性&#xff0c;但是随着网络攻击的不断拓展&#xff0c;各个行业中的服务器也会遭受到不同类型的网络攻击&#xff0c;严重的会导致服务器业务中断出现故障&#xff0c;给企业带来巨大的经济损失。…

C++ 优先级队列

一、引言 队列的特性是先进先出。优先级队列的本质是一个有序队列&#xff0c;根据成员的优先级&#xff0c;对队列中的成员进行排序。优先级队列默认是大顶堆&#xff0c;即堆顶元素最大 二、常用函数 empty()size()top()push()emplace()pop()swap() 三、代码示例 class …

学习笔记(27):线性回归基础与实战:从原理到应用的简易入门

线性回归&#xff1a;通过拟合线性方程&#xff08;如 \(y w_1x_1 w_2x_2 b\)&#xff09;预测房价、销售额等连续变量&#xff0c;需掌握特征标准化、正则化&#xff08;L1/L2&#xff09;防止过拟合。应用场景&#xff1a;金融领域的股价预测、电商用户消费金额预估。 线性…

kubesphere安装openelb

kubesphere安装openelb 1.安装openelb 2.修改配置文件 1.命令直接修改 $ kubectl edit configmap kube-proxy -n kube-system ipvs:strictARP: truemode: "ipvs"重启kube-proxy组件 $ kubectl rollout restart daemonset kube-proxy -n kube-system 2.通过界面去修…

数据库10:MySQL的数据类型与约束和属性设置,数据模式

一.数据类型 整数类型&#xff08;integer types&#xff09; 数据类型字节有符号范围无符号范围说明tinyint1-128 ~ 1270 ~ 255非常小的整数smallint2-32,768 ~ 32,7670 ~ 65,535小整数mediumint3-8,388,608 ~ 8,388,6070 ~ 16,777,215中等整数int4-2,147,483,648 ~ 2,147,4…

uniapp项目中node_modules\sass\sass.dart.js的体积过大怎么处理

用Node-Sass替代&#xff08;如果适用&#xff09;&#xff1a;虽然Dart Sass是Sass的主要实现之一&#xff0c;但有时它可能会比Node-Sass占用更多的空间。如果你不需要Dart Sass特有的功能&#xff0c;可以考虑切换到Node-Sass&#xff08;注意Node-Sass已停止维护&#xff0…

界面组件DevExpress WPF中文教程:Grid - 如何获取节点?

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

Kalibr解毒填坑(一):相机标定失败

文章目录 📚简介🍀 解毒踩坑🚀 主点错误📚简介 相机内参标定通常涉及确定焦距(fx, fy)、主点(cx, cy)、畸变系数(径向和切向)等参数。Kalibr是一个开源的标定工具,支持多相机、IMU和联合标定,适用于复杂的传感器系统。 但kalibar标定相机内参受到数据和配置影…

Swift 的基础设计哲学是 “通过模块化组合实现安全与效率的平衡“,就像用标准化工业零件建造摩天大楼

一、基础模块&#xff1a;地基与钢结构&#xff08;Basic Types & Collections&#xff09; 比喻&#xff1a;积木与工具箱&#xff0c;决定建筑的稳定性和容量。场景&#xff1a;搭建程序的基础结构&#xff0c;如变量、数据类型、运算符。包含&#xff1a;基本语法、运算…

【RK3568+PG2L50H开发板实验例程】Linux部分/FPGA dma_memcpy_demo 读写案例

本原创文章由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处&#xff08;www.meyesemi.com) 1.案例简介 案例功能描述&#xff1a;ARM端利用 PCIe总线对 FPGA的 DRAM执行读写操作。应用程序通过 ioctl函数触发 …

7.3实验部分

一、HDFS基础操作 以root用户登录&#xff0c;创建如下HDFS目录&#xff1a; /dw/yourname/input hadoop fs -mkdir -p /dw/zhanggengchen/input /dw/yourname/output hadoop fs -mkdir -p /dw/zhanggengchen/output 输出结果&#xff1a; [rootmaster hadoop-mapreduce]# ha…

[nett5: AddressedEnvelope]-源码解析

AddressedEnvelope AddressedEnvelope<M, A> 表示一个带有发送者和接收者地址的消息封装&#xff0c;常用于处理如 UDP 数据报这类含地址信息的通信场景。 public interface AddressedEnvelope<M, A extends SocketAddress> {// 实际的消息内容M content();// 消…

基于 Drone CI 实现前端自动化打包并集成 Spug 自动发布流程

前言&#xff1a;代码自动化部署目前使用的是Spug开源运维平台&#xff0c;通过docker直接部署该平台后&#xff0c;在前端自动化打包&#xff08;npm run build&#xff09;会遇见Node的版本问题&#xff0c;因为Spug容器使用的是Centos7&#xff0c;所以Node版本只支持V16&am…

【基础】Golang语言开发环境搭建(Linux主机)

目录 1. 下载并安装Go语言2. 配置环境变量3. 验证安装4. 配置Go模块5. 安装常用开发工具6. 配置IDE&#xff08;可选&#xff09;7. 第一个Go程序 在Linux主机上搭建Golang开发环境&#xff0c;你可以按照以下步骤进行操作&#xff1a; 1. 下载并安装Go语言 首先从官网下载Go…

MySQL安全加固:使用mysql_secure_installation

在安装MySQL后&#xff0c;为了确保服务器的安全性&#xff0c;建议使用mysql_secure_installation工具对MySQL进行安全加固。这个工具可以帮助我们完成一些关键的安全配置&#xff0c;包括设置强密码、移除匿名用户、限制root用户的远程登录以及清理默认的测试数据库等。以下是…

设计模式之中介者模式 (Mediator Pattern) -聊天室-控制室

中介者模式用于减少多个对象之间的直接通信&#xff0c;而是通过一个中介对象来协调它们之间的交互。下面我用一个聊天室的例子来演示这个模式。 举个栗子&#xff1a;聊天室系统 在这个系统中&#xff0c;用户不直接相互发送消息&#xff0c;而是通过聊天室&#xff08;中介者…

SpringSecurity01

目录 一、权限控制 二、相关框架 1、shiro 2、springsecurity 三、springsecurity使用流程 1、搭建环境实现默认用户名和密码登录 2、使用数据库表中定义好的用户名和密码访问实现等值密码匹配 1&#xff09;sql文件 2)搭建jdbc或者mybatis或者mybatis-plus环境 3&am…

解决git clone报错:fatal unable to access xxx. Could not resolve host github.com

作者&#xff1a;唐叔在学习 专栏&#xff1a;问题百宝箱 文章目录 问题描述问题诊断网络连通性测试 解决方案1. 获取GitHub最新IP地址2. 修改系统hosts文件 验证解决方案常见问题解答总结 问题描述 当使用git clone命令克隆GitHub仓库时&#xff0c;可能会遇到如下错误&#…

魔术方法__call__

__call__ 是一个特殊方法&#xff08;也称为魔术方法&#xff09;&#xff0c;用于使一个类的实例能够像函数一样被调用。当定义了这个方法后&#xff0c;实例对象可以后接括号&#xff08;即 ()&#xff09;来触发调用&#xff0c;这会让实例表现得像函数一样。 ​使实例可调…