步进电机的使用

一、步进电机介绍

01**、步进电机基本概念**

  • 步进电机是将电脉冲信号转换为角位移****/****线位移开环控制元件
  • 非超载时,转速与停止位置仅由脉冲频率、脉冲数决定,不受负载影响
  • 每输入一个脉冲,电机转过一个固定步距角,无累积误差,控制简单。
  • 必须搭配脉冲信号****+****功率驱动电路使用,涉及机械、电机、电子、计算机多领域知识。

02**、步进电机分类**

  • 永磁式**:二相为主,转矩与体积小**,步距角 7.5°/15°。
  • **反应式:**三相为主,转矩大,步距角 1.5°;噪声与振动大,已基本淘汰。
  • **混合式:**结合永磁式与反应式优点,分二相、五相,应用最广泛。

03 步进电机的****主要技术指标

1)相数

内部线圈组数。常用二****///**五相;相数不同步距角不同,二相电机的步距角为 0.9°/1.8° ,三相为 0.75° /1.5° 、五相为 0.36° /0.72° 。使用细分驱动器**后,可通过细分数调整步距角,相数不再起决定作用。

2)步距角

每输入一个脉冲电机转过的角度。固有步距角与实际工作步距角,实际值受驱动器影响。

3)拍数

完成一个磁场周期变化所需的脉冲数;四相电机常见四拍、八拍两种运行方式。

4)保持转矩

电机通电不转时的锁定力矩,是步进电机最核心参数;低速力矩接近保持转矩,高速时输出力矩与功率会明显衰减。

二、步进电机工作原理

01****步进电机基本特性

  • 步进电机是将电脉冲转换为角位移****/****线位移的电磁机械装置。
  • 具备快速启停特性,电机的负荷不超动态转矩时,可通过脉冲瞬间启动或停止。
  • 步距角、转速仅由输入脉冲频率决定,不受温度、气压、振动、电网电压及负载波动影响,适合精确定位场景。

02****核心工作原理

  • 常见接线:三线、四线、五线、六线,控制逻辑一致,均由脉冲信号驱动。
  • 旋转角度与脉冲个数成正比,每发一个脉冲,电机转动固定角度。
  • 转向由励磁脉冲顺序控制,正序正转、逆序反转。

步进电机组成最主要的就是转子定子部分。

定子:步进电机中固定不动的部分,是电机的磁场与线圈载体。

转子:步进电机中可以旋转的部分,是输出角位移 / 线位移的执行部件。

步进电机的电流流过定子产生磁场的过程叫做励磁

下面是以2相4线的步进电机举例:

二相步进电机,电机转子的旋转,是由不同磁极的磁场相斥和相吸实现的。如右图所示,A相产生N极磁场吸引转子的S极,B相产生S极磁场吸引转子的N极,使转子产生旋转的动力。如果**改变AB相定子线圈的电流方向,电机会产生另一步的旋转。**连续改变A、B相定子线圈的电流方向,电机会产生连续的旋转。

03****励磁方式

**一相励磁:**瞬间仅 1****个线圈导通,每步转动 1.8°

**特点:**结构简单、精度好、功耗小,但转矩小、振动大。

**二相励磁:**瞬间 2****个线圈同时导通,每步转动 1.8°

**特点:**转矩大、振动小,目前应用最广泛

**一二相励磁(半步励磁):**一相与二相交替导通,每步转动 0.9°

**特点:**分辨率高、运转平滑,适用场景广泛。

三、步进电机实验原理

本次实验是使用普中TMS320F28335单片机。

01 ULN2003 芯片介绍

ULN2003 是一个单片高电压、高电流的达林顿晶体管阵列集成电路。

1)主要特点

①500mA 额定集电极电流(单个输出)

②高电压输出:50V

③输入和各种逻辑类型兼容

④继电器驱动器

2)逻辑框图

从上图可以很容易理解该芯片的使用方法,其内部实际上就相当于非门电路,即输入高输出为低,输入低输出高

(3)封装

02 硬件电路设计

从原理图可知,ULN2003 与 TC1508S 输入管脚兼容,二者步进电机 IO 口定义一致。

**区别在于:**ULN2003 可以驱动4相5线的步进电机(也可以驱动2相4线的电机),TC1508S 可以驱动2相4线步进电机。

03 接线

使用仿真器将开发板和电脑连接成功后,把编写好的程序编译后,如果没有 报错即可将点击仿真调试,程序即会写入到芯片的RAM内。将四线双极性步进电 机正确接入到直流电机模块的J2输出端子的上,电机与开发板接口管脚连接如 下:

电机A- ---> OA

电机A+ ---> OB

电机B- ---> OC

电机B+ ---> OD

如下图所示:

上图是使用TC1508S 驱动步进电机

上图: 如果使用的是五线四相步进电机就使用ULN2003,即可将其接入到步进电机模块接口M1上, 板上接口是防呆的所以也不会出现插反问题。

四、步进电机程序

注意:下面程序是使用TC1508S 驱动步进电机的。

(1)key.h

cpp 复制代码
/*
 * key.h
 *
 *  Created on: 2018-1-22
 *      Author: Administrator
 *  功能说明:F28335矩阵按键驱动头文件,包含引脚定义、宏定义、函数声明
 */

