开发自己的 86Duino 函式库

本文件将解释如何替 86Duino 建立新的程式库。

86Duino 函式库的格式,在旧版 86Duino Coding 1xx 开发环境基本上与 Arduino 1.5.2 相容,在新版 86Duino Coding 2xx 开发环境与 Arduino 1.5.8 相容,因此使用者可以参考 Arduino library tutorial 页面来撰写 86Duino 程式库。(注意在旧版 86Duino Coding 1xx 开发环境上,有个限制与 Arduino 不同:任何在 86Duino 程式库内的档案须符合 DOS 8.3 filename 规范,也就是说任何档案的档案名称最多支援长度至八个字母以及在 ”.” 后最长为三个字母的副档名。这个限制是来自 DOSBOX 模拟器,86Duino Coding 1xx 开发环境所用来编译程式的工具之一。在新版 86Duino Coding 2xx 开发环境已没有此限制。)

我们将会由建立一个利用 LED 灯闪烁来制造摩斯密码的范例来解释如何将函式转换成程式库。转换成程式库后可以轻易的令其他使用者来使用你所撰写的程式或更新并改进它。

我们使用此简易产生摩斯密码的草稿码作为范例:

int pin = 13;

void setup()
{
  pinMode(pin, OUTPUT);
}

void loop()
{
  dot(); dot(); dot();
  dash(); dash(); dash();
  dot(); dot(); dot();
  delay(3000);
}

void dot()
{
  digitalWrite(pin, HIGH);
  delay(250);
  digitalWrite(pin, LOW);
  delay(250);
}

void dash()
{
  digitalWrite(pin, HIGH);
  delay(1000);
  digitalWrite(pin, LOW);
  delay(250);
}

若执行此草稿码将会以 pin13 闪烁出 SOS (紧急呼叫) 的摩斯密码。

此草稿码有一些不同的部分是我们必须要加进程式库内的。首先,当然是 dot() 以及 dash() 这两个用来控制闪烁的函式。第二,用来指定以哪只 ledPin 脚来闪烁出摩斯密码的 pin 变数。最后,将 pin 脚初始化成输出模式时所呼叫的 pinMode()

让我们开始将草稿码转换成函式库!

一个程式库至少需要两个档案:一个标头档 (附档名为 .h) 以及一个原始码档 (副档名为.cpp)。标头档内所放的是此程式库的定义,通常包含着程式库内所有函式或变数的清单。原始码档内则放着实际用来执行的程式码。我们将此程式库称为 Morse,因此我们的标头档必须为 Morse.h。让我们看看其内容为何,虽然一开始单看标头档会有些混淆,但之后配合原始码档即可厘清。

标头档的核心是由程式库内所有函式的定义所组成,并将程式库内所使用的变数以类别的方式封装起来。

class Morse
{
  public:
    Morse(int pin);
    void dot();
    void dash();
  private:
    int _pin;
};

一个类别只是单纯的函式与变数的集合。这些函式以及变数可以是 public 的,意味着任何其他使用你程式库的函式都可以存取。或者可以是 private 的,代表着只有同一类别内的函式可以存取。每个类别都会有一个特别的函式称为 建构元,这是用来建立一个类别的 实体 时所使用的。建构元的名称会与类别名称相同,且没有回传型态。

在标头档内还需要加入一些其他东西。一个是 #include 指令,它令你可以存取 Arduino/86Duino 所使用的程式语言中的标准型态与常数 (一般草稿码会自动加入,但程式库须自行加入)。此指令的使用方式如下 (必须放在类别定义程式码的上方):

   #include "Arduino.h"

最后,标头档常被一组看起来诡异的架构所包裹住。

#ifndef Morse_h
#define Morse_h

// the #include statment and code go here...

#endif

基本上,此架构可以预防其他使用者 #include 两次同一个程式库。

最后,在程式库的最上方通常会以注解来撰写一些资讯,包括程式库名称,简短的程式库用途描述,作者,撰写日期以及使用权许可。

让我们来看看完整的标头档范例:

/*
  Morse.h - Library for flashing Morse code.
  Created by David A. Mellis, November 2, 2007.
  Released into the public domain.
*/
#ifndef Morse_h
#define Morse_h

#include "Arduino.h"

class Morse
{
  public:
    Morse(int pin);
    void dot();
    void dash();
  private:
    int _pin;
};

#endif

现在让我们来看看原始码档 Morse.cpp。首先是一些 #include 命令让此程式库可使用 Arduino/86Duino 的标准函式并连结至你的标头档。

   #include "Arduino.h"
   #include "Morse.h"

再来是建构元:此段程式码在有人要建立此类别的实体时呼叫。在此范例中,使用者须指定要使用哪根 pin 脚。我们将此 pin 脚初始化成输出状态后将此变数储存于 private 变数以供其他类别内的函式使用。

Morse::Morse(int pin)
{
  pinMode(pin, OUTPUT);
  _pin = pin;
}

在此段程式码内有一些奇怪的地方。首先是在函式名称前的 Morse:: 符号。这代表此函式是属于 Morse 类别的成员函式。在撰写其他此类别的成员函式时将会再见到它。第二个地方是我们的 private 变数 _pin。此变数可以是任何你喜欢的名字,只要与标头档内的定义吻合即可。在此加入一条底线是一般用来方便辨认此变数属于private,且也可以与传入的参数做为分别 (如此范例的参数 pin)。

