单片机:步进电机(内含:1 步进电机简介+2 步进电机工作原理+ 3 步进电机技术指标 +4. 软件设计+5.原始代码+6.实验现象)

简介: 单片机:步进电机(内含:1 步进电机简介+2 步进电机工作原理+ 3 步进电机技术指标 +4. 软件设计+5.原始代码+6.实验现象)

本章用到两个功能,推荐反复练习,重点是代码部分和步进电机原理部分

1 步进电机简介

步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。

2 步进电机工作原理

通常步进电机的转子为永磁体,当电流流过定子绕组时,定子绕组产生一矢

量磁场。磁场会带动转子旋转一定的角度,使得转子的一对磁场方向与定子的磁

场方向一致。当定子的矢量磁场旋转一个角度。转子也随着该磁场转步距角。每

输入一个电脉冲,电动机转动一个角度前进一步。

步进电机又分为单极性的步进电机和双极性的步进电机;具体简易图如下图

所示:


4c2bd812b2934d93a6a946ca9bbe1a36.png


其中左侧为单极性步进电机,右侧为双极性的步进电机.


双极性步进电机驱动原理:


在双相激励的过程中,也可以在换相位时加一个关闭相位的状态而产生走半

步的现象,这将步进电机的整个步距角一分为二,例如,一个 90°的步进电机

将每半步移动 45°,具体见下图。


5ce071c0940b4a66be3b98f8aad2ec6b.png


1. A 相通电,B 相不通电

2. A、B 相全部通电,且电流相同,产生相同磁性

3. B 相通电,A 断电

4. B 相通电,A 相通电,且电流相等,产生相同磁性

5. A 相通电,B 断电

6. A、B 相全部通电,且电流相同,产生相同磁性

7. B 相通电,A 断电

8. B 相通电,A 相通电,且电流相等,产生相同磁性

其中 1~4 步与 5~8 步的电流方向相反(电流相反,电磁的极性就相反)这

样就产生了顺时针旋转,同理逆时针是将通电顺序反过来即可。

注:单相与双相基本相同,理解原理即可


3 步进电机技术指标 :


包括静态指标和动态指标,此处不是重点,不再赘述.


4. 软件设计

本章所要实现的功能是:通过 ULN2003 驱动模块控制 28BYJ48 步进电机运行

方向及速度,当按下 KEY1 键可调节电机旋转方向;当按下 KEY2 键,电机加速;

当按下 KEY3 键,电机减速。

step_motor_28BYJ48_send_pulse 函数用于输出一个数据给 ULN2003,从而 实现向步进电机发送一个脉冲信号。它有两个形参,第一个为 step,指定步进 序号,可选值为 0-7,代表步进电机控制信号的 8 个节拍。第二个为 dir,指定电机的旋转方向,可选 1:顺时针,0:逆时针。这里指的顺时针逆时针是两个不 同方向。

函数先判断 dir 参数值,如果为 0,则为逆时针旋转,将 step 值变为 8 的互补数,其实就是将 8 个节拍反向输出。

主函数实现的功能很简单,首先定义一些变量,进入循环,检测是否有按键

按下,当KEY1 按下,切换步进电机方向;当 KEY2 按下,使电机加速;当 KEY3

按下,使电机减速。

程序中所用 STEPMOTOR_MAXSPEED 和 STEPMOTOR_MINSPEED 在开头已定义,表

示步进电机最大运行速度和最低运行速度,当然可以根据实际现象适当调整这两

个值。

5.原始代码如下:


(注:代码部分不建议直接复制粘贴,要多次理解,更要自己敲出来,复制粘贴容易眼高手低)