#ifndef KEY_H_
#define KEY_H_

// 包含F28335官方底层寄存器定义头文件
#include "DSP2833x_Device.h"
// 包含F28335工程示例通用头文件
#include "DSP2833x_Examples.h"

//======================== 按键行引脚(输出控制)定义 ========================
// 行1:GPIO48 输出低电平
#define KEY_L1_SetL			(GpioDataRegs.GPBCLEAR.bit.GPIO48=1)
// 行2:GPIO49 输出低电平
#define KEY_L2_SetL			(GpioDataRegs.GPBCLEAR.bit.GPIO49=1)
// 行3:GPIO50 输出低电平
#define KEY_L3_SetL			(GpioDataRegs.GPBCLEAR.bit.GPIO50=1)

// 行1:GPIO48 输出高电平
#define KEY_L1_SetH			(GpioDataRegs.GPBSET.bit.GPIO48=1)
// 行2:GPIO49 输出高电平
#define KEY_L2_SetH			(GpioDataRegs.GPBSET.bit.GPIO49=1)
// 行3:GPIO50 输出高电平
#define KEY_L3_SetH			(GpioDataRegs.GPBSET.bit.GPIO50=1)

//======================== 按键列引脚(输入检测)定义 ========================
// 列1:读取GPIO12引脚电平
#define KEY_H1			(GpioDataRegs.GPADAT.bit.GPIO12)
// 列2:读取GPIO13引脚电平
#define KEY_H2			(GpioDataRegs.GPADAT.bit.GPIO13)
// 列3:读取GPIO14引脚电平
#define KEY_H3			(GpioDataRegs.GPADAT.bit.GPIO14)

//======================== 按键返回值宏定义 ========================
// 按键1按下返回值
#define KEY1_PRESS		1
// 按键2按下返回值
#define KEY2_PRESS		2
// 按键3按下返回值
#define KEY3_PRESS		3
// 按键4按下返回值
#define KEY4_PRESS		4
// 按键5按下返回值
#define KEY5_PRESS		5
// 按键6按下返回值
#define KEY6_PRESS		6
// 按键7按下返回值
#define KEY7_PRESS		7
// 按键8按下返回值
#define KEY8_PRESS		8
// 按键9按下返回值
#define KEY9_PRESS		9
// 无按键按下返回值
#define KEY_UNPRESS		0

//======================== 函数声明 ========================
// 按键初始化函数:配置行列引脚的输入/输出模式
void KEY_Init(void);

// 按键扫描函数
// mode:扫描模式(0=连续扫描,1=单次扫描/松手检测)
// 返回值:按键编号(1-9)或 0(无按键)
char KEY_Scan(char mode);

