介绍

步进电机是一种将电脉冲信号转换成相应角位移或线位移的电动机。每输入一个脉冲信号,转子就转动一个角度或前进一步,其输出的角位移或线位移与输入的脉冲数成正比,转速与脉冲频率成正比。因此,步进电动机又称脉冲电动机。在非超载且不超频的情况下,电机的旋转位置只取决于脉冲个数,转速只取决脉冲信号的频率。所以说步进电机它的开环能力非常优秀,目前也被广泛的应用于各种开环系统上。

步进电机通过控制脉冲频率可以控制电机转动的速度和加速度,从而达到调速的目的。控制方便,但想玩转也并非易事,在本章内容中主要涉及的是步进电机的驱动控制,其中包括:基础的旋转和换向控制,定位控制等。

步进电机的分类

一般我们可从其磁激励的方式进行区分,将步进电机区分为三大类:永磁式、反应式(磁阻式)、混合式步进电机。他们之间的区别如下:

  • 反应式:定子上有绕组、转子由软磁材料组成。结构简单、成本低、步距角小,可达 1.2°、但噪声和震动大,动态性能较低。

  • 永磁式:永磁式步进电机的转子用永磁材料制成,转子的极数与定子的极数相同。其特点是动态性能好、输出力矩大,但这种电机步矩角大(一般为 7.5°或 15°)。精度也就一般。

  • 混合式:混合式步进电机综合了反应式和永磁式的优点,其定子上有多相绕组、转子上采用永磁材料,转子和定子上均有多个小齿以提高步矩精度。其特点是输出力矩大、动态性能好,步距角小,但结构复杂、成本也相对较高,但这类步进电机的应用最为广泛,我们后面的教程也是主要以混合式的步进电机来讲解。

类别 优点 缺点
永磁式 动态性能好,输出力矩大 步距角过大(一般 7.5°或 15°),精度较差
磁阻式 结构简单,成本低,步距角小可达 1.2° 噪音和震动过大,动态性能较低
混合式 力矩大,动态性能好,步距角小,精度高 结构复杂,成本相对较高

以极性的方式作为区分,可分为:单极性步进电机双极性步进电机

左侧为单机性步进电机,右侧为双极性的步进电机,它们的区别就是电流的流向,单极性步进电机,特点是有一个公共端,电流的流向固定且只有一个方向;双极性步进电机的特点:电流流向是双向的,电机中有两个电流回路。单极性步进电机较双极性步进电机驱动起来较为简单,但是单极性的输出力矩较小。

工作原理

步进电机的核心部件主要有定子转子定子上的绕组

步进电机的工作原理就是控制定子绕组周期性、交替得电,使定子产生磁场,进而控制步进电机转子一步一步的运动起来。

单极性步进电机驱动

单极性整步驱动,图示中有 5 根线,分别是 A、B、C、D 以及公共端,公共端是一直通电的,ABCD 相是交替得电的。

单极性步进电机整步驱动

  • 第一:A 相通电,通过电磁原理,电生磁,然后通过磁力把转子吸引到 A 处;
  • 第二:A 相关闭,B 相通电,转子就会旋转 90°到 B 处;第三步 B 相关闭,C 相通电,转子会再次旋转 90°,到 C 处,接着第四步:C 相关闭,D 相通电,就会旋转到 D 处
  • 重复: 该顺序就可以以 90°的步距角顺时针旋转起来。这种属于单相激励步进,意思就是每步进一步都只受到了一个磁场的力,但是更为常见的是双相激励的方式,因为力矩相对会更大。

单极性的双相激励方式驱动

单极性的双相激励方式驱动。它的工作方式是同时两相一起通电,它与上一种驱动方式的区别是固定在两相中间位置,因为两相同时通入相同的电流此时磁力矢量在两相中间就会把转子吸引到两相的中间位置,还有一个区别就是这种方式它是受到了两个磁场的力所以他的输出力矩相对上一种会更大。接着我们看下它的通电顺序:AB—BC—CD—DA,重复该顺序就可以使电机顺时针旋转起来。像这种方式,相邻的线圈的角度为 90°,然后转子直接一步到位旋转 90°的方式称为整步驱动。

半步驱动的方式

半步驱动的方式:它每步步进的距离为 45°,我们来看下它的通电顺序:A—AB—B—BC—C—CD—D—DA,重复该步骤,电机就可以以 45°的步距角顺时针

旋转了,同理想要逆时针旋转的话就将通电顺序反过来即可。

双极性步进电机驱动原理

双极性与单极性类似,都可分为整步与半步驱动方式,不同的是,单极性的电流方向是单向的,而双极性的步进电机可以通过改变电流的方向来改变每相磁场的方向。