#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
//定义 ULN2003 控制步进电机管脚
sbit IN1_A=P1^0;
sbit IN2_B=P1^1;
sbit IN3_C=P1^3;
sbit IN4_D=P1^4;
//定义 ULN2003 控制步进电机管脚
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
#define STEPMOTOR_MAXSPEED 1
#define STEPMOTOR_MINSPEED 5
//延时函数,ten_us=1 时,大约延时 10us
void delay_10us(u16 ten_us)
{
    while(ten_us--);
}
//ms 延时函数,ms=1 时,大约延时 1ms
void delay_ms(u16 ms)
{
    u16 i,j;
    for(i=ms;i>0;i--)
    {
        for(j=110;j>0;j--)
        {
            ;
        }
    }
}
//独立按键扫描函数.mode的返回值是判断是不是多次扫描
u8 key_scan(u8 mode)
{
    static u8 key=1;
    if(mode)key=1;//等于1,多次扫描
    if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))
    {
        delay_10us(1000);//消抖
        key=0;        //返回值,否则第二次无法进入循环
        if(KEY1==0)
            return KEY1_PRESS;
        else if(KEY2==0)
            return KEY2_PRESS;
        else if(KEY3==0)
            return KEY3_PRESS;
        else if(KEY4==0)
            return KEY4_PRESS;
    }
    else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)
    {
        key=1;//防止第二次无法进入循环
    }
        return KEY_UNPRESS ;
}
//输出一个数据给 ULN2003 从而实现向步进电机发送
//一个脉冲
//step:指定步进序号,可选值 0~7 
//dir:方向选择,1:顺时针,0:逆时针
void step_motor_28BYJ48_send_pulse(u8 step,u8 dir)
{
    u8 temp=step;//默认顺时针
    if(dir==0)//逆时针旋转情况
    temp=-step;
    //8 个节拍控制:A->AB->B->BC->C->CD->D->DA
    switch(temp)
    {
        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=0;IN3_C=1;IN4_D=0;break;
        case 4:IN1_A=1;IN2_B=0;IN3_C=1;IN4_D=0;break;
        case 5:IN1_A=1;IN2_B=0;IN3_C=1;IN4_D=1;break;
        case 6:IN1_A=1;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;
    }
}//只要理解步进电机自传原理,就很简单
//不能为了敲代码而敲代码!
void main()
{
    u8 key=0;
    u8 dir=0;//默认逆时针方向
    u8 speed=STEPMOTOR_MAXSPEED;//默认最大速度旋转
    u8 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==KEY2_PRESS)//返回值为:减速
        {
            if(speed<STEPMOTOR_MAXSPEED) 
                speed+=1;
        }
        //执行步进电机的循环(A-->AB-->B-->....-->A)
        step_motor_28BYJ48_send_pulse(step++,dir);
        if(step==8)step=0;
        delay_ms(speed);
        } 
}


ad50bbbbf71643879db43ff0986335ad.png


错误修正:


1.在主循环的while循环中,第三个else if的返回值判断是减速的时候,应该改为


else if(key=KEY3_PRESS)  


逻辑是如果按键3按下,就执行speed--,减速命令.


2.#define KEY1_PRESS 4和#define KEY_UNPRESS 0在此函数中均未被使用,可直接不进行宏定义,不影响代码的执行


6.实验现象


使用 USB 线将开发板和电脑连接成功后(电脑能识别开发板上 CH340 串口),

把编译后产生的.hex 文件烧入到芯片内,实现现象如下:当按下 KEY1 键可调节

电机旋转方向;当按下 KEY2 键,电机加速;当按下 KEY3 键,电机减速。


9b28794555eb413aa6223ba9107bc0c5.png

注意:将步进电机红色线对接到“步进电机模块”输出端子 J47 的 5V 上,如图

576f06641ef1454e92790fe2326481f2.png


相关文章
|
1月前
|
传感器
51单片机循迹小车原理介绍和代码示例
51单片机循迹小车原理介绍和代码示例
51单片机循迹小车原理介绍和代码示例
|
1月前
|
传感器
51单片机矩阵键盘超详解!(内含LCD1602代码)
51单片机矩阵键盘超详解!(内含LCD1602代码)
25 0
【51单片机】利用【时间延迟】的原理规避【按键抖动问题】
【51单片机】利用【时间延迟】的原理规避【按键抖动问题】
【51单片机】自定义动态数码管显示(设计思路&原理&代码演示)
【51单片机】自定义动态数码管显示(设计思路&原理&代码演示)
【51单片机】自定义静态数码管显示(设计思路&代码演示)
【51单片机】自定义静态数码管显示(设计思路&代码演示)
|
1月前
|
编译器 C语言 开发者
单片机原理与应用:探索微型计算机世界
单片机原理与应用:探索微型计算机世界
28 1
|
1月前
|
数据采集 数据处理 C语言
单片机:探索其原理、应用与编程实践
单片机:探索其原理、应用与编程实践
29 1
|
1月前
|
物联网
STC51单片机-实验开发装置仿真-物联网应用系统设计
STC51单片机-实验开发装置仿真-物联网应用系统设计
75 0
|
1月前
|
物联网
STC51单片机-控制LED闪亮的仿真-物联网应用系统设计
STC51单片机-控制LED闪亮的仿真-物联网应用系统设计
51 0
|
1月前
|
传感器 人工智能 物联网
单片机:编程实践与应用探索
单片机:编程实践与应用探索
28 4

热门文章

最新文章