#endif /* KEY_H_ */

(2)key.c

cpp 复制代码
/*
 * key.c
 *  功能:TMS320F28335 3×3矩阵按键驱动实现文件
 *  驱动方式:行输出扫描 + 列输入检测,支持按键消抖、单次/连续扫描
 *  Created on: 2018-1-22
 *      Author: Administrator
 */

#include "key.h"

/**********************************************************
 * 函数名:KEY_Init
 * 功能  :矩阵按键GPIO初始化
 * 入口  :无
 * 返回  :无
 * 说明  :配置列引脚为上拉输入,行引脚为推挽输出,初始输出高电平
 **********************************************************/
void KEY_Init(void)
{
    // 开启受保护的寄存器写使能
    EALLOW;

    // 开启GPIO时钟,必须先开时钟才能操作GPIO
    SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;

    //==================== 列引脚配置(输入检测)GPIO12/13/14 ====================
    // GPIO12 配置为普通GPIO功能
    GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;
    // GPIO12 配置为输入模式
    GpioCtrlRegs.GPADIR.bit.GPIO12=0;
    // GPIO12 使能内部上拉电阻(按键未按下时保持高电平)
    GpioCtrlRegs.GPAPUD.bit.GPIO12=0;

    // GPIO13 配置为普通GPIO、输入、上拉使能
    GpioCtrlRegs.GPAMUX1.bit.GPIO13=0;
    GpioCtrlRegs.GPADIR.bit.GPIO13=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO13=0;

    // GPIO14 配置为普通GPIO、输入、上拉使能
    GpioCtrlRegs.GPAMUX1.bit.GPIO14=0;
    GpioCtrlRegs.GPADIR.bit.GPIO14=0;
    GpioCtrlRegs.GPAPUD.bit.GPIO14=0;

    //==================== 行引脚配置(输出扫描)GPIO48/49/50 ====================
    // GPIO48 配置为普通GPIO功能
    GpioCtrlRegs.GPBMUX2.bit.GPIO48=0;
    // GPIO48 配置为输出模式
    GpioCtrlRegs.GPBDIR.bit.GPIO48=1;
    // GPIO48 使能内部上拉电阻
    GpioCtrlRegs.GPBPUD.bit.GPIO48=0;

    // GPIO49 配置为普通GPIO、输出、上拉使能
    GpioCtrlRegs.GPBMUX2.bit.GPIO49=0;
    GpioCtrlRegs.GPBDIR.bit.GPIO49=1;
    GpioCtrlRegs.GPBPUD.bit.GPIO49=0;

    // GPIO50 配置为普通GPIO、输出、上拉使能
    GpioCtrlRegs.GPBMUX2.bit.GPIO50=0;
    GpioCtrlRegs.GPBDIR.bit.GPIO50=1;
    GpioCtrlRegs.GPBPUD.bit.GPIO50=0;

    // 关闭受保护的寄存器写使能
    EDIS;

    // 行引脚初始状态:全部输出高电平(无按键按下)
    GpioDataRegs.GPBSET.bit.GPIO48=1;
    GpioDataRegs.GPBSET.bit.GPIO49=1;
    GpioDataRegs.GPBSET.bit.GPIO50=1;
}

/**********************************************************
 * 函数名:KEY_Scan
 * 功能  :3×3矩阵按键扫描函数
 * 入口  :mode - 扫描模式
 *         mode=0:连续扫描(按住不放持续返回键值)
 *         mode=1:单次扫描(按下只返回一次,松手后才能再次触发)
 * 返回  :按键值 1~9(对应KEY1~KEY9),0表示无按键按下
 **********************************************************/