双极性的整步驱动

  • 双极性的整步驱动,它没有公共端,所以他的电流可以从 A+进去也可以从A-进去,B 相同理。我们看下它的通电顺序第一步:A 相通电,此时 A+方向接电源正极,A-接电源负极,那么此时根据电磁原理,产生磁场,异性相吸,就会将转子吸引到第一步的位置;接着第二步:A 相关闭,B 相通电(B+接正,B-接负),就会吸引转子旋转 90°;第三步:B 相关闭,A 相通电但是极性与第一步相反(A+接负,A-接正),此时就会吸引转子继续旋转 90°;第四步:A 相关闭,B 相通电,极性与第 2 步相反,重复该步骤就可以使其以 90°的步距角顺时针旋转了。

  • 这一种驱动方式属于单相激励。

双极性也有双相激励

双极性的双相激励驱动方式,力矩相较于单相会更大,它的通电顺序为:AB(A+B+接正)—AB(A-B+接正)—AB(A-B-接正)—AB(A+B-接正)重复该顺序即可顺时针旋转起来。

通电顺序

  • 第一:A 相通电(A+接正),B 相不通电;
  • 第二:AB 相通电(A+B+接正),通入相同电流,产生磁力相同;
  • 第三:B 相通电(B+接正),A 相不通电
  • 第四:AB 相通电(A-B+接正),通入相同电流,产生磁力相同;
  • 第五:A 相通电(A-接正),B 相不通电;
  • 第六:AB 相通电(A-B-接正),通入相同电流,产生磁力相同;
  • 第七:B 相通电(B-接正),A 相不通电
  • 第八:AB 相通电(A+B-接正)通入相同电流,产生磁力相同;

重复上面步骤就可以以 45°的步距角顺时针旋转,与整步相比半步的驱动方式旋转起来更加的顺滑。

细分驱动原理

  • 细分驱动,单双极步进电机都同理,所以不分单双极电机。在上图中均为双相激励;其中图(a)为 A 相电流很大,B 相的电流极其微弱,接近 0;图 (c)为 A 相和 B 相的电流相同,电流决定磁场,所以说 A 相和 B 相的磁场也是相同的。(a) 和(c)可以是极限特殊的情况,再看图(b)和图(d)这两个是由于 A 相和 B 相的电流不同产生位置情况;由此可以得出改变定子的电流比例就可以使得转子在任意角度停住
  • 所以细分的原理就是:通过改变定子的电流比例,进而控制转子在一个整步中的不同位置,即可以将一个整步分成多个小步来运行。在上图中就是一个整步分成了 4 步来跑,从(a)~(d)是 A 相的电流逐渐减小,B 相电流逐渐增大的过程,如果驱动器的细分能力很强,可以将其分成 32 细分、64 细分等;这不仅提高了步进电机旋转的顺畅度而且提高了每步的精度。

指标参数

静态参数

  • 相数:产生不同对极 N、S 磁场的激磁线圈对数,也可以理解为步进电机中线圈的组数,其中两相步进电机步距角为 1.8°,三相的步进电机步距角为 1.5°,相数越多的步进电机,其步距角就越小。
  • 拍数:完成一个磁场周期性变化所需脉冲数或导电状态用 n 表示,或指电机转过一个齿距角所需脉冲数,以四相电机为例,有四相四拍运行方式即 AB-BC-CD-DA-AB,四相八拍运行方式即 A-AB-B-BC-C-CD-D-DA-A。
  • 步距角:一个脉冲信号所对应的电机转动的角度,可以简单理解为一个脉冲信号驱动的角度,电机上都有写,一般 42 两相混合式步进电机的步距角为 1.8°。
  • 定位转矩:电机在不通电状态下,电机转子自身的锁定力矩(由磁场齿形的谐波以及机械误差造成的)。
  • 静转矩:电机在额定静态电压作用下,电机不作旋转运动时,电机转轴的锁定力矩。此力矩是衡量电机体积的标准,与驱动电压及驱动电源等无关。

动态参数

  • 步距角精度:步进电机转动一个步距角度的理论值与实际值的误差。用百分比表示:误差/步距角 *100%。
  • 失步:电机运转时运转的步数,不等于理论上的步数。也可以叫做丢步,一般都是因负载太大或者是频率过快。
  • 失调角:转子齿轴线偏移定子齿轴线的角度,电机运转必存在失调角,由失调角产生的误差,采用细分驱动是不能解决的。
  • 大空载起动频率:在不加负载的情况下,能够直接起动的最大频率。
  • 最大空载的运行频率:电机不带负载的最高转速频率。
  • 运行转矩特性:电机的动态力矩取决于电机运行时的平均电流(而非静态电流),平均电流越大,电机输出力矩越大,即电机的频率特性越硬。
  • 电机正反转控制:通过改变通电顺序而改变电机的正反转。

步进电机的特点

  • 步进电机的精度大概为步距角的 3~5%,且不会积累。
  • 步进电机的外表允许的最高温度较高。步进电机发热的主要原因是铜损和铁损,铜损指铜导线的导电发热效应,铁损指作为铁芯的硅钢片在磁场中产生涡流效应而被加热。一般步进电机会因外表温度过高而产生磁性减小,从而导致力矩减小。一般来说磁性材料的退磁点都在摄氏 130 度以上,有的甚至高达摄氏 200度以上,所以步进电机外表温度在摄氏 80-90 度是完全正常的(28BYJ-48不会达到很高的工作温度)。
  • 步进电机的转矩与速度成反比,速度越快力矩越小。
  • 低速时步进电机可以正常启动,高速时不会启动,并伴有啸叫声。步进电机的空载启动频率是固定的,如果高于这个频率电机不能被启动,并且会丢步或堵转。

