人若无名 便可潜心练剑.|

hazy1k

园龄:7个月粉丝:14关注:0

2024-08-20 09:45阅读: 50评论: 0推荐: 0

第14章 步进电机实验

第十四章 步进电机实验

1. 导入

前面章节, 我们介绍了直流电机的控制, 本章将向大家介绍步进电机, 步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。 本章主要从步进电机的结构、 工作原理、 电机参数分别介绍, 最后通过实验来实现步进电机运动的简单控制。 本章所要实现的功能是: 通过 ULN2003 驱动模块控制 28BYJ48 步进电机运行方向及速度, 当按下 KEY1 键可调节电机旋转方向; 当按下 KEY2 键, 电机加速; 当按下 KEY3 键, 电机减速。

2. 步进电机简介

步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。 在非超载的情况下, 电机的转速、 停止的位置只取决于脉冲信号的频率和脉冲数, 而不受负载变化的影响, 即给电机加一个脉冲信号, 电机则转过一个步距角。

这一线性关系的存在, 加上步进电机只有周期性的误差而无累计误差等特点。 使得在速度、位置等控制领域用步进电机来控制变的非常的简单。 虽然步进电机已被广泛的应用, 但步进电机并不能像普通的直流电机, 交流电机在常规下使用。 它必须由双环形脉冲信号、 功率驱动电路等组成控制系统方可使用。

屏幕截图 2024 06 07 101845

和其他芯片一样,我们只要会用就行,至于什么结构,将来专业课会介绍步进电机_百度百科 (baidu.com)

3. 步进电机工作原理

过于专业,我们不讨论,想要了解可以参考一下:

步进电机基本原理及驱动方式详解_步进电机驱动器细分原理-CSDN博客

图解: 步进电机原理与驱动方式 - 知乎 (zhihu.com)

4相5线步进电机驱动原理_四相五线步进电机工作原理-CSDN博客

4. 步进电机技术指标

4.1 静态技术指标

  • 相数:产生不同对极 N、 S 磁场的激磁线圈对数, 也可以理解为步进电机中线圈的组数, 其中两相步进电机步距角为 1.8° , 三相的步进电机步距角为1.5° , 相数越多的步进电机, 其步距角就越小。

  • 拍数:完成一个磁场周期性变化所需脉冲数或导电状态用 n 表示, 或指电机转过一个齿距角所需脉冲数, 以四相电机为例, 有四相四拍运行方式即AB-BC-CD-DA-AB, 四相八拍运行方式即 A-AB-B-BC-C-CD-D-DA-A。

  • 步距角:一个脉冲信号所对应的电机转动的角度, 可以简单理解为一个脉冲信号驱动的角度, 电机上都有写, 一般 42 步进电机的步距角为 1.8°

  • 定位转矩:电机在不通电状态下, 电机转子自身的锁定力矩( 由磁场齿形的谐波以及机械误差造成的) 。

  • 静转距:电机在额定静态电压作用下, 电机不作旋转运动时, 电机转轴的锁定力矩。 此力矩是衡量电机体积的标准, 与驱动电压及驱动电源等无关。

4.2 动态技术指标

  • 步距角精度:步进电机转动一个步距角度的理论值与实际值的误差。 用百分比表示: 误差/步距角 *100%。

  • 失步:电机运转时运转的步数, 不等于理论上的步数。 也可以叫做丢步,一般都是因负载太大或者是频率过快。

  • 失调角:转子齿轴线偏移定子齿轴线的角度, 电机运转必存在失调角, 由失调角产生的误差, 采用细分驱动是不能解决的。

  • 最大空载起动频率:在不加负载的情况下, 能够直接起动的最大频率。

  • 最大空载的运行频率:电机不带负载的最高转速频率。

  • 运行转距特性:电机的动态力矩取决于电机运行时的平均电流( 而非静态电流) , 平均电流越大, 电机输出力矩越大, 即电机的频率特性越硬。

  • 电机正反转控制:通过改变通电顺序而改变电机的正反转。

更多可以参考:步进电机参数解读(主要技术参数)_旋转步进电机 - 鸣志官网 (moons.com.cn)

步进电机型号,尺寸,参数表(CK3)-中国步进电机网 (zgbjdj.com)

5. 28BYJ-48步进电机简介

我们做实验用到的步进电机为:28BYJ-48 步进电机,该步进电机自带减速器,为四相无线步进电机,直径为28mm,实物图及内部结构如下:

屏幕截图 2024 06 07 103809

28BYJ48 步进电机旋转驱动方式如下表:

屏幕截图 2024 06 07 103913

28BYJ48 步进电机主要参数如下所示:

屏幕截图 2024 06 07 104204