接下来是之前从草稿码抽出要做成程式库的部分。看起来大致上与之前相同,除了在函式名称前面多加上了 Morse:: 以及用 _pin 取代 pin

void Morse::dot()
{
  digitalWrite(_pin, HIGH);
  delay(250);
  digitalWrite(_pin, LOW);
  delay(250);  
}

void Morse::dash()
{
  digitalWrite(_pin, HIGH);
  delay(1000);
  digitalWrite(_pin, LOW);
  delay(250);
}

最后,通常会于原始码档的最上方以注解方式留下相关资讯。最终原始码档如下:

/*
  Morse.cpp - Library for flashing Morse code.
  Created by David A. Mellis, November 2, 2007.
  Released into the public domain.
*/

#include "Arduino.h"
#include "Morse.h"

Morse::Morse(int pin)
{
  pinMode(pin, OUTPUT);
  _pin = pin;
}

void Morse::dot()
{
  digitalWrite(_pin, HIGH);
  delay(250);
  digitalWrite(_pin, LOW);
  delay(250);  
}

void Morse::dash()
{
  digitalWrite(_pin, HIGH);
  delay(1000);
  digitalWrite(_pin, LOW);
  delay(250);
}

以上即完成了程式库。让我们看看如何使用你所建立的程式库。

首先,建立一个 Morse 资料夹并放置在 libraries 资料夹内。再将 Morse.hMorse.cpp 放入 Morse 资料夹内。启动 86Duino 编译环境后,开启草稿码 > 汇入程式库即可看到 Morse 在清单内。当草稿码使用到此程式库内的功能时将会编译此程式库。如果档案未被编译,请确认档案副档名确实为 .h 或 .cpp (不可使用其他副档名如 .pde 或 .txt)

让我们利用刚做出的程式库来重写一次打出摩斯密码 SOS 的草稿码:

#include <Morse.h>

Morse morse(13);

void setup()
{
}

void loop()
{
  morse.dot(); morse.dot(); morse.dot();
  morse.dash(); morse.dash(); morse.dash();
  morse.dot(); morse.dot(); morse.dot();
  delay(3000);
}

可以发现与旧草稿码有些许的不同。(除了将某些草稿码移动到程式库的部分)。

首先,我们在草稿码顶端加入了 #include 命令,令草稿码可以使用 Morse 程式库的功能并将 Morse 程式库编入机器码传至板子处执行。若是草稿码内不再使用 Morse 程式库了,使用者应该要删除 #include 命令来节省空间。

第二,我们为 Morse 类别建立了一个实体称做 morse

   Morse morse(13);

当这行命令被执行时 (通常是于 setup() 函式被执行之前),将会呼叫 Morse 类别的建构元并传送指定的参数 (在此范例中为 13)。

注意我们的 setup() 是空的,因为原先呼叫 pinMode() 的步骤被移入程式库内了 (当建构实体时会呼叫)。

最后,呼叫 dot() 以及 dash() 程式的部分须加入实体名称做为前缀也就是 morse。我们可能会建立多个 Morse 类别的实体,但每个实体所用的 pin 脚是储存于各自的 _pin 成员变数内。当我们以其中一个实体的名称来呼叫成员函式时,将会以该实体所储存的成员变数内容来执行。

   Morse morse(13);
   Morse morse2(12);

如此一来,若是利用实体 morse2.dot() 来呼叫 dot 函式时 _pin 成员变数将会是12。

当尝试过新的草稿码后,你可能会发现我们程式库内所使用的关键字并不会被编译环境改变颜色加以标记。这是由于 86Duino 软体并不能自动的辨认出程式库内所定义的东西 (即使标头档内写得很明确),因此我们必须给予一些提示。在 Morse 资料夹内建立一个档案名为 keywords.txt ,其档案内容如下:

   Morse KEYWORD1
   dash KEYWORD2
   dot KEYWORD2

每行内有想被当作关键字的名称以及一个 tab 键 (非空白键) 以及关键字的种类。类别名称的关键字种类通常为 KEYWORD1,在草稿码编辑视窗内将被标识为橘色。函式的关键字种类通常为 KEYWORD2,在草稿码编辑视窗内将被边是为棕色。修改后须重新启动 86Duino 编译环境关键字的设定才能顺利运作。

你也可以提供其他使用者有关此程式库的范例草稿码。建立一个 examples 资料夹并放置在 Morse 资料夹内。并将含有草稿码的资料夹 (此范例我们称之为 SOS) 移至 examples 资料夹内 (可藉由草稿码 > 显示草稿码的所在目录来找到草稿码位置)。重启 86Duino 执行环境后,可以在档案 > 范例清单内找到 Morse。在草稿码内也可加入一些注解来解释如何使用此程式库。

上述的范例程式库是取自 Arduino tutorial,使用者可从 Arduino 的网站上下载:Morse.zip


返回函式库主页面

The text of the 86Duino reference is a modification of the Arduino reference, and is licensed under a Creative Commons Attribution-ShareAlike 3.0 License. Code samples in the reference are released into the public domain.