char KEY_Scan(char mode)
{
    // 静态变量:记录3行按键的状态,用于松手检测(只在第一次按下时有效)
    static char keyl1=1;
    static char keyl2=1;
    static char keyl3=1;

    //======================== 第一行扫描:拉低L1,拉高L2/L3 ========================
    KEY_L1_SetL;	// 行1输出低电平
    KEY_L2_SetH;	// 行2输出高电平
    KEY_L3_SetH;	// 行3输出高电平

    // 判断:行1未被锁定 + 任意一列检测到低电平(按键按下)
    if(keyl1==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))
    {
        DELAY_US(10000);  // 软件消抖:延时10ms,避开按键抖动干扰
        keyl1=0;          // 锁定行1,防止重复触发

        // 判断具体是哪一列按键按下
        if(KEY_H1==0)
        {
            return KEY1_PRESS;	// 第一行第一列:KEY1
        }
        else if(KEY_H2==0)
        {
            return KEY4_PRESS;	// 第一行第二列:KEY4
        }
        else if(KEY_H3==0)
        {
            return KEY7_PRESS;	// 第一行第三列:KEY7
        }
    }
    // 所有列都为高电平 → 按键松开 → 解除行1锁定
    else if(KEY_H1==1&&KEY_H2==1&&KEY_H3==1)
    {
        keyl1=1;
    }
    // 单次扫描模式:强制解锁,确保按下只返回一次
    if(mode)
        keyl1=1;

    //======================== 第二行扫描:拉低L2,拉高L1/L3 ========================
    KEY_L2_SetL;
    KEY_L1_SetH;
    KEY_L3_SetH;
    if(keyl2==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))
    {
        DELAY_US(10000);
        keyl2=0;
        if(KEY_H1==0)
        {
            return KEY2_PRESS;	// 第二行第一列:KEY2
        }
        else if(KEY_H2==0)
        {
            return KEY5_PRESS;	// 第二行第二列:KEY5
        }
        else if(KEY_H3==0)
        {
            return KEY8_PRESS;	// 第二行第三列:KEY8
        }
    }
    else if(KEY_H1==1&&KEY_H2==1&&KEY_H3==1)
    {
        keyl2=1;
    }
    if(mode)
        keyl2=1;

    //======================== 第三行扫描:拉低L3,拉高L1/L2 ========================
    KEY_L3_SetL;
    KEY_L1_SetH;
    KEY_L2_SetH;
    if(keyl3==1&&(KEY_H1==0||KEY_H2==0||KEY_H3==0))
    {
        DELAY_US(10000);
        keyl3=0;
        if(KEY_H1==0)
        {
            return KEY3_PRESS;	// 第三行第一列:KEY3
        }
        else if(KEY_H2==0)
        {
            return KEY6_PRESS;	// 第三行第二列:KEY6
        }
        else if(KEY_H3==0)
        {
            return KEY9_PRESS;	// 第三行第三列:KEY9
        }
    }
    else if(KEY_H1==1&&KEY_H2==1&&KEY_H3==1)
    {
        keyl3=1;
    }
    if(mode)
        keyl3=1;

    // 无任何按键按下
    return KEY_UNPRESS;
}

(3)step_motor.c

cpp 复制代码
/*
 * step_motor.c
 *
 *  Created on: 2018-1-23
 *      Author: Administrator
 *  功能说明:TMS320F28335 步进电机驱动源文件
 *           实现步进电机控制GPIO初始化
 */

#include "step_motor.h"

/**********************************************************
 * 函数名:Step_Motor_Init
 * 功能  :步进电机控制引脚初始化
 * 入口  :无
 * 返回  :无
 * 说明  :配置GPIO2/3/4/5为通用推挽输出,初始输出低电平
 **********************************************************/
