一、硬件基础

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);
    }
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