51单片机控制步进电机(附代码)
步距角为5.625°(5.625°是电机转子每转一步转动的角度),电机转子的转动经过 1:64 减速后,输出轴也同步转动一步,输出轴每步的步距角为 5.625。(电机转子转 1 圈需 360°/5.625°=64 步, 经 1:64 减速后,电机转子要转64圈,输出轴才转1圈,所以输出轴转 1 圈需 64×64=4096步)“Y” 是 “永”(拼音:Yǒng)的首字母,代表该电机为。1、类型:四相
一、硬件基础
28BYJ-48 步进电机参数:
1、类型:四相永磁步进电机(A、B、C、D 四相)。、
2、驱动方式:常用四相八拍(比四相四拍更平稳,步距角更小)
3、减速比:1:64(电机内部有1:64的减速齿轮)
4、驱动模块:通常搭配 ULN2003(达林顿管阵列,放大电流驱动电机)
“28BYJ-48”名称解释:
1. “28”:电机外径尺寸
2. “B”:电机类型(步进电机)
“B” 是 “步”(拼音:Bù)的首字母,代表该电机为步进电机(区别于直流电机 “Z”、交流电机 “J” 等类型)。
3. “Y”:转子类型(永磁式)
“Y” 是 “永”(拼音:Yǒng)的首字母,代表该电机为永磁式步进电机。其转子采用永久磁铁(永磁体)。
4. “J”:结构特征(带减速箱)
“J” 是 “减”(拼音:Jiǎn)的首字母,代表该电机内部集成了减速齿轮箱(减速比 1:64)。
5. “48”:产品系列代号
接线方式

| 51 单片机引脚 | ULN2003 模块 | 说明 |
|---|---|---|
| P1.0 | IN1 | 控制 A 相 |
| P1.1 | IN2 | 控制 B 相 |
| P1.2 | IN3 | 控制 C 相 |
| P1.3 | IN4 | 控制 D 相 |
| VCC | VCC | 单片机与 ULN2003 共 5V 电源 |
| GND | GND | 共地 |
ULN2003 需外接 5V 电源给电机供电(外接5V电源与单片机 5V 可共地,但电机电流较大,建议单独供电)
二、核心控制逻辑
1. 四相八拍驱动原理
步进电机通过按特定顺序给四相绕组通电实现转动,四相八拍的励磁顺序为:A → AB → B → BC → C → CD → D → DA(正转)反转则按相反顺序:DA → D → CD → C → BC → B → AB → A
四相八拍的正转相序为 A → AB → B → BC → C → CD → D → DA(共 8 个状态,循环往复)。每切换到下一个状态(如:A→AB 或 AB→B 等等),即为 “正转 1 步”。即每切换一次相序状态,电机转子或输出轴就转动一步。
“1 步” 的物理意义:在四相八拍驱动下,每步切换一次相序状态后,电机转子转动一步 。步距角为5.625°(5.625°是电机转子每转一步转动的角度),电机转子的转动经过 1:64 减速后,输出轴也同步转动一步,输出轴每步的步距角为 5.625° ÷ 64 ≈ 0.0879°。
四相八拍电机输出轴转 1 圈(360°)需要的步数:4096 步。(电机转子转 1 圈需 360°/5.625°=64 步, 经 1:64 减速后,电机转子要转64圈,输出轴才转1圈,所以输出轴转 1 圈需 64×64=4096步)
三、示范代码
#include <reg52.h>
// 定义控制引脚(连接ULN2003的IN1-IN4,对应A、B、C、D相)
sbit IN1 = P1^0; // A相控制
sbit IN2 = P1^1; // B相控制
sbit IN3 = P1^2; // C相控制
sbit IN4 = P1^3; // D相控制
// 四相八拍正转相序表
unsigned char code ForwardTable[8] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09};
// 四相八拍反转相序表
unsigned char code ReverseTable[8] = {0x09, 0x08, 0x0C, 0x04, 0x06, 0x02, 0x03, 0x01};
// 全局变量:步间延时(毫秒),控制转速(值越小,转速越快)
unsigned int stepDelay = 5; // 默认延时5ms(对应约6 RPM)6RPM为每分钟转6圈
/**
* 延时函数(控制每步的间隔时间)
* @param ms:延时毫秒数
*/
void DelayMs(unsigned int ms) {
unsigned int i, j;
for(i = ms; i > 0; i--)
for(j = 112; j > 0; j--); // 12MHz晶振下,约1ms延时(需校准)
}
/**
* 设置步进电机转速(输出轴转速,单位:RPM,转/分钟)
* 在四相八拍时,输出轴1圈=4096步,转速与步间延时的关系:
* stepDelay(ms) = 60000 / (RPM × 4096),计算在特定转速下输出轴每转一步要耗费多少毫秒。
* (RPM × 4096)是输出轴每分钟转动的步数;1分钟=60000ms
* @param rpm:目标转速(建议范围1-15 RPM,过高会丢步)
*/
void setSpeed(unsigned int rpm) {
unsigned long calcDelay; // 用于计算延时(避免溢出)
// 限制转速范围(1-15 RPM为实际有效范围)
if(rpm < 1) rpm = 1;
if(rpm > 15) rpm = 15;
// 计算步间延时:60秒=60000毫秒,总步数=RPM×4096步/分钟
calcDelay = 60000;
calcDelay /= (unsigned long)rpm * 4096; // 得到每步所需毫秒数
// 若计算结果为0(高转速时),强制设为1ms(避免无延时导致丢步)
stepDelay = (calcDelay == 0) ? 1 : (unsigned int)calcDelay;
}
/**
* 输出轴正转N步(使用当前设置的转速)
* @param N:转动步数
*/
void ForwardNSteps(unsigned int N) {
unsigned int step;
unsigned char phase = 0;
for(step = 0; step < N; step++) {
P1 = ForwardTable[phase]; //切换相序状态,每切换一次输出轴转动一步。
DelayMs(stepDelay); // 使用动态延时(由setSpeed设置)
phase = (phase + 1) % 8; //限制phase的范围在0~7
}
}
/**
* 输出轴反转N步(使用当前设置的转速)
* @param N:转动步数
*/
void ReverseNSteps(unsigned int N) {
unsigned int step;
unsigned char phase = 0;
for(step = 0; step < N; step++) {
P1 = ReverseTable[phase];
DelayMs(stepDelay); // 使用动态延时
phase = (phase + 1) % 8;
}
}
// 主函数:示例不同转速下的转动效果
void main() {
while(1) {
// 1. 低速测试:3 RPM(较慢)
setSpeed(3);
ForwardNSteps(2048);
DelayMs(1000);
// 2. 中速测试:8 RPM(中等速度)
setSpeed(8);
ReverseNSteps(4096); // 反转1圈(4096步)
DelayMs(1000);
}
}
更多推荐



所有评论(0)