在上图中 28BYJ48 步进电机主要参数中可以看到有一个减速比: 1:64, 步进角为 5.625/64 度, 如果需要转动一圈, 那么需要 360/5.625*64=4096 个脉冲信号

减速比这个和之前介绍的直流减速电机有点类似, 所以 28BYJ48 步进电机实际上是: 减速齿轮+步进电机组成, 28BYJ48 步进电机减速齿轮实物图如下所示:

屏幕截图 2024 06 07 104308

6. 硬件设计

本实验使用到硬件资源如下:

  • 步进电机驱动模块

  • 28BYJ-48 步进电机

该电路在前面直流电机实验中已介绍, 此处不再重复。

7. 软件设计

本章所要实现的功能是: 通过 ULN2003 驱动模块控制 28BYJ48 步进电机运行方向及速度, 当按下 KEY1 键可调节电机旋转方向; 当按下 KEY2 键, 电机加速;当按下KEY3键,电机减速

#include <REGX52.H>

//定义ULN2003控制步进电机管脚
sbit IN1_A = P1^0;
sbit IN2_B = P1^1;
sbit IN3_C = P1^2;
sbit IN4_D = P1^3;

//定义独立按键控制脚
sbit KEY1 = P3^1;
sbit KEY2 = P3^0;
sbit KEY3 = P3^2;
sbit KEY4 = P3^3;

//使用宏定义独立按键按下的键值
#define KEY1_PRESS    1
#define KEY2_PRESS    2
#define KEY3_PRESS    3
#define KEY4_PRESS    4
#define KEY_UNPRESS   0

// 定义步进电机速度,值越小,速度越快(1~5)
#define STEPMOTOR_MAXSPEED    1  
#define STEPMOTOR_MINSPEED    5      

void delay_10us(unsigned int ten_us)
{
    while(ten_us--);    
}

void delay_ms(unsigned int ms)
{
    unsigned int i,j;
    for(i=ms;i>0;i--)
        for(j=110;j>0;j--);
}

// 发送脉冲函数
void motor_28BYJ48_send(unsigned char step, unsigned char dir)
{
    unsigned char temp = step; // 定义临时变量为步进序号

    if(dir == 0) // 如果为逆时针旋转
    {
        temp = 7 - step; // 调换节拍信号
    }

    switch(temp) // 8个节拍控制:A->AB->B->BC->C->CD->D->DA
    {
        case 0: 
            IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=0;
            break;
        case 1: 
            IN1_A=1;IN2_B=1;IN3_C=0;IN4_D=0;
            break;
        case 2: 
            IN1_A=0;IN2_B=1;IN3_C=0;IN4_D=0;
            break;
        case 3: 
            IN1_A=0;IN2_B=1;IN3_C=1;IN4_D=0;
            break;
        case 4: 
            IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=0;
            break;
        case 5: 
            IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=1;
            break;
        case 6: 
            IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=1;
            break;
        case 7: 
            IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=1;
            break;
        default: 
            IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=0;
            break; // 停止相序    
    }            
}

// 按键扫描函数
unsigned char key_scan(int mode)
{
    static int key = 1; // 静态变量

    if(mode)key = 1; // 连续扫描按键
    if(key == 1 && (KEY1 == 0 || KEY2 == 0 || KEY3 == 0|| KEY4 == 0)) // 代表任意按键按下
    {
        delay_10us(1000); // 消抖
        key = 0;
        if(KEY1 == 0) // 代表按键1按下
            return KEY1_PRESS;
        else if(KEY2 == 0) // 代表按键1按下
            return KEY2_PRESS;
        else if(KEY3 == 0) // 代表按键3按下
            return KEY3_PRESS;
        else if(KEY4 == 0) // 代表按键4按下
            return KEY4_PRESS;    
    }
    else if(KEY1 == 1 && KEY2 == 1 && KEY3 == 1 && KEY4 == 1) // 代表无按键按下
    {
        key = 1;            
    }
    return KEY_UNPRESS;        
}

void main()
{    
    int key = 0;
    int dir = 0; // 默认逆时针方向
    int speed = STEPMOTOR_MAXSPEED; // 默认最大速度旋转
    int step = 0;

    while(1)
    {            
        key = key_scan(0);
        if(key == KEY1_PRESS) // 换向
        {
            dir = !dir; // 方向反转    
        }
        else if(key == KEY2_PRESS) // 加速
        {
            if(speed>STEPMOTOR_MAXSPEED) // 如果速度不为最大速度,加速
                speed -= 1;            
        }
        else if(key == KEY3_PRESS)//减速
        {
            if(speed < STEPMOTOR_MINSPEED) // 如果速度不为最小速度,减速
                speed +=1;            
        }
        motor_28BYJ48_send(step++, dir);
        if(step == 8)
        {
            step = 0;    
        }    
        delay_ms(speed);                        
    }        
}

