51单片机电机控制模拟(5)步进电机

步进电机可用于微控制器项目的各个领域,例如制作机器人、机械臂、自动门锁系统等。本文将向您解释步进电机(单极和双极步进电机)的构造、基本原理、不同的控制类型(半步和全步)、接口技术(使用 L293D 或 ULN2003)以及使用 C 语言对微控制器进行编程以控制步进电机。步进电机类型市场上有两种基本类型的步进电机。

单极步进电机(Unipolar stepper motor)

单极步进电机有五或六根电线和四个线圈(实际上是两个线圈,每个线圈由中心连接分割为两部分)。线圈的中心连接连接在一起并用作电源连接。它们被称为单极步进电机,因为电源总是从一个极进入。

Image
Image

双极步进电机(Bipolar stepper motor)

双极步进电机通常有四根电线。与单极步进电机不同,双极步进电机没有公共中心连接。它们有两组独立的线圈。您可以通过测量电线之间的电阻来区分它们与单极步进电机。您应该找到两对具有相同电阻的电线。如果您将仪表的引线连接到两根未连接的电线(即未连接到同一线圈),您应该看到无穷大电阻(或无连续性)。

Image
Image

正如前面所说的,我们将主要讨论“单极步进电机”,这是市场上最常见的步进电机类型。下面给出了一个 6 引线步进电机的简单示例,在 5 引线步进电机中,第5 根和第 6 根线连接在一起形成 1 根公共线。

Image

步进电机的工作原理

现在让我们讨论一下步进电机的工作原理。当我们给步进电机的线圈通电时,步进电机的轴(实际上是一个永磁体)会根据通电线圈的极点自行对齐。因此,当电机线圈以特定顺序通电时,电机轴会根据线圈的极点自行对齐,从而旋转。下面给出了通电操作的一个小例子。

Image

您可以在示例中看到,当线圈“A”通电时,如上图所示,在“A+A\”处会产生南北极性,磁轴会根据产生的极性自动对齐。当下一个线圈通电时,轴会再次对齐并迈出一步。这就是工作原理。

Image

我们已经看到,要使步进电机工作,我们需要按顺序给线圈通电。

步进序列

步进电机可以以两种不同的模式或序列驱动。即

  • 全步进序列(Full Step Sequence)
  • 半步进序列(Half Step Sequence)

我们将逐一介绍这些序列。

全步进序列

在全步进序列中,两个线圈同时通电,电机轴旋转。下表给出了线圈通电的顺序。

Full Mode Sequence
StepABA\B\
01100
10110
20011
31001

下面的动画图给出了完整模式序列的工作原理。

Image

半步进序列

在半模式步进序列中,电机步进角减小到全模式的一半。因此,角度分辨率也增加了,即,它变为全模式角度分辨率的两倍。此外,在半模式序列中,步数是全模式的两倍。半模式通常比全模式更受欢迎。下表显示了线圈通电的模式。

Half Mode Sequence
StepABA\B\
01100
10100
20110
30010
40011
50001
61001
71000

下面的动画图给出了半模式序列的工作原理。

Image

步进角

步进电机的步进角定义为电机每走一步所经过的角度。要计算步进角,只需用 360 除以电机完成一圈所需的步数。正如我们所见,在半模式下,电机完成一圈所需的步数加倍,因此步进角减小到一半。

如上例所示,步进电机在全模式下旋转需要 4 步才能完成一圈,因此步进角可以计算为…

步进角 ø = 360° / 4 = 90°

在半模式下,步进角减半,即 45°。

因此,我们可以通过这种方式计算任何步进电机的步进角。通常,步进角在您使用的步进电机的规格表中给出。了解步进电机的步进角有助于您校准电机的旋转,也有助于您将电机移动到正确的角度位置。

双极步进电机的步进顺序

双极电机的结构更简单。它有两个绕组,没有中心抽头,中心有一个永磁体,就像单极步进电机一样。由于结构更简单,步进顺序有点复杂,因为两个线圈的功率必须以这样一种方式控制,即两极的极性反转。下表显示了此极性顺序。

Polarity Sequence
StepAA\BB\
0+ve-ve-ve-ve
1-ve-ve+ve-ve
2-ve+ve-ve-ve
3-ve-ve-ve+ve

通过一次激活一个线圈,可以根据微控制器的逻辑电平来解释上述极性序列,如下表所示。

Step Sequence
StepAA\BB\
01000
10010
20100
30001

步进电机连接

连接单极步进电机

实际上,将步进电机连接到控制器的方法有很多,其中最常用的接口是:

