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

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

相关文章推荐

Cadence Allegro PCB Design 16.3破解安装

转自:http://linxiangjie.itweekee.com/?p=289 在高速数字电路设计中,Cadence Allegro无疑是最常用的工具之一,但是如果要买正版,费用不是你我等能够...
  • hjwang1
  • hjwang1
  • 2013年09月15日 17:53
  • 2363

[Android编译(二)] 从谷歌官网下载android 6.0源码、编译并刷入nexus 6p手机

1 前言经过一周的奋战,终于从谷歌官网上下载最新的android 6.0.1_r62源码,编译成功,并成功的刷入nexus6p,接着root完毕,现写下这篇博客记录一下实践过程。2 简介自己下载and...
  • fuchaosz
  • fuchaosz
  • 2016年09月27日 14:37
  • 11580

Verilog HDL语言的四相八拍步进电机驱动

这两天,学校做关于cpld的课程设计,本来应该用VHDL写的,但是由于我对这个比较白痴,所以就选用Verilog HDL写了,由于旁边有同学是学这个的这样,有什么问题也好解决一点。下面就先把我Veri...

单片机控制步进电机正反转8拍

  • 2017年04月30日 20:08
  • 5KB
  • 下载

驱动三相六拍式步进电机

  • 2012年07月31日 10:15
  • 3KB
  • 下载

小型步进电机驱动芯片的应用和介绍如HR8833

步进电机在生活中的应用处处可见,涉及到自动化机械制动产品基本都会有马达电机,小型的步进电机在消费类产品上应用非常广泛,像机器人,游戏机,安防相机,打票机,pOS机等,设计工程师在器件选型上会因为产品种...

步进电机工作原理 驱动 _28BYJ-48 以及程序实例下载

http://weibo.com/GTY55IW    先讲一下步进电机的工作原理: 步进式电动机   一、前言   步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载的情况...

步进电机细分驱动

步进电机细分驱动的实质是步进电机在输入脉冲切换时,只 改变相应绕组中的电流的一部分,即对相电流实施微量控制,利用各相电流的 阶梯变化产生一系列的假想的磁极对,则转子对应的每步运动也相应只是原步 距角的...

步进电机驱动方式总结

方式一:ULN2003驱动 适用范围:最大驱动电流0.5A,驱动5V直流电机,5V二相六线线步进电机,12V二相六线线步进电机(短时间可用,发热量大,注意散热),无散热片注:二相四线线步进电机不...

NX300 步进电机驱动电路图

NX300 步进电机驱动电路图   最近工作原因,一直很忙,过完年后就没有什么时间玩这个控制程序了,学习需要持之以恒,这些革命工作还得继续!上次说要把拆下的步进电机驱动电路专门设计,只有参考原来...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:步进电机的8拍驱动函数示例
举报原因:
原因补充:

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