8. 小结

关于步进电机我们其实不必了解那么细致,我们只需要会驱动它工作就行咯,下面详细解释一下代码,相信你就能学会了:

8.1 脉冲函数

  1. 参数说明
  • step: 表示步进电机的步进序号,取值范围是0到7。每个步进序号对应步进电机转动的一种状态。
  • dir: 表示步进电机的转动方向,通常用 0 和 1 表示不同的方向。
  1. 步进电机控制
  • 函数使用了一个 switch 语句根据 step 的值设置四个控制引脚 IN1_AIN2_BIN3_CIN4_D 的状态,以控制步进电机 ULN2003 驱动模块的输入信号。每个 case 分支对应于步进电机的一个步进状态,具体如下:
    • step = 0 到 step = 7 分别设置不同的引脚状态,通过改变这些状态,可以控制步进电机的每一步转动。
    • default 分支用于在超出范围时设置所有引脚为低电平,以确保安全。
  1. 延时控制
  • 使用 for 循环和 delay_10us 函数来控制每个步进状态的时间长度。具体的延时时间由 STEPMOTOR_MAXSPEED 和 STEPMOTOR_MINSPEED 宏定义决定,这些宏定义在主程序中设置步进电机的最大速度和最小速度。

这个函数的核心功能是根据输入的步进序号和方向,通过控制四个引脚的电平状态,向步进电机发送脉冲信号,从而实现步进电机的精确控制。

8.2 按键扫描函数

参数:

  • mode: 整型参数,用于指示是否进行连续扫描。如果 mode 非零,则进行连续扫描;否则只进行一次按键检测。

静态变量:

  • static int key = 1;: 使用静态变量 key 来记录当前的按键状态,初始值为 1。静态变量的作用是保留其数值,在函数调用之间保持持久性。

按键检测流程:

  1. 连续扫描模式处理: 如果 mode 参数为真(非零),则重置 key 变量为 1,表示将进行连续的按键扫描。

  2. 按键检测:

  • 如果 key 等于 1,并且任意一个按键(KEY1KEY2KEY3KEY4)被按下(输入为低电平),则执行以下操作:
    • 调用 delay_10us(1000); 函数进行按键消抖(即延时一段时间以确保稳定的按键状态)。
    • 将 key 设为 0,表示已经检测到按键按下。
    • 根据每个按键的状态,分别返回预定义的按键值:
      • 如果 KEY1 为低电平,则返回 KEY1_PRESS
      • 如果 KEY2 为低电平,则返回 KEY2_PRESS
      • 如果 KEY3 为低电平,则返回 KEY3_PRESS
      • 如果 KEY4 为低电平,则返回 KEY4_PRESS
  1. 无按键按下时处理: 如果所有按键(KEY1KEY2KEY3KEY4)均为高电平(未按下状态),则执行以下操作:
  • 将 key 设为 1,表示所有按键均未按下。
  1. 返回值: 如果在上述检测中未发现按键按下,则返回 KEY_UNPRESS 表示无按键按下状态。

该函数实现了对硬件上四个按键(KEY1KEY4)的状态监测,并在检测到按键按下时返回相应的按键按下状态,同时通过延时消抖处理按键的机械弹跳问题。

8.3 主函数

while(1)
{
    key = key_scan(0); // 调用按键扫描函数,返回当前按键状态给 key 变量

    if(key == KEY1_PRESS) // 如果检测到 KEY1 按下
    {
        dir = !dir; // 切换方向,通过对 dir 变量取反实现
    }
    else if(key == KEY2_PRESS) // 如果检测到 KEY2 按下
    {
        // 加速操作
        // 若速度已经最大,此时加速会导致速度减1
        if(speed > STEPMOTOR_MAXSPEED)
            speed -= 1;
    }
    else if(key == KEY3_PRESS) // 如果检测到 KEY3 按下
    {
        // 减速操作
        // 若速度已经最小,此时减速会导致速度加1
        if(speed < STEPMOTOR_MINSPEED)
            speed += 1;
    }

    // 控制步进电机的运动
    motor_28BYJ48_send(step++, dir); // 发送步进信号,同时 step 自增,控制电机步进位置
    if(step == 8)
    {
        step = 0; // 当步进到最后一步(8步)时,重置 step 为 0,形成循环步进
    }

    delay_ms(speed); // 根据当前速度延时,控制电机运行速度
}

2024.6.27 第一次修订

2024.7.20 第二次修订

2024.8.20 第三次修订,后期不再维护

本文作者:hazy1k

本文链接:https://www.cnblogs.com/hazy1k/p/18368788

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   hazy1k  阅读(50)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起