使用 L293D – H 桥电机驱动器的接口

使用 ULN2003/2004 – 达林顿(Darlington)阵列的接口

我们将逐一讨论这两种连接技术。上述方法需要 4 个控制器引脚进行接口。

使用 L293D 连接单极步进机

Image

正如您在上面的电路中看到的,四个引脚“控制器引脚 1”、2、3 和 4 将根据控制器中编程的步进顺序控制步进电机的运动和方向。

使用 ULN2003/2004 连接单极步进机

Image

正如在 L293D 的情况下已经讨论过的,在这个电路中,四个引脚“控制器引脚 1”、2、3 和 4 也将根据控制器发送的步进顺序控制步进电机的运动和方向。

连接双极步进电机

正如我们所研究的,双极步进电机有 2 个不同的线圈。双极步进电机的步进顺序与单极步进电机相同。该电机的驱动电路需要一个 H 桥,因为它允许独立控制所施加电源的极性。这可以按照下图所示完成:

Image

步进电机编程

单极电机全步序列编程

#include <reg51.H>
#define stepper P2
 
void delay()
{
	unsigned char i,j,k;
	for(i=0;i<6;i++) {
		for(j=0;j<255;j++)
			for(k=0;k<255;k++);
	}
}
 
void main()
{
	while (1) {
		stepper = 0x0C;
		delay();
		stepper = 0x06;
		delay();
		stepper = 0x03;
		delay();
		stepper = 0x09;
		delay();
	}
}

Proteus演示结果(以ULN2003芯片为例),电机步进角设为90°。

Image

单极电机半步序列编程

#include <reg51.h>
#include <stdio.h>
#define stepper P2

void delay()
{
	unsigned char i,j,k;
	for(i=0;i<6;i++) {
		for(j=0;j<255;j++)
			for(k=0;k<255;k++);
	}
}

void main()
{
	while (1) {
		stepper = 0x08;
		delay();
		stepper = 0x0C;
		delay();
		stepper = 0x04;
		delay();
		stepper = 0x06;
		delay();
		stepper = 0x02;
		delay();
		stepper = 0x03;
		delay();
		stepper = 0x01;
		delay();
		stepper = 0x09;
		delay();
	}
}

Proteus演示结果

Image

双极步进电机编程

#include <reg51.h>
#include <stdio.h>
#define stepper P2

void delay()
{
	unsigned char i,j,k;
	for(i=0;i<6;i++) {
		for(j=0;j<255;j++)
			for(k=0;k<255;k++);
	}
}

void main()
{
	while (1) {
		stepper = 0x08;
		delay();
		stepper = 0x02;
		delay();
		stepper = 0x04;
		delay();
		stepper = 0x01;
		delay();
	}
}

Proteus演示结果(以L293D芯片为例),电机步进角设为90°。

Image

将电机的步进角改为1.8°,以下代码可实现步进电机正反转180°。

#include <reg51.h>
// Define motor control port
#define stepper P2  // Connect motor driver inputs to Port 2
// Delay function (1ms delay approximation for a 12 MHz crystal)
void delay(unsigned int time) {
    unsigned int i, j;
    for (i = 0; i < time; i++) {
        for (j = 0; j < 250; j++);  // Adjusted for 12 MHz clock
    }
}
// Function to rotate the stepper motor in full-step mode
void stepper_full_step(int steps, int direction) {
    int i, step;
    for (step = 0; step < steps; step++) {
        if (direction == 0) {  // Forward rotation
            stepper = 0x08;  // IN1 and IN4 ON (binary: 1001)
            delay(30);
            stepper = 0x02;  // IN1 and IN2 ON (binary: 0011)
            delay(30);
            stepper = 0x04;  // IN2 and IN3 ON (binary: 0110)
            delay(30);
            stepper = 0x01;  // IN3 and IN4 ON (binary: 1100)
            delay(30);
        } else {  // Reverse rotation
            stepper = 0x01;  // IN3 and IN4 ON (binary: 1100)
            delay(30);
            stepper = 0x04;  // IN2 and IN3 ON (binary: 0110)
            delay(30);
            stepper = 0x02;  // IN1 and IN2 ON (binary: 0011)
            delay(30);
            stepper = 0x08;  // IN1 and IN4 ON (binary: 1001)
            delay(30);
        }
    }
}
void main() {
    while (1) {
        stepper_full_step(25, 0);  // Rotate 180° forward
        delay(1000);               // 1-second delay
        stepper_full_step(25, 1);  // Rotate 180° backward
        delay(1000);               // 1-second delay
    }
}