5

单片机很好玩13,步进电机的使用

 3 years ago
source link: https://blog.popkx.com/mcu-is-fun-13-the-use-of-stepper-motor/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

单片机很好玩13,步进电机的使用

发表于 2019-01-27 19:01:29   |   已被 访问: 501 次   |   分类于:   单片机   |   暂无评论

前面几节主要介绍了如何使用C语言编程控制声光器件,本节再来说一点机械方面的经典器件——电机。然后我们在使用C语言编程单片机,制作一个“向日葵”,如下图:
[video width="544" height="960" mp4="https://www.xrkzn.cn/wp-content/uploads/2018/08/寻光器.mp4"][/video]
能够看出,电机会控制箭头始终指向光线最强的方向。

电机的分类方式有很多,按照用途总体可分为两大类:以直流电机为代表的驱动类电机,和以步进电机为代表的控制类电机。驱动类电机主要应用在电钻、风扇、小车轮子等设备上,而控制类电机则主要用在自动化仪表、智能机器、空调扇叶转动等设备上。

那显然,我们制作“向日葵”的目标时,选择使用控制类电机是非常合适的。这里我选用的是 28BYJ-48 步进电机,如下图:

6c112df5a13f22c7f1a7496d8ca72522.png

根据使用手册,步进电机 28BYJ-48 中的 28 表示步进电机的最大外径是 28 mm,B 表示是步进电机,Y表示是永磁式,J 表示电机是减速型的,48 表示电机是四相八拍的。

28BYJ-48 步进电机的工作原理

其实“48(四相八拍)”就是用于说明如何驱动这款步进电机的,先来看看它的内部原理图:

4ae2e00b13c14ad90c7dc775cd1423e3.png

步进电机的内圈(转子,顾名思义,它与转动轴相连,负责电机转动)有 6 个齿,每个齿上都是永磁体(Y),带有永久的磁性。步进电机的外圈(定子,保持不动)与外壳相连,它有 8 个齿,每个齿上都绕制了线圈,正对着的两个线圈是串联在一起的,所以它们同时导通或者关闭,这就形成了所谓的“四相”。

定子上的线圈导通时,因为电磁感应,就会产生磁力,吸引靠其最近的转子齿。如果交替导通 4 对线圈,则步进电机就转动起来了。按照上图中的步进电机内外圈相对位置,完成一个 B-C-D-A 四节拍后,转子将转过一个定子齿的角度,依此类推,当完成 8个这样的“四节拍”后,电机就恰好转过一圈。

9f1b3cd6b34df55456cff070258e6282.png

这样一来,显然一个节拍能够驱动步进电机转动 360/(8* 4)=11.25度。那么,有没有更加精细的控制方法呢?当然是有的,可以在每个节拍之间在加上一个节拍,形成 B-BC-C-CD-D-DA-A-AB 八节拍的控制方式,这样一个节拍能够驱动电机转动 5.626 度,控制就更精细了。

C语言编程51单片机,控制步进电机旋转

为了制作“向日葵”,应使用C语言编程51单片机,驱动步进电机实现正向旋转和反向旋转的功能,那么怎么实现呢?先来看看如何连线。

28BYJ-48 步进电机有 5 根控制线,其中一根线接 5V 驱动电源,另外 4 根就分别是 A、B、C、D 四个相了,可以使用单片机的 4 个 IO 口分别控制,这样一来,若想控制 A 相导通,只需编写C语言代码控制 A 相为低就可以了。8 个节拍的控制顺序如下:

6861577953e5e87334955fb89b37f9b0.png

考虑到51单片机的IO口电流驱动能力比较弱,所以按照第二节介绍的方法,使用三极管间接控制步进电机了,控制电路如下图:
ee76aabd05dc95964edbcf1adfc63934.png

这里将 A、B、C、D 依次连接到 P0 口的低 4 位了,所以若想导通 A 相,P0 的低 4 位应该是 0b1110,也就是 0xE,依此类推,其他几相应该是:
unsigned char code beatCode[8] = {0xe,0xc,0xd,0x9,0xb,0x3,0x7,0x6};

若想驱动电机转动,依次给 P0 赋值 beatCode[i] 就可以了。那么,多久赋值一次呢?再来看 28BYJ-48 步进电机的使用手册:

b901fbb4c66d37fef781b99cac968d3b.png

请注意 P.P.S 这个参数(pulses per second, 每秒脉冲数),也即 1 秒可以赋值 550 次,相当于一次赋值要维持 1/550 约为 1.8 ms。这样一来,控制步进电机转动的C语言程序可以这么写:
char motorIndex = 0;
void Delay2ms(unsigned int cnt)
{
    unsigned int i = 2000;
    while(cnt--)
        while(i--);
}

void MotorTurn(unsigned int rounds)
{
    while(rounds--){
        P0 = beatCode[motorIndex];
        motorIndex ++;
        motorIndex = motorIndex&0x07;
        Delay2ms(1);
    }
}
273a64a5a549c83a0eb3b3d573caaf83.png

MotorTurn() 函数就可以控制步进电机转动。代码很简单,就是依次向 P0 口赋值 beatCode 即可,因为 beatCode 只有 8 个元素,所以有 motorIndex = motorIndex&0x07; 这么一句。

假设上面的C语言代码是控制步进电机“正向旋转”的,那么我们还需要能够控制电机“反向旋转”的C语言程序,该怎么写呢?其实只要反向将 beatCode 赋值给 P0 就可以了,请看:

void MotorTurnBack(unsigned int rounds) // 反转
{
    while(rounds--){
        P0 = beatCode[motorIndex];      
        if(motorIndex > 0)
            motorIndex --;
        else
            motorIndex = 7;
        Delay2ms(1);
    }
}

MotorTurnBack() 函数可以控制步进电机“反向转动”。现在用C语言编写 main 函数,控制电机正向转动一会,再反向转动一会,代码如下,请看:

void main()
{
    while(1){
        MotorTurn(1000);
        MotorTurnBack(1000);
    }
}
b97269cea5153adeddf393cbc444a9fb.png

代码很简单,现在编译C语言程序,烧写到单片机,就能发现一切与预期一致。

制作“向日葵”

到这里,我们就完成了使用C语言编程单片机,控制步进电机正向和反向旋转的功能。再结合之前介绍的光敏电阻,就能实现文章开头的“向日葵”功能了,限于篇幅,下一节再说了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK