步进电机的8拍驱动函数示例

转载 2016年06月01日 12:47:56

http://www.arduino.cn/thread-16151-1-1.html


在做arduino的步进电机实验时,很多人都是直接用IDE自带的stepper库来驱动步进电机。但是这个库只封装了2拍和4拍的步进电机驱动,而很多步进电机(如常见的28BYJ-48)是8拍驱动的。当然4拍也可以转起来,不过精度、平稳性和力矩都没有8拍好。

其实,驱动步进电机是个很简单的事情。在每种电机的资料中,都有驱动表格,如果有一定的编程能力,最好自己写个函数来驱动,可以做到最简洁而优雅,且占用最少的资源。这种简单的驱动,没有必要封装成库。

作为例子,针对上述28BYJ-48步进电机(5V,步进角度5.625,5线4相,8拍驱动,机械减速1:64),做了两个驱动函数。第一个示例函数用传统的方式,代码使用switch case结构,看起来比较清晰,可以作为思路的参考。第二个示例函数用了单片机口的概念,体现了单片机的特点,简洁而优雅。
这两个示例函数可以在1.0版以上的IDE中调用,都已测试通过。测试的最新版本是1.6.3。

只要有步进电机的驱动数据表格,这两个函数稍作修改就可以用于各种步进电机。


下面是28BYJ-48步进电机的驱动表格。


函数一测试代码:


int p = 0;    //  拍计数,顺时针7-0,逆时针0-7。
int t=24;          //  每拍延时,控制速度,1ms对应最高速。
                  //  负值为逆时针方向。
 
void setup() {
  Serial.begin(9600);  //初始化串口,作为监视。
  pinMode(4,OUTPUT);  //设置D4-D7脚为步进电机控制脚。
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
}
 
void loop() {
//  Serial.println(p);   //  串口输出拍数,调试用。
  t = 1;                //  每拍延时24ms,设置转速和方向。负值逆时针转。
  one_step(t);          //  驱动一拍。
}
 
//  此函数驱动一拍,参数控制速度与旋转方向。
void one_step(int t) {
    switch(p) {
    case 0:                        //  (0001)  对应8拍不同的输出值。
      digitalWrite(4,LOW);
      digitalWrite(5,LOW);
      digitalWrite(6,LOW);
      digitalWrite(7,HIGH);
      break;
    case 1:                       //  (0011)
      digitalWrite(4,LOW);
      digitalWrite(5,LOW);
      digitalWrite(6,HIGH);
      digitalWrite(7,HIGH);
      break;
    case 2:                       //  (0010)
      digitalWrite(4,LOW);
      digitalWrite(5,LOW);
      digitalWrite(6,HIGH);
      digitalWrite(7,LOW);
      break;
    case 3:                       //  (0110)
      digitalWrite(4,LOW);
      digitalWrite(5,HIGH);
      digitalWrite(6,HIGH);
      digitalWrite(7,LOW);
      break;
    case 4:                       //  (0100)
      digitalWrite(4,LOW);
      digitalWrite(5,HIGH);
      digitalWrite(6,LOW);
      digitalWrite(7,LOW);
      break;
    case 5:                        //  (1100)
      digitalWrite(4,HIGH);
      digitalWrite(5,HIGH);
      digitalWrite(6,LOW);
      digitalWrite(7,LOW);
      break;
    case 6:                       //  (1000)
      digitalWrite(4,HIGH);
      digitalWrite(5,LOW);
      digitalWrite(6,LOW);
      digitalWrite(7,LOW);
      break;
    case 7:                       //  (1001)
      digitalWrite(4,HIGH);
      digitalWrite(5,LOW);
      digitalWrite(6,LOW);
      digitalWrite(7,HIGH);
      break;
  }
  if (t < 0) {                  // t为负值,正向计数0-7。
      p ++;
      if (p > 7 ) {
        p = 0;                 // 计数到7重新开始。
      }
    } else {                    // t为正值,逆向计数7-0。
      p --;
      if ( p < 0 ) {          // 计数到零重新开始。
        p = 7;
      }
    }
  Serial.println(abs(t));
  delay(abs(t));            // 延时,短则转速高。
}


   

函数one_step()可以驱动一拍,使用方法在注释中都有。速度用延时函数控制,延时越少,速度越快。延时1ms可以轻松启动。注意,使用串口调试时,每发送一条串口数据,会有5ms左右的延时(在我自己的计算机上测试的数据)。这个延时也会包括在每一拍的驱动延时中。

函数二测试代码:
[C] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/* 步进电机8拍驱动,对应28BYJ-48,每圈64步,减速比64,
   输出轴每圈4096步。使用二进制掩码直接置位输出口。
*/
int p = 0;         // 拍计数,顺时针0-7,逆时针7-0。
int t;                // 每拍延时,控制速度,1ms对应最高速。负值为逆时针方向。
byte b[] = {B00010000,B00110000,B00100000,B01100000,
                 B01000000,B11000000,B10000000,B10010000};
                      // 对应每拍的D4-D7脚输出掩码。高4位有效。
                            
void setup() {
//  Serial.begin(9600);  // 初始化串口,作为监视。
  DDRD = DDRD | B11110000; // 置D4-D7脚为步进输出,其它脚不变。 
}
 
void loop() {
//  Serial.println(p);  // 串口输出拍数,调试用。
  t = -24;               // 每拍延时24ms,设置转速和方向。负值逆时针转。
  one_step(t);         // 驱动一拍。
}
 
//  此函数驱动一拍,参数控制速度与旋转方向。
void one_step(int t) {
  PORTD = PORTD & B00001111; // 清除D4-D7脚,D0-D3脚不变。
  PORTD = PORTD | b[p];               // 置位D4-D7脚,D0-D3脚不变。
//  Serial.println(PORTD,BIN);           //  串口输出掩码,调试用。
  if(t < 0) {                                     // t为负值,逆向计数0-7。
      p --;
      if(p < 0 ) {
        p = 7;                                   // 计数到0重新开始。
      }
    }else {                                      // t为正值,逆正向计数7-0。
      p ++;
      if( p > 7 ) {                              // 计数到7重新开始。
        p = 0;
      }
    }
  delay(abs(t));                              // 延时,短则转速高。
}

函数one_step()可以驱动一拍,使用方法在注释中都有。DDRD和PORTD是IDE的内置常数,分别表示arduino板上D0-D7脚的输出方向和输出状态,用二进制数直接可以定义。具体可查阅http://wiki.geek-workshop.com/doku.php?id=arduino:arduino_language_reference。


在arduino的学习和实验中,建议还是要学一点单片机的编程知识,最好不要照搬教程或者别人的代码,至少要问一个问什么。可以打开看看自己用到的官方库或第三方库,是不是适合自己的硬件。

代码的简洁和优雅,体现了编程的教养。

四线八拍步进电机(28BYJ48)代码

~\My Documents\Arduino\my_stepper\my_stepper.ino.html
  • V__KING__
  • V__KING__
  • 2014年01月04日 10:27
  • 2433

stm32简说步进电机(有代码)!!!

步进电机(也称脉冲电机)是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载的情况下,电机的转速,停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载的变化,即给电机一个脉冲信号,电机则转过一个...
  • msdnwolaile
  • msdnwolaile
  • 2016年07月25日 12:56
  • 14823

步进电机示例,步进电机八拍,双四拍,正反转规范示例。

  • 2010年03月09日 21:18
  • 89KB
  • 下载

步进电机的一些常识

1、拍数:完成一个磁场周期性变化所需脉冲数或导电状态用n表示,或指电机转过一个齿距角所需脉冲数,以四相电机为例,有四相四拍运行方式即AB-BC-CD-DA-AB,四相八拍运行方式即 A-AB-B-BC...
  • yezhubenyue
  • yezhubenyue
  • 2011年02月13日 16:48
  • 8082

四相八拍步进电机的转速如何计算?

四相八拍步进电机的转速如何计算
  • jackie430
  • jackie430
  • 2011年04月01日 23:55
  • 9930

步进电机原理和驱动

步进电机原理和驱动         步进电机是一种将电脉冲转化为角位移的执行机构。当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(称为“步距角”),它的旋转是以固...
  • zhenwenxian
  • zhenwenxian
  • 2014年06月25日 01:38
  • 4725

STM32驱动步进电机

步进电机是将电脉冲信号转变为角位移或线位移,可以通过控制脉冲来控制,因此比一般的电机更精准。这篇文章将会讲述我对四线两项步进电机的调试经验。1.步进电机以及THB7128的接线THB7128步进电机驱...
  • m0_38054539
  • m0_38054539
  • 2017年03月25日 21:20
  • 2478

如何用51单片机控制步进电机运动

本来接触单片机挺久了的,但是一直只是停留在非常初级的认识阶段,本科的时候上过几门课,但是从来没有自己捣鼓过单片机,这次突然来了兴趣,感觉一下子学到了好多东西,在这里好好整理一下。这篇文章只适合于入门阶...
  • buaazt
  • buaazt
  • 2017年01月05日 17:56
  • 5343

三、步进电机H桥的驱动方法

前面的文章里面我们介绍了步进电机的结构原理和细分控制原理。从步进电机的机构上我们了解到给步进电机的各相上按一定时序通电就能让步进电机转动起来,采用细分控制的方法能够使得电机运行更加平稳和准确。那么接下...
  • JX_zhipeng
  • JX_zhipeng
  • 2017年03月17日 14:29
  • 1570

51--步进电机驱动代码

#include #define uchar unsigned char #define uint unsigned int sbit dianji=P0^2; uchar ...
  • lxk7280
  • lxk7280
  • 2015年06月01日 20:21
  • 1213
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:步进电机的8拍驱动函数示例
举报原因:
原因补充:

(最多只允许输入30个字)