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

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

举报

相关文章推荐

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

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

步进电机linux驱动

#include #include #include #include #include #include #include #include #include #...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

STM32驱动步进电机

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

步进电机驱动 参数 --准备

1、步进电机旋转一周需要多少个脉冲是如何计算的?? 如细分/微步 等等有何关系?? 多少个脉冲一周不是计算出来的,电机做好就定死了,没法改的,目前市面上步进电机转一周最少的是整步200个脉冲,最多听说...

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

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

NX300 步进电机驱动电路图

NX300 步进电机驱动电路图   最近工作原因,一直很忙,过完年后就没有什么时间玩这个控制程序了,学习需要持之以恒,这些革命工作还得继续!上次说要把拆下的步进电机驱动电路专门设计,只有参考原来...

51控制步进电机的驱动

/*********************************************************************** 程序功能: 本程序为用单片机制作的占空比均匀间隔可调...

步进电机控制

首先,什么是步进电机: 然后是步进电机的分类: 这里重点讲一下二相和四相电机: 两相八线步进电机有两种接法: 我们怎么让步进电机动起来: 然后我们讲单片机控制方式: 一般...

步进电机驱动方式总结

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

STM32F103C8T6 ULN2003步进电机驱动代码

步进电机的驱动原理特别简单百度一下就OK了。 以下是用流水灯改进的代码。很垃圾但是可以使用!!! 仅供测试 #include "stm32f10x.h" #include "delay.h" #inc...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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