单片机控制步进电机_单片机控制输出的pwm脉冲数控制步进电机 - CSDN
精华内容
参与话题
  • 单片机控制步进电机

    万次阅读 多人点赞 2019-06-06 19:07:38
    单片机控制步进电机正转 反转 加速 减速;由LCD1602实时显示步进电机的状态;F-正转,B-反转;数字越大,转速越大; 仿真原理图如下: MCU和LCD1602显示模块: ULN2803驱动和步进电机模块: C语言代码如下...

    简介:
    用单片机控制步进电机正转 反转 加速 减速;
    由LCD1602实时显示步进电机的状态;F-正转 B-反转;数字越大,转速越大;
    仿真原理图如下:
    MCU和LCD1602显示模块:
    在这里插入图片描述
    ULN2803驱动和步进电机模块:
    在这里插入图片描述
    C语言代码如下:

    /*-----------------------------
    FileName: StepperMotor.h
    Function: 函数头文件
    Author: Zhang Kaizhou
    Date: 2019-6-6 17:59:39
    ------------------------------*/
    #include <reg52.h>
    #include <string.h>
    #define uchar unsigned char
    #define uint unsigned int
    #define Factor 5 // 转速控制常数	
    
    /*LCD1602端口设置*/
    sbit lcdrs = P1^0;
    sbit lcdrw = P1^1;
    sbit lcden = P1^2;
    
    /*步进电机驱动器端口设置*/
    sbit direcChange = P1^3; // 方向翻转
    sbit speedUp = P1^4; // 加速
    sbit slowDown = P1^5; // 减速
    
    /*主函数声明*/
    void keyScan();
    void execute();
    
    /*LCD1602显示相关函数声明*/
    void LCDInit();
    void displayInit();
    void display(uchar oper, uchar dat);
    void writeCommand(uchar command);
    void writeData(uchar dat);
    void delay(uchar xms);
    
    /*-------------------------------------------
    FileName:main.c
    Function: MCU控制步进电机
    Description:控制步进电机正转 反转 加速 减速;
    由LCD1602实时显示步进电机的状态;
    F-正转 B-反转;数字越大,转速越大;
    ---------------------------------------------
    Author: Zhang Kaizhou
    Date: 2019-6-6 17:56:41
    -------------------------------------------*/
    #include "StepperMotor.h"
    
    uchar code pulseTable0[] = {0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x04, 0x08}; // 一相励磁(同一时刻只有一个线圈通电,旋转角1.8度)
    uchar code pulseTable1[] = {0x0c, 0x06, 0x03, 0x09, 0x09, 0x03, 0x06, 0x0c}; // 二相励磁(同一时刻有两个线圈通电,旋转角1.8度)
    uchar code pulseTable2[] = {0x08, 0x0c, 0x04, 0x06, 0x02, 0x03, 0x01, 0x09,
    						    0x09, 0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08}; // 一-二相励磁场(一二相交替励磁,旋转角0.9度)
    uchar speed = 0, startPos = 0; // 默认正转
    bit oper = 0/*操作数*/, direcFlag = 0; // 初始状态为正向
    
    void main(){
    	LCDInit(); // LCD1602显示初始化
    	displayInit();
    	while(1){
    		keyScan(); // 按键扫描
    		display(0, direcFlag);
    		display(1, speed);
    		execute();
    	}
    }
    
    /*按键扫描*/
    void keyScan(){
    	if(!speedUp){ // 加速
    		delay(5);
    		if(!speedUp){
    			if(speed < 4){
    				while(!speedUp);
    				speed++;
    			}else{
    				while(!speedUp);
    				speed = 3;
    			}
    		}
    	}
    	if(!slowDown){ // 减速
    		delay(5);
    		if(!slowDown){
    			if(speed != 0){
    				speed--;
    			}else{
    				while(!slowDown);
    				speed = 0;
    			}
    		}
    	}
    	if(!direcChange){ // 方向翻转
    		delay(5);
    		if(!direcChange){
    			while(!direcChange);
    			direcFlag = ~direcFlag;
    		}
    	}
    }
    
    /*步进电机控制执行函数*/
    void execute(){
    	uchar i, j;
    	startPos = (direcFlag == 0) ? 0 : 4; // 方向控制
    	for(i = startPos; i <= (startPos + 4); i++){
    		P2 = pulseTable0[i];
    		for(j = 0; j < (speed + 1) * Factor; j++){ // 用延时来控制脉冲输出的频率,从而控制步进电机转速
    			delay(10);
    		} 
    	}
    }
    
    /*-----------------------------
    FileName:display.c
    Function: LCD1602显示函数
    Author: Zhang Kaizhou
    Date: 2019-6-6 17:58:42
    ------------------------------*/
    #include "StepperMotor.h"
    
    uchar code table0[] = {"Direction:"}; // 每行的字符数据
    uchar code table1[] = {"Speed:"};
    uchar code table2[] = {"1234"};
    uchar code table3[] = {"FB"}; // F-正向 B-反向
    
    /*初始化LCD1602的设置*/
    void LCDInit(){
    	lcden = 0; // 拉低使能端,准备产生使能高脉冲信号
    	writeCommand(0x38); // 显示模式设置(16x2, 5x7点阵,8位数据接口)
    	writeCommand(0x0c); // 开显示,不显示光标
    	writeCommand(0x06); // 写一个字符后地址指针自动加1
    	writeCommand(0x01); // 显示清零,数据指针清零
    }
    
    /*LCD上电界面*/
    void displayInit(){
    	uchar i;
    	writeCommand(0x80); // 将数据指针定位到第一行首
    	for(i = 0; i < strlen(table0); i++){
    		writeData(table0[i]);
    		delay(5);
    	}
    	
    	writeCommand(0x80 + 0x40); // 将数据指针定位到第二行首
    	for(i = 0; i < strlen(table1); i++){
    		writeData(table1[i]);
    		delay(5);
    	}
    }
    
    /*LCD显示函数*/
    void display(uchar oper, uchar dat){
    	if(oper == 0){ // 方向显示
    		if(dat == 0){ // 正向
    			writeCommand(0x80 + strlen(table0)); // 数据指针定位到第一行空闲处
    			writeData(table3[0]);
    		}else if(dat == 1){ // 反向
    			writeCommand(0x80 + strlen(table0)); // 数据指针定位到第一行空闲处
    			writeData(table3[1]);
    		}
    	}
    	if(oper == 1){ // 速度显示
    		writeCommand(0x80 + 0x40 + strlen(table1)); // 数据指针定位到第二行空闲处
    		writeData(table2[dat]);
    	}
    }
    
    /*写指令函数*/
    void writeCommand(uchar command){
    	lcdrs = 0; // 命令选择
    	lcdrw = 0;
    	P0 = command;
    	delay(5);
    	
    	lcden = 1; // 产生一个正脉冲使能信号
    	delay(5);
    	lcden = 0;
    }
    
    /*写数据函数*/
    void writeData(uchar dat){
    	lcdrs = 1; // 数据选择
    	lcdrw = 0;
    	P0 = dat;
    	delay(5);
    	
    	lcden = 1;
    	delay(5);
    	lcden = 0;
    }
    
    /*延时函数*/
    void delay(uchar xms){
    	uint i, j;
    	for(i = xms; i > 0; i--)
    		for(j = 110; j > 0; j--);
    }
    
    展开全文
  • 51单片机步进电机实验

    千次阅读 2019-05-19 19:30:38
    1.步进电机图片 2.步进电机介绍 ...这一线性关系的存在,加上步进电机只有周期性的误差而无累积误差等特点,使得步进电机在速度、位置等控制领域的控制操作非常简单。虽然步进电机应用广泛,但它并不像...

    1.步进电机图片

     

    2.步进电机介绍

    步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。这一线性关系的存在,加上步进电机只有周期性的误差而无累积误差等特点,使得步进电机在速度、位置等控制领域的控制操作非常简单。虽然步进电机应用广泛,但它并不像普通的直流和交流电机那样在常规状态下使用,它必须由双环形脉冲信号、功率驱动电路等组成控制系统方可使用.因此.用好步进电机也非易事,它涉及机械、电机、电子及计算机等许多专业知识。

    3.步进电机分类

    (1)永磁式(PM)。一般为二相,转矩和体积较小,步距角一般为7.5°或15°。

    (2)反应式(VR)。一般为三相,可实现大转矩输出.步距角一般为1.5°,但噪声和振动都很大。在欧美等发达国家20世纪80年代已经淘汰。

    (3)混合式(HB)。指混合了永磁式和反应式的优点。它又分为二相和五相,二相步距角一般为180°,而五相步距角一般为0.72°。这种步进电机的应用最为广泛。

    4.技术指标

        (1)步进电机的静态指标

        ①相数—电机内部的线圈组数。目前常用的有二相、三相、四相、五相步进电机。电机相数不同,其步距角也不同。一般二相电机的步距角为0.9°/1.8°,三相为0.75°/1.5°、五相为0.36°/0.72°。在没有细分驱动器时,用户主要靠选择不同相数的步进电机来满足自己步距角的要求.如果使用细分驱动器,则“相数”将变得没有意义,用户只需在驱动器上改变细分数,就可以改变步距角。

        ②步距角—表示控制系统每发一个步进脉冲信号,电机所转动的角度。电机出厂时给出了一个步距角的值,如86BYG250A型电机的值为0.9°/1.8°(表示半步工作时为0.9°、整步工作时为1.8°),这个步距角可称为“电机固有步距角”,它不一定是电机实际工作时的真正步距角,真正的步距角和驱动器有关。

        ③拍数—完成一个磁场周期性变化所需脉冲数或导电状态.或指电机转过一个步距角所需脉冲数。以四相电机为例,有四相四拍运行方式,即AB-BC-CD-DA-AB:四相八拍运行方式,即A-AB-B-BC-C-CD-D-DA-A

        ④定位转矩—电机在不通电状态下,转子自身的锁定力矩(由磁场齿形的谐波以及机械误差造成).

    ⑥保持转矩—步进电机通电但没有转动时,定子锁住转子的力矩。它是步进电机最重要的参数之一,通常步进电机在低速时的力矩接近保持转矩。由于步进电机的输出力矩随速度的增大而不断衰减,输出功率也随速度的增大而变化,所以保持转矩就成了衡量步进电机最重要参数之一。比如,当人们说2N·m的步进电机时,在没有特殊说明的情况下,是指保持转矩为2N·m的步进电机。

    (2)步进电机的动态指标

    ①步距角精度—步进电机每转过一个步距角的实际值与理论值的误差,用百分比表示:误差/步距角X100%。不同运行拍数其值不同,四拍运行时应在5%之内,八拍运行时应在15%以内。

    ②失步—电机运转时运转的步数不等于理论上的步数,称为失步。

    ③失调角—转子齿轴线偏移定子齿轴线的角度.电机运转必存在失调角,由失调角产生的误差,采用细分驱动是不能解决的。

    最大空载起动频率—电机在某种驱动形式、电压及额定电流下,在不加负载的情况下,能够直接起动的最大频率。

    最大空载运行频率—电机在某种驱动形式、电压及额定电流下,电机不带负载的最高转速频率。

    运行矩频特性—电机在某种测试条件下,测得运行中输出力矩与频率关系的曲线称为运行矩频特性。它是电机诸多动态曲线中最重要的,也是电机选择的根本依据,如图所示。

    电机一但选定,电机的静力矩确定,而动态力矩却不然.电机的动态力矩取决于电机运行时的平均电流(而非静态电流),平均电流越大,电机输出力矩越大.即电机的频率特性越硬。

      

     

    其中.曲线3电流最大或电压最高;曲线I电流最小或电压最低,曲线与负载的交点为负载的最大速度点。要使平均电流大,尽可能提高驱动电压,或采用小电感大电流的电机。      

    ④电机的共振点—步进电机均有固定的共振区域,其共振区一般在50r/min-80r/min或在180r/min左右。电机驱动电压越高,电机电流越大,负载越轻,电机体积越小。则共振区向上偏移,反之亦然。为使电机输出电矩大、不失步且整个系统的噪声降低,一般工作点均应偏移共振区较多。因此,在使用步进电机时应避开此共振区。     

    5.步进电机工作原理

    步进电机是一种将电脉冲转换成相应角位移或线位移的电磁机械装置。它具有快速启、停能力,在电机的负荷不超过它能提供的动态转矩时,可以通过输入脉冲来控制它在一瞬间的启动或停止。步进电机的步距角和转速只和输入的脉冲频率有关,和环境温度、气压、振动无关,也不受电网电压的波动和负载变化的影响。因此,步进电机多应用在需要精确定位的场合。  

    (1)工作原理

    步进电机有三线式、五线式和六线式,但其控制方式均相同,都要以脉冲信号电流来驱动.假设每旋转一圈需要200个脉冲信号来励磁,可以计算出每个励磁信号能使步进电机前进1.8°。其旋转角度与脉冲的个数成正比。步进电动机的正、反转由励磁脉冲产生的顺序来控制。六线式四相步进电机是比较常见的,它的控制等效电路如下图所示。它有4条励磁信号引线A,/A,B,/B 通过控制这4条引线上励磁脉冲产生的时刻,即可控制步进电机的转动.每出现一个脉冲信号,步进电机只走一步。因此,只要依序不断送出脉冲信号,步进电机就能实现连续转动。   

     

    (2)励磁方式

    步进电机的励磁方式分为全步励磁和半步励磁两种。其中全步励磁又有一相励磁和二相励磁之分;半步励磁又称一二相励磁。假设每旋转一圈需要200个脉冲信号来励磁,可以计算出每个励磁信号能使步进电动机前进1.8°。简要介绍如下。

    ①一相励磁—在每一瞬间,步进电机只有一个线圈导通.每送一个励磁信号,步进电机旋转1.8,这是三种励磁方式中最简单的一种。

    其特点是:精确度好、消耗电力小,但输出转矩最小,振动较大。如果以该方式控制步进电机正转,对应的励磁顺序如下表所示。若励磁信号反向传送,则步进电机反转。表中的1和0表示送给电机的高电平和低电平。

     

    ②二相励磁—在每一瞬间,步进电动机有两个线圈同时导通。每送一个励磁信号,步进电机旋转1.8。

    其特点是:输出转矩大,振动小,因而成为目前使用最多的励磁方式。如果以该方式控制步进电机正转,对应的励磁顺序见下表。若励磁信号反向传送,则步进电机反转。

     

      ③一二相励磁—为一相励磁与二相励磁交替导通的方式。每送一个励磁信号,步进电机旋转0.9。

    其特点是:分辨率高,运转平滑,故应用也很广泛。如果以该方式控制步进电机正转,对应的励磁顺序见下表。若励磁信号反向传送,则步进电机反转。

     

    6.步进电机的驱动

    步进电机的驱动可以选用专用的电机驱动模块,如L298, FF5754等,这类驱动模块接口简单,操作方便,它们既可驱动步进电机,也可驱动直流电机。除此之外,还可利用三极管自己搭建驭动电路。不过这样会非常麻烦,可靠性也会降低。另外,还有一种方法就是使用达林顿驱动器ULN2003,该芯片单片最多可一次驱动八线步进电机,当然如果只有四线或六线制的也是没有问题的。

    首先我们看一下电路原理图

     本实验采用四线双极性步进电机,该电机与TC1117连接如上图所示,M_IN为单片机控制口,M_OUT为电机接入口,其中M_IN分别控制步进电机的相序A,B.

    TC1117芯片工作逻辑真值表:

    开发板上使用的 4线双极性步进电机,其有两相A,B,每个绕组有两根线,A+和A-B+和 B-,运行方式可以是A+ —A-—B+—B-,如果想换个方向运行,可以是 A- —A+—B—B+。

    步进电机的四个引脚A+、A-、B+、B-分别连接到OUA、OUTB、OUTC、OUTD四个引脚

     

    实际物理连接图如下:

     

     

    示例程序为:

     

       #include "reg52.h"
       
       typedef unsigned char u8;
       typedef unsigned int u16;
    
       sbit MOTOA = P1^0; //A+引脚
       sbit MOTOB = P1^1; //A-引脚
       sbit MOTOC = P1^2; //B+引脚
       sbit MOTOD = P1^3; //B-引脚
    
       #define SPEED 60000
    
       void delay(u16 i) //延时函数
       {
       while(i --);
       }
    
       void main()
       {
    
       P1 = 0x00; //电机处于待机状态
       while(1)
       {
       MOTOA = 1; //A+状态
       MOTOB = 0;
       MOTOC = 1;
       MOTOD = 1;
       delay(SPEED); //延时
    
       MOTOA = 0; //A-状态
       MOTOB = 1;
       MOTOC = 1;
       MOTOD = 1;
       delay(SPEED); //延时
    
       MOTOA = 1; //B+状态
       MOTOB = 1;
       MOTOC = 1;
       MOTOD = 0;
       delay(SPEED); //延时
    
       MOTOA = 1; //B-状态
       MOTOB = 1;
       MOTOC = 0;
       MOTOD = 1;
       delay(SPEED); //延时
    
       }
       }
    
    
    
    
    

     

    上例程序驱动步进电机的方向为: A+ —A-—B+—B-,

    如果想换个方向运行,也就是 A- —A+—B—B+,可以使用以下程序:

       #include "reg52.h"
       
       typedef unsigned char u8;
       typedef unsigned int u16;
    
       sbit MOTOA = P1^0; //A+引脚
       sbit MOTOB = P1^1; //A-引脚
       sbit MOTOC = P1^2; //B+引脚
       sbit MOTOD = P1^3; //B-引脚
    
       #define SPEED 60000
    
       void delay(u16 i) //延时函数
       {
       while(i --);
       }
    
       void main()
       {
    
       P1 = 0x00; //电机处于待机状态
       while(1)
       {
       MOTOA = 0; //A-状态
       MOTOB = 1;
       MOTOC = 1;
       MOTOD = 1;
       delay(SPEED); //延时
    
       MOTOA = 1; //A+状态
       MOTOB = 0;
       MOTOC = 1;
       MOTOD = 1;
       delay(SPEED); //延时
    
       MOTOA = 1; //B-状态
       MOTOB = 1;
       MOTOC = 0;
       MOTOD = 1;
       delay(SPEED); //延时
    
       MOTOA = 1; //B+状态
       MOTOB = 1;
       MOTOC = 1;
       MOTOD = 0;
       delay(SPEED); //延时
    
       }
       }
    
    
    
    
    

    如果想两个方向轮流运行,可以将上面两个程序结合在一块使用。

    展开全文
  • 基于51单片机步进电机控制

    万次阅读 多人点赞 2018-05-10 18:23:41
    前面笔者分享过基于51单片机的两种小车制作,我们利用的是L298N驱动控制电机转动,那么接下来,笔者给大家介绍两种利用51单片机控制步进电机的小程序。 首先我们要如何使电机转动呢,源程序如下: #include &...

    前面笔者分享过基于51单片机的两种小车制作,我们利用的是L298N驱动控制电机转动,那么接下来,笔者给大家介绍两种利用51单片机控制步进电机的小程序。
    首先我们要如何使电机转动呢,源程序如下:

    #include <reg52.h>
    
    
    unsigned char code F_Rotation[4]={0x02,0x04,0x08,0x10}; //正转表格,换算成二进制 0000 0010,0000 0100,0000 1000,0001 0000
    unsigned char code B_Rotation[4]={0x10,0x08,0x04,0x02}; //反转表格,换算成二进制 0001 0000,0000 1000,0000 0100,0000 0010
    /******************************************************************/
    /*                    延时函数                                    */
    /******************************************************************/
    void Delay(unsigned int i)//延时
    {
     while(--i);
    }
    /******************************************************************/
    /*                   主函数                                       */
    /******************************************************************/
    main()
    {
    
     unsigned char i;
    
     while(1)
     {
      for(i=0;i<4;i++)      //4相
         {
         P1=F_Rotation[i];  //输出对应的相 可以自行换成反转表格
         Delay(500);        //改变这个参数可以调整电机转速 ,数字越小,转速越大
         }
      }
    }

    接下来,我们要控制电机的正反转,这个程序主要用于4相步进电机的常规驱动,速度不可调的过快,不然就没有力矩的转动了,按s4可控制电机正反转:

    #include <reg52.h>
    
    bit Flag;//定义正反转标志位
    
    
    unsigned char code F_Rotation[4]={0xf1,0xf2,0xf4,0xf8}; //正转表格
    unsigned char code B_Rotation[4]={0xf8,0xf4,0xf2,0xf1}; //反转表格
    /******************************************************************/
    /*                    延时函数                                    */
    /******************************************************************/
    void Delay(unsigned int i)//延时
    {
     while(--i);
    }
    /******************************************************************/
    /*                   主函数                                       */
    /******************************************************************/
    main()
    {
    
     unsigned char i;
    
    
      EX1=1;         //外部中断0开
      IT1=1;         //边沿触发
      EA=1;          //全局中断开
    
     while(!Flag)            
     {
      P0=0x71;//显示 F 标示正转
      for(i=0;i<4;i++)      //4相
         {
         P1=F_Rotation[i];  //输出对应的相 可以自行换成反转表格
         Delay(500);        //改变这个参数可以调整电机转速 ,数字越小,转速越大
         }
      }
    while(Flag)
     { 
      P0=0x7C;//显示 b 标示反转
      for(i=0;i<4;i++)      //4相
         {
         P1=B_Rotation[i];  //输出对应的相 
         Delay(500);        //改变这个参数可以调整电机转速 ,数字越小,转速越大
         }
      }
    }
    /******************************************************************/
    /*                   中断入口函数                                 */
    /******************************************************************/
    void ISR_Key(void) interrupt 2 using 1
    {
     Delay(300);
    
     Flag=!Flag;         //s3按下触发一次,标志位取反
    
     }

    最后介绍一下带停机的步进电机正反转的方法:

    #include <reg52.h>
    
    unsigned char Flag;//定义正反转和停止标志位
    sbit KEY = P3^3;
    
    
    unsigned char code F_Rotation[4]={0xf1,0xf2,0xf4,0xf8}; //正转表格
    unsigned char code B_Rotation[4]={0xf8,0xf4,0xf2,0xf1}; //反转表格
    /******************************************************************/
    /*                    延时函数                                    */
    /******************************************************************/
    void Delay(unsigned int i)//延时
    {
     while(--i);
    }
    /******************************************************************/
    /*                   主函数                                       */
    /******************************************************************/
    main()
    {
    
     unsigned char i;
    
    
      EX1=1;         //外部中断0开
      IT1=1;         //边沿触发
      EA=1;          //全局中断开
    
     while(Flag==0)            
     {
      P0=0x71;//显示 F 标示正转
      for(i=0;i<4;i++)      //4相
         {
         P1=F_Rotation[i];  //输出对应的相 可以自行换成反转表格
         Delay(500);        //改变这个参数可以调整电机转速 ,数字越小,转速越大
         }
      }
    while(Flag==1)
     { 
      P0=0x7C;//显示 b 标示反转
      for(i=0;i<4;i++)      //4相
         {
         P1=B_Rotation[i];  //输出对应的相 
         Delay(500);        //改变这个参数可以调整电机转速 ,数字越小,转速越大
         }
      }
    while(Flag==2)  //停止
     { 
      P0=0x6D;//   显示 S
      P1=0;
      }
    }
    /******************************************************************/
    /*                   中断入口函数                                 */
    /******************************************************************/
    void ISR_Key(void) interrupt 2 using 1
    {
     Delay(500);
     if(!KEY)
     {
    
     Flag++;         //s3按下触发一次
     if(Flag==3)
       Flag=0;
      }
     }
    展开全文
  • 单片机-控制-步进电机

    千次阅读 多人点赞 2018-08-18 23:01:57
    开始浏览正文之前,请大家先花几分钟看完这段...通俗一点讲:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(即步进角),是现代数字程序控制系统中的主要执行元件,应用极为...

    开始浏览正文之前,请大家先花几分钟看完这段视频:

    步进电机是如何工作的


    步进电机(stepping motor)

    步进电机

    步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件,是一种将电脉冲转化为角位移的执行机构。通俗一点讲:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(即步进角),是现代数字程序控制系统中的主要执行元件,应用极为广泛。可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。

    在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响。

    当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度,称为”步距角”,它的旋转是以固定的角度一步一步运行的。

    可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。

    步进电机是一种感应电机,它的工作原理是利用电子电路,将直流电变成分时供电的多相时序控制电流,用这种电流为步进电机供电,步进电机才能正常工作,驱动器就是为步进电机分时供电的多相时序控制器。

    虽然步进电机已被广泛地应用,但步进电机并不能像普通的直流电机、交流电机在常规下使用。它必须由双环形脉冲信号、功率驱动电路等组成控制系统方可使用。因此用好步进电机却非易事,它涉及到机械、电机、电子及计算机等许多专业知识。

    步进电机作为执行元件,是机电一体化的关键产品之一,广泛应用在各种自动化控制系统中。随着微电子和计算机技术的发展,步进电机的需求量与日俱增,在各个国民经济领域都有应用。

    步进电机又称为脉冲电机,基于最基本的电磁铁原理,它是一种可以自由回转的电磁铁,其动作原理是依靠气隙磁导的变化来产生电磁转矩。

    由于步进电机是一个把电脉冲转换成离散的机械运动的装置,具有很好的数据控制特性,因此,计算机成为步进电机的理想驱动源,随着微电子和计算机技术的发展,软硬件结合的控制方式成为了主流,即通过程序产生控制脉冲,驱动硬件电路。单片机通过软件来控制步进电机,更好地挖掘出了电机的潜力。因此,用单片机控制步进电机已经成为了一种必然的趋势,也符合数字化的时代趋势。


    步进电机和伺服电机、舵机有何区别?

    伺服电机不仅仅只包含一个电机,通常是包含电机、传感器和控制器的电机系统(具体可以参考伺服电机/舵机 控制)。
    舵机是个俗称,适用于航模上,其实是一种低端的但最常见的伺服电机系统,价格低廉但精度较低。


    单片机控制示例

    51单片机按键控制单反转仿真

    相信通过视频及文字内容,大家对步进电机相关原理已经非常熟悉。下面通过Arduino Pro MINI开发板进行一项简易的步进电机控制实验。
    步进电机内部结构
    步进电机(Stepper/Step/Stepping Motor),主要是依靠定子线圈序列通电,顺次在不同的角度形成磁场,推拉定子旋转。接触步进电机时会有很多容易混淆的概念。比如单极性、双极性、两相八线、四相八线等等。主要是由于线圈的接法不同,我们先简单地辩析一下:按照电机驱动架构可分为单极性 (unipolar) 和双极性 (bipolar) 步进电机。所谓的极性,就是电流通过线圈绕组产生磁场的极性,单极性就是只有一个磁极,双极就是有两个磁极。四相,八相是指步进电机的相数,即步进电机内部的线圈组数。电机的相数不同,步进电机接收到每个脉冲信号的角度也不同。通过不同的极性,不同的相数,线圈接法会得到不同的电机性能。


    实验前要准备的元件
    - 28BYJ-48 五线四相步进电机
    - ULN2003驱动芯片
    - Arduino Pro MINI开发板
    - 杜邦线若干
    28BYJ-48,DC5V,五线四相步进电机


    示例代码一:

        可以直接在Arduino IDE的File> Examples> Stepper> MotorKnob里直接导入示例代码。
    

    Stepper.h是Arduino IDE自带的控制步进电机的标准库。

    电路原理图(电位计10K即可)
    实物连接示意图

        /*
         * MotorKnob
         *
         * A stepper motor follows the turns of a potentiometer
         * (or other sensor) on analog input 0.
         *
         * http://www.arduino.cc/en/Reference/Stepper
         * This example code is in the public domain.
         */
        #include <Stepper.h>
        // change this to the number of steps on your motor
        #define STEPS 100
        // create an instance of the stepper class, specifying
        // the number of steps of the motor and the pins it's
        // attached to
        Stepper stepper(STEPS, 8, 9, 10, 11);
        // the previous reading from the analog input
        int previous = 0;
        void setup() {
          // set the speed of the motor to 30 RPMs
          stepper.setSpeed(30);
        }
        void loop() {
          // get the sensor value
          int val = analogRead(0);
    
          // move a number of steps equal to the change in the
          // sensor reading
          stepper.step(val - previous);
    
          // remember the previous value of the sensor
          previous = val;
        }

    Stepper函数是用来创建步进电机实例的,共有如下两种用法:
    steps代表电机转一圈所用的步数。这个一般是步进电机出厂是就固定的。
    - 也可以通过步距角计算得出:
    转一圈的步数 = 360 / 步距角

                Stepper(steps, pin1, pin2)
                Stepper(steps, pin1, pin2, pin3, pin4)

    pin1,pin2,pin3,pin4是连接至步进电机的引脚。
    根据电机的引线数确定。pin3,pin4是可选的。

        setSpeed(rpms)函数是用来设置步进电机的速度,即每分钟该转的步数。
    
    • 根据实例代码,当转动电位器,步进电机也会转动一定角度。

    示例代码二:

    调用大神写好的库当然可以节约大量的开发时间,不过懂得原理也是非常有必要的。下面通过五线四相步进电机来进行简单说明:

    五线四相步进电机的工作方式
    `四相步进电机可以在:`
        - 四相单拍   : 通电顺序为 A-B-C-D
        - 四相双拍1  : 通电顺序为 AB-BC-CD-DA
        - 四相双拍2  : 通电顺序为 AC-BC-BD-DA
        - 四相八拍   : 通电顺序为 A-AB-B-BC-C-CD-D-DA-A
    `四种工作方式下工作。`
    




    下面依照8拍驱动方式编写相关代码:
        /* Main.ino file 
         * by: 禾灮Studios
         * 
         * Created:   周三 6月 13 2018
         * Processor: Arduino Uno
         * Compiler:  Arduino AVR (Proteus)
         */
        #define motor_pin_1 8       //A
        #define motor_pin_2 9       //B
        #define motor_pin_3 10      //C
        #define motor_pin_4 11      //D
        int shiJian =10;        //参数用于电机调速
    
    
        void steps_to_move_N(){     //逆时针旋转 八拍方式驱动,顺序为A AB B BC C CD D DA
            //1000  
            digitalWrite(motor_pin_1, HIGH);
            digitalWrite(motor_pin_2, LOW);
            digitalWrite(motor_pin_3, LOW);
            digitalWrite(motor_pin_4, LOW);
            delay(shiJian); 
            //1100  
            digitalWrite(motor_pin_1, HIGH);
            digitalWrite(motor_pin_2, HIGH);
            digitalWrite(motor_pin_3, LOW);
            digitalWrite(motor_pin_4, LOW);
            delay(shiJian);
            // 0100  
            digitalWrite(motor_pin_1, LOW);
            digitalWrite(motor_pin_2, HIGH);
            digitalWrite(motor_pin_3, LOW);
            digitalWrite(motor_pin_4, LOW);
            delay(shiJian);
            // 0110  
            digitalWrite(motor_pin_1, LOW);
            digitalWrite(motor_pin_2, HIGH);
            digitalWrite(motor_pin_3, HIGH);
            digitalWrite(motor_pin_4, LOW);
            delay(shiJian);
            //0010  
            digitalWrite(motor_pin_1, LOW);
            digitalWrite(motor_pin_2, LOW);
            digitalWrite(motor_pin_3, HIGH);
            digitalWrite(motor_pin_4, LOW);
            delay(shiJian);
            //0011  
            digitalWrite(motor_pin_1, LOW);
            digitalWrite(motor_pin_2, LOW);
            digitalWrite(motor_pin_3, HIGH);
            digitalWrite(motor_pin_4, HIGH);
            delay(shiJian);
            //0001  
            digitalWrite(motor_pin_1, LOW);
            digitalWrite(motor_pin_2, LOW);
            digitalWrite(motor_pin_3, LOW);
            digitalWrite(motor_pin_4, HIGH);
            delay(shiJian);
            //1001  
            digitalWrite(motor_pin_1, HIGH);
            digitalWrite(motor_pin_2, LOW);
            digitalWrite(motor_pin_3, LOW);
            digitalWrite(motor_pin_4, HIGH);
            delay(shiJian);
        }
        void steps_to_move_Z(){
            //1001  
            digitalWrite(motor_pin_1, HIGH);
            digitalWrite(motor_pin_2, LOW);
            digitalWrite(motor_pin_3, LOW);
            digitalWrite(motor_pin_4, HIGH);
            delay(shiJian);
            //0001  
            digitalWrite(motor_pin_1, LOW);
            digitalWrite(motor_pin_2, LOW);
            digitalWrite(motor_pin_3, LOW);
            digitalWrite(motor_pin_4, HIGH);
            delay(shiJian);
            //0011  
            digitalWrite(motor_pin_1, LOW);
            digitalWrite(motor_pin_2, LOW);
            digitalWrite(motor_pin_3, HIGH);
            digitalWrite(motor_pin_4, HIGH);
            delay(shiJian);
            //0010  
            digitalWrite(motor_pin_1, LOW);
            digitalWrite(motor_pin_2, LOW);
            digitalWrite(motor_pin_3, HIGH);
            digitalWrite(motor_pin_4, LOW);
            delay(shiJian);
            // 0110  
            digitalWrite(motor_pin_1, LOW);
            digitalWrite(motor_pin_2, HIGH);
            digitalWrite(motor_pin_3, HIGH);
            digitalWrite(motor_pin_4, LOW);
            delay(shiJian);
            // 0100  
            digitalWrite(motor_pin_1, LOW);
            digitalWrite(motor_pin_2, HIGH);
            digitalWrite(motor_pin_3, LOW);
            digitalWrite(motor_pin_4, LOW);
            delay(shiJian);
            //1100  
            digitalWrite(motor_pin_1, HIGH);
            digitalWrite(motor_pin_2, HIGH);
            digitalWrite(motor_pin_3, LOW);
            digitalWrite(motor_pin_4, LOW);
            delay(shiJian);
            //1000  
            digitalWrite(motor_pin_1, HIGH);
            digitalWrite(motor_pin_2, LOW);
            digitalWrite(motor_pin_3, LOW);
            digitalWrite(motor_pin_4, LOW);
            delay(shiJian); 
        }
    
        void setup(){  //初始化
            // put your setup code here, to run once:
            // setup the pins on the microcontroller:
            pinMode(motor_pin_1, OUTPUT);
            pinMode(motor_pin_2, OUTPUT);
            pinMode(motor_pin_3, OUTPUT);
            pinMode(motor_pin_4, OUTPUT);
    
            digitalWrite(motor_pin_1, HIGH);
            digitalWrite(motor_pin_2, HIGH);
            digitalWrite(motor_pin_3, HIGH);
            digitalWrite(motor_pin_4, HIGH); 
        }
        void loop(){   // put your main code here, to run repeatedly:
            steps_to_move_Z();
            // steps_to_move_N();
        } 

    示例代码三:

    下面的代码适用于Arduino系列,以及AVR单片机编程,修改后可直接用于其他单片机。
    本段代码是对示例代码二中函数的简化表述方式。

        /* Main.ino file 
         * by: 禾灮Studios
         * 
         * Created:   周三 6月 13 2018
         * Processor: Arduino Uno
         * Compiler:  Arduino AVR (Proteus)
         */
        #define motor_pin_1 8       //A
        #define motor_pin_2 9       //B
        #define motor_pin_3 10      //C
        #define motor_pin_4 11      //D
        int shiJian =10;        //参数用于电机调速   
        //定义八拍方式驱动,顺序为A-AB-B-BC-C-CD-D-DA
        unsigned char clockWise[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x0d}; 
    
            void zzz(){    //顺时针旋转
              for(int i=0;i<8;i++){
                PORTB = clockWise[i];
                delay(shiJian);
              }
            }
            void fff(){     //逆时针旋转
              for(int i=0;i<8;i++){
                PORTB = clockWise[8-i];
                delay(shiJian);
              } 
            }
    
        void setup(){  //初始化
            // put your setup code here, to run once:
            // setup the pins on the microcontroller:
            DDRB=0xFF;    //端口B设置为输出
            PORTB=0xFF;   //端口B初始值设置为1
        }
        void loop(){   // put your main code here, to run repeatedly:
            zzz();       
            fff();
        }

    实物连接


    以上内容就是控制步进电机的几种简易方法,各有优缺点大家根据自己的喜好和需要进行选择。不足之处还请大家批评指正。


        感谢一直关注着禾灮成长进步的朋友们。你们的信任、支持和鼓励,鞭策着我们一路走到了今天。
    
        感谢所有的合作伙伴,我们相互促进,共同见证了彼此的成长。
    
        感谢所有曾经在禾灮彼此倚靠、相互鼓励、携手同心、砥砺同行的兄弟姐妹。这里承载了我们的青春与热血。
    
                    禾灮,感谢有你。
    
        未来,我们将一如既往,砥砺前行。
    
                                            禾灮·小楊
                                           2018.07.05
    

    展开全文
  • 51单片机控制TB6600驱动器驱动42步进电机

    万次阅读 多人点赞 2020-08-15 10:45:44
    51单片机控制TB6600驱动器驱动42步进电机功能实现目标硬件简介硬件连接程序代码功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个...
  • 该工程是在keil开发环境下c51单片机控制步进电机的控制程序,实现四相四拍、四相八拍的正转及反转
  • 4按键控制,分别是启停、正反转、+速、-速。51单片机控制板电路图,程序源码+注解下载
  • Atmega16单片机控制步进电机实现正反针功能,采用S型曲线进行加减速,模块化的写法,可以实现任意角度转动的步进电机程序,具体内容可以关注我的博客,里面有详细的讲解。
  • 单片机控制步进电机-电路连接

    千次阅读 多人点赞 2019-02-22 21:26:14
    单片机控制步进电机-线路连接 说明:如何利用单片机去控制步进电机?本案例讲解的内容是硬件连接部分,采用常用的电子器件去实现单片机控制步进电机的功能。后续会分别讲解单片机程序,S曲线生成方法,上位机等...
  • 单片机控制步进电机-AVR详细程序

    千次阅读 2019-02-22 21:24:48
    单片机控制步进电机-单片机程序(avr) 硬件线路连接图见上一篇文章 软件: ICCV7 FOR AVR-写程序 Progisp-烧程序 速度S曲线生成器(后续后单独讲解)-生成S曲线数组代码 硬件: Atmega16 ASP下载线 杜邦...
  • 51单片机控制二相四线步进电机

    千次阅读 2020-09-09 10:37:11
    步进电机按定子上绕组来分,有二相、三相和五相等系列。最受欢迎的是两相混合式步进电机,约占97%以上的市场份额,其原因是性价比高,配上细分驱动器后效果良好。该种电机的基本步距角为1.8°/步,配上半步驱动器后...
  • 51单片机控制电动机正反转和调速

    万次阅读 多人点赞 2018-06-14 11:05:59
    经过不断地摸索和参考高手的设计,最终完成了单片机步进电机控制,可以实现步进电机的实时正反转,加速,减速。  至于步进电机的工作原理,相信很多人都已经知道,本次采用的是四相步进电机,采用四相八拍的工作...
  • 51单片机步进电机控制实验

    千次阅读 2018-12-20 19:10:34
    ORG 0000H LJMP MAIN MAIN: MOV A,#33H LOOP:MOV P1,A LCALL DELAY RLC A LJMP LOOP DELAY: MOV R5,#10 D1: MOV R6,#50 D2: MOV R7,#248 DJNZ R7,$ DJNZ R6,D2 DJNZ R5,D1 RET END
  • 如何用51单片机控制步进电机运动

    万次阅读 多人点赞 2017-01-05 17:56:26
    本来接触单片机挺久了的,但是一直只是停留在非常初级的认识阶段,本科的时候上过几门课,但是从来没有自己捣鼓过单片机,这次突然来了兴趣,感觉一下子学到了好多东西,在这里好好整理一下。这篇文章只适合于入门...
  • 51单片机 步进电机旋转角度控制

    千次阅读 2014-11-14 23:42:38
    #include typedef unsigned char uchar; typedef unsigned int uint; typedef unsigned long ulong; uchar code beatCode[8] = { 0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6 }; ulong beats = 0;...uchar T0RH =
  • 步进电机控制 (驱动板为TB6560)

    万次阅读 2014-05-24 16:35:43
    本文主要讲述了利用单片机对42步进电机进行
  • #include typedef unsigned char uchar; typedef unsigned int uint; typedef unsigned long ulong; uchar code beatCode[8] = { 0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6 }; ulong beats = 0;...uchar T0RH =
  • 51单片机按键控制步进电机加减速及正反转

    万次阅读 多人点赞 2020-04-09 18:44:09
    之前尝试用单片机控制42步进电机正反转,电机连接导轨实现滑台前进后退,在这里分享一下测试程序及接线图,程序部分参考网上找到的,已经实际测试过,可以实现控制功能。 所用硬件:步进电机及驱动器、STC89C52...
  • 步进电机单片机控制

    千次阅读 2005-12-14 10:10:00
    本设计采用凌阳16 位单片机SPCE061A对步进电机进行控制,通过IO口输出的具有时序的方波作为步进电机的控制信号,信号经过芯片L298N驱动步进电机;... 步进电机单片机控制 作者:李通 刘志垠摘要:本设计采用凌阳16 位
  • 1.能通过按键分别实现电机正反转以及停机 2.能通过按键分别控制让其旋转3个不同角度。(角度没有要求)
1 2 3 4 5 ... 20
收藏数 1,902
精华内容 760
关键字:

单片机控制步进电机