步进电机驱动

便于控制步进电机,将 MOS 管、控制器、电源、保护电路、散热器等等集成在一起,就做成了步进电机驱动器,驱动器的作用就是将控制器的信号放大或者进行转换。电机开发板输出脉冲信号给步进电机驱动器,驱动器将其功率放大控制步进电机,有些驱动器支持细分功能可以调节电流大小达到细分驱动,使其步距角更小,精度更高,旋转起来更加的顺滑。

驱动ULN2003例子

ULN2003是最常见的电机驱动器IC之一,由7对达林顿晶体管对的阵列组成,每对能够驱动高达500mA和50V的负载。该板上使用了七对中的四对。

  • 连接器:可以完美地匹配电动机的电线,这使得将电动机轻松连接到板上非常容易;还有用于四个控制输入的连接以及电源连接。
  • 四个LED:在四根控制输入线上显示活动(以指示步进状态),它们在电机运行时提供良好的视觉效果。
  • ON / OFF跳线:用于隔离步进电机的电源。

  • IN1 – IN4脚:用于驱动电动机。将它们连接到stm32上的数字输出引脚。
  • GND:是常见的接地引脚。
  • VCC:为电动机供电。将其连接到外部5V电源。由于电机消耗的功率过多,因此切勿使用Arduino的5V电源为步进电机供电。

Code

moter.c

unsigned int Zz_flag = 0;
unsigned int Fz_flag = 0;
unsigned int Zz_Value = 0;
unsigned int Fz_Value = 0;

void Motor_Init(void)
{

    GPIO_InitTypeDef GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC,&GPIO_InitStruct);
}

void Motor_Zz(void)//正转
{
    Zz_Value = 1;
    Fz_Value = 0;
}

void Motor_Fz(void)//反转
{
    Fz_Value = 1;
    Zz_Value = 0;
}

void Motor_Stop(void)
{
    Zz_Value = 0;
    Fz_Value = 0;
    Motor_A = 0;
    Motor_B = 0;
    Motor_C = 0;
    Motor_D = 0;
}

void Motor_Zz_Function(void)
{
            switch(Zz_flag)//八拍
        {
            case 0 : Motor_A = 1;Motor_B = 0;Motor_C = 0; Motor_D = 0;Zz_flag++;break;//A

            case 1 : Motor_A = 1;Motor_B = 1;Motor_C = 0; Motor_D = 0;Zz_flag++;break;//AB

            case 2 : Motor_A = 0;Motor_B = 1;Motor_C = 0; Motor_D = 0;Zz_flag++;break;//B

            case 3 : Motor_A = 0;Motor_B = 1;Motor_C = 1; Motor_D = 0;Zz_flag++;break;//BC

            case 4 : Motor_A = 0;Motor_B = 0;Motor_C = 1; Motor_D = 0;Zz_flag++;break;//C

            case 5 : Motor_A = 0;Motor_B = 0;Motor_C = 1; Motor_D = 1;Zz_flag++;break;//CD

            case 6 : Motor_A = 0;Motor_B = 0;Motor_C = 0; Motor_D = 1;Zz_flag++;break;//D

            case 7 : Motor_A = 1;Motor_B = 0;Motor_C = 0; Motor_D = 1;Zz_flag = 0;break;//DA

            default : break;

        }
}
void Motor_Fz_Function(void)
{
    switch(Fz_flag)
        {
            case 0 : Motor_A = 1;Motor_B = 0;Motor_C = 0; Motor_D = 1;Fz_flag++;break;//DA

            case 1 : Motor_A = 0;Motor_B = 0;Motor_C = 0; Motor_D = 1;Fz_flag++;break;//D

            case 2 : Motor_A = 0;Motor_B = 0;Motor_C = 1; Motor_D = 1;Fz_flag++;break;//CD

            case 3 : Motor_A = 0;Motor_B = 0;Motor_C = 1; Motor_D = 0;Fz_flag++;break;//C

            case 4 : Motor_A = 0;Motor_B = 1;Motor_C = 1; Motor_D = 0;Fz_flag++;break;//BC

            case 5 : Motor_A = 0;Motor_B = 1;Motor_C = 0; Motor_D = 0;Fz_flag++;break;//B

            case 6 : Motor_A = 1;Motor_B = 1;Motor_C = 0; Motor_D = 0;Fz_flag++;break;//AB

            case 7 : Motor_A = 1;Motor_B = 0;Motor_C = 0; Motor_D = 0;Fz_flag=0;break;//A

            default : break;

        }
}

moter.h

#ifndef __MOTER_H
#define __MOTER_H


void Motor_Init(void);
void Motor_Zz(void);//正转
void Motor_Fz(void);//反转
void Motor_Stop(void);
void Motor_Zz_Function(void);
void Motor_Fz_Function(void);

#endif