void Step_Motor_Init(void)
{
    // 开启受保护寄存器写使能(F28335操作关键寄存器必须加)
    EALLOW;

    // 开启GPIO时钟,必须先开启时钟才能正常操作GPIO引脚
    SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;

    //==================== 步进电机控制引脚配置 ====================
    // GPIO2 配置为普通GPIO功能(0=通用IO,1=外设功能)
    GpioCtrlRegs.GPAMUX1.bit.GPIO2=0;
    // GPIO2 配置为输出模式(0=输入,1=输出)
    GpioCtrlRegs.GPADIR.bit.GPIO2=1;

    // GPIO3 配置为普通GPIO、输出模式
    GpioCtrlRegs.GPAMUX1.bit.GPIO3=0;
    GpioCtrlRegs.GPADIR.bit.GPIO3=1;

    // GPIO4 配置为普通GPIO、输出模式
    GpioCtrlRegs.GPAMUX1.bit.GPIO4=0;
    GpioCtrlRegs.GPADIR.bit.GPIO4=1;

    // GPIO5 配置为普通GPIO、输出模式
    GpioCtrlRegs.GPAMUX1.bit.GPIO5=0;
    GpioCtrlRegs.GPADIR.bit.GPIO5=1;

    // 关闭受保护寄存器写使能
    EDIS;

    //==================== 引脚初始电平设置 ====================
    // GPIO2 输出低电平
    GpioDataRegs.GPACLEAR.bit.GPIO2=1;
    // GPIO3 输出低电平
    GpioDataRegs.GPACLEAR.bit.GPIO3=1;
    // GPIO4 输出低电平
    GpioDataRegs.GPACLEAR.bit.GPIO4=1;
    // GPIO5 输出低电平
    GpioDataRegs.GPACLEAR.bit.GPIO5=1;
}

(4)step_motor.h

cpp 复制代码
/*
 * step_motor.h
 *
 *  Created on: 2018-1-23
 *      Author: Administrator
 */

#ifndef STEP_MOTOR_H_
#define STEP_MOTOR_H_

#include "DSP2833x_Device.h"     // DSP2833x 头文件
#include "DSP2833x_Examples.h"   // DSP2833x 例子相关头文件

#define STEP_MOTOR_4LINE2
//#define STEP_MOTOR_5LINE4

// A相设置高电平
#define MOTO_OUTA_SETH	(GpioDataRegs.GPASET.bit.GPIO2=1)
#define MOTO_OUTA_SETL	(GpioDataRegs.GPACLEAR.bit.GPIO2=1)

#define MOTO_OUTB_SETH	(GpioDataRegs.GPASET.bit.GPIO3=1)
#define MOTO_OUTB_SETL	(GpioDataRegs.GPACLEAR.bit.GPIO3=1)

#define MOTO_OUTC_SETH	(GpioDataRegs.GPASET.bit.GPIO4=1)
#define MOTO_OUTC_SETL	(GpioDataRegs.GPACLEAR.bit.GPIO4=1)

#define MOTO_OUTD_SETH	(GpioDataRegs.GPASET.bit.GPIO5=1)
#define MOTO_OUTD_SETL	(GpioDataRegs.GPACLEAR.bit.GPIO5=1)

void Step_Motor_Init(void);


#endif /* STEP_MOTOR_H_ */

(5)main.c

cpp 复制代码
#include "DSP2833x_Device.h"
#include "DSP2833x_Examples.h"
#include "leds.h"
#include "key.h"
#include "step_motor.h"

// 这个是5线4相的电机步进表
//#ifdef STEP_MOTOR_5LINE4
//unsigned char Step_table_ZTurn[]={0xfff7,0xfffb,0xffdf,0xffef};
//unsigned char Step_table_FTurn[]={0xffef,0xffdf,0xfffb,0xfff7};
//#endif
// 4线2相的电机步进表
#ifdef STEP_MOTOR_4LINE2
// 电机正转
unsigned char Step_table_ZTurn[]={0xfff7,0xffdf,0xfffb,0xffef};
/**  0xfff7: 0111  A相线圈反向通电
     0xffdf: 1101  B相线圈反向通电
     0xfffb: 1011  A相线圈正向通电
     0xffef: 1110  B相线圈正向通电
             通电顺序是:磁场顺序:A 反 → B 反 → A 正 → B 正
**/
// 电机反转
unsigned char Step_table_FTurn[]={0xffef,0xfffb,0xffdf,0xfff7};
/**  0xffef: 1111 1111 1110 1111   GPIO4 = 0,    B相线圈正向通电
     0xfffb: 1111 1111 1111 1011   GPIO2 = 0,    A相线圈正向通电
     0xffdf: 1111 1111 1101 1111   GPIO5 = 0,    B相线圈反向通电
	 0xfff7: 1111 1111 1111 0111   GPIO3 = 0,    A相线圈反向通电
             通电顺序是:磁场顺序: B 正→ A 正 → B 反→ A 反
**/
#endif

