第14章 步进电机实验
第十四章 步进电机实验
1. 导入
前面章节, 我们介绍了直流电机的控制, 本章将向大家介绍步进电机, 步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。 本章主要从步进电机的结构、 工作原理、 电机参数分别介绍, 最后通过实验来实现步进电机运动的简单控制。 本章所要实现的功能是: 通过 ULN2003 驱动模块控制 28BYJ48 步进电机运行方向及速度, 当按下 KEY1 键可调节电机旋转方向; 当按下 KEY2 键, 电机加速; 当按下 KEY3 键, 电机减速。
2. 步进电机简介
步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。 在非超载的情况下, 电机的转速、 停止的位置只取决于脉冲信号的频率和脉冲数, 而不受负载变化的影响, 即给电机加一个脉冲信号, 电机则转过一个步距角。
这一线性关系的存在, 加上步进电机只有周期性的误差而无累计误差等特点。 使得在速度、位置等控制领域用步进电机来控制变的非常的简单。 虽然步进电机已被广泛的应用, 但步进电机并不能像普通的直流电机, 交流电机在常规下使用。 它必须由双环形脉冲信号、 功率驱动电路等组成控制系统方可使用。
和其他芯片一样,我们只要会用就行,至于什么结构,将来专业课会介绍步进电机_百度百科 (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,实物图及内部结构如下:
28BYJ48 步进电机旋转驱动方式如下表:
28BYJ48 步进电机主要参数如下所示:
在上图中 28BYJ48 步进电机主要参数中可以看到有一个减速比: 1:64, 步进角为 5.625/64 度, 如果需要转动一圈, 那么需要 360/5.625*64=4096 个脉冲信号
减速比这个和之前介绍的直流减速电机有点类似, 所以 28BYJ48 步进电机实际上是: 减速齿轮+步进电机组成, 28BYJ48 步进电机减速齿轮实物图如下所示:
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 脉冲函数
- 参数说明
step
: 表示步进电机的步进序号,取值范围是0到7。每个步进序号对应步进电机转动的一种状态。dir
: 表示步进电机的转动方向,通常用 0 和 1 表示不同的方向。
- 步进电机控制
- 函数使用了一个
switch
语句根据step
的值设置四个控制引脚IN1_A
、IN2_B
、IN3_C
、IN4_D
的状态,以控制步进电机 ULN2003 驱动模块的输入信号。每个case
分支对应于步进电机的一个步进状态,具体如下:step = 0
到step = 7
分别设置不同的引脚状态,通过改变这些状态,可以控制步进电机的每一步转动。default
分支用于在超出范围时设置所有引脚为低电平,以确保安全。
- 延时控制
- 使用
for
循环和delay_10us
函数来控制每个步进状态的时间长度。具体的延时时间由STEPMOTOR_MAXSPEED
和STEPMOTOR_MINSPEED
宏定义决定,这些宏定义在主程序中设置步进电机的最大速度和最小速度。
这个函数的核心功能是根据输入的步进序号和方向,通过控制四个引脚的电平状态,向步进电机发送脉冲信号,从而实现步进电机的精确控制。
8.2 按键扫描函数
参数:
mode
: 整型参数,用于指示是否进行连续扫描。如果mode
非零,则进行连续扫描;否则只进行一次按键检测。
静态变量:
static int key = 1;
: 使用静态变量key
来记录当前的按键状态,初始值为 1。静态变量的作用是保留其数值,在函数调用之间保持持久性。
按键检测流程:
-
连续扫描模式处理: 如果
mode
参数为真(非零),则重置key
变量为 1,表示将进行连续的按键扫描。 -
按键检测:
- 如果
key
等于 1,并且任意一个按键(KEY1
、KEY2
、KEY3
、KEY4
)被按下(输入为低电平),则执行以下操作:- 调用
delay_10us(1000);
函数进行按键消抖(即延时一段时间以确保稳定的按键状态)。 - 将
key
设为 0,表示已经检测到按键按下。 - 根据每个按键的状态,分别返回预定义的按键值:
- 如果
KEY1
为低电平,则返回KEY1_PRESS
。 - 如果
KEY2
为低电平,则返回KEY2_PRESS
。 - 如果
KEY3
为低电平,则返回KEY3_PRESS
。 - 如果
KEY4
为低电平,则返回KEY4_PRESS
。
- 如果
- 调用
- 无按键按下时处理: 如果所有按键(
KEY1
、KEY2
、KEY3
、KEY4
)均为高电平(未按下状态),则执行以下操作:
- 将
key
设为 1,表示所有按键均未按下。
- 返回值: 如果在上述检测中未发现按键按下,则返回
KEY_UNPRESS
表示无按键按下状态。
该函数实现了对硬件上四个按键(KEY1
到 KEY4
)的状态监测,并在检测到按键按下时返回相应的按键按下状态,同时通过延时消抖处理按键的机械弹跳问题。
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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步