// ===================== 调速参数 =====================
int speed_delay = 8000;
#define MIN_DELAY 3000
#define MAX_DELAY 10000

// 运行模式:0=停止 1=正转 2=反转
char run_mode = 0;
// =====================================================

void main()
{
    int i=0;
    char key=0;
    char j=0;

    InitSysCtrl();
    LED_Init();
    KEY_Init();
    Step_Motor_Init();

    while(1)
    {

        key = KEY_Scan(0);

        // ===================== 按键设置模式 =====================
        if(key == KEY1_PRESS) run_mode = 1;   // 一直正转
        if(key == KEY2_PRESS) run_mode = 2;   // 一直反转
        if(key == KEY5_PRESS) run_mode = 0;   // 立即停止

        // 调速
        if(key == KEY3_PRESS){
            speed_delay -= 1000;
            if(speed_delay < MIN_DELAY) speed_delay = MIN_DELAY;
        }
        if(key == KEY4_PRESS){
            speed_delay += 1000;
            if(speed_delay > MAX_DELAY) speed_delay = MAX_DELAY;
        }
        // =========================================================

        // ===================== 电机运行 =====================
        if(run_mode == 1) // 正转
        {
        // 将十六进制数值0xffef写入到 GPIOA 的数据寄存器,此数值经过设计,能直接设置 GPIO2/3/4/5 的高低电平,从而实现一个节拍的励磁状态。
            GpioDataRegs.GPADAT.all = Step_table_ZTurn[j];
            j = (j+1) % 4;
            DELAY_US(speed_delay);
        }
        else if(run_mode == 2) // 反转
        {
            GpioDataRegs.GPADAT.all = Step_table_FTurn[j];
            j = (j+1) % 4;
            DELAY_US(speed_delay);
        }
        else // 停止
        {
            GpioDataRegs.GPADAT.all = 0xFFFF; // 不给线圈通电,电机停止转动
        }
        // =====================================================

        if(i++%2000 == 0) LED1_TOGGLE;
    }
}

步进电机工作原理步进电机工作

相关推荐
三佛科技-1873661339721 小时前
国产替代新选择|替代STM32/APM32型号推荐(32位MCU)
stm32·单片机·嵌入式硬件
要不枉此行21 小时前
BLE 性能调优全攻略:MTU 配置、DLE 开启与干扰优化
单片机
llilian_161 天前
信号失真度测试仪 自动失真测试仪 低失真度自动测量仪为各行业精准赋能 自动失真仪
网络·功能测试·单片机·测试工具
jghhh011 天前
基于TMS320F28033的20MHz手持式双踪袖珍示波器设计与实现
stm32·嵌入式硬件·51单片机
zmj3203241 天前
KW45芯片的安全启动
单片机·嵌入式开发·安全启动
DA02211 天前
系统移植-STM32MP1_BusyBox移植
stm32·单片机·系统移植
殷忆枫1 天前
基于STM32F103C8T6的R60AFD1毫米波雷达模块驱动设计
stm32·单片机·嵌入式硬件
somi71 天前
ARM-12-I.MX6U LCD
arm开发·单片机·嵌入式硬件·自用
bubiyoushang8881 天前
基于STM32的心电采集系统设计
stm32·单片机·嵌入式硬件
笨笨饿1 天前
26_为什么工程上必须使用拉普拉斯变换
c语言·开发语言·人工智能·嵌入式硬件·机器学习·编辑器·概率论