65.9K
CodeProject 正在变化。 阅读更多。
Home

嵌入式编程 – Netduino 入门 - 第 2 部分

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2015年1月20日

CPOL

7分钟阅读

viewsIcon

13840

嵌入式编程 – Netduino 入门 - 第 2 部分

在我上一篇文章中,我介绍了 Netduino 开发平台入门的基础知识。文章涵盖了环境设置以及我们创建的第一个程序,即闪烁板载 LED。第一个示例中的所有代码都插入到了 Main 方法中。在第二部分中,我们将重构代码,利用 C# 的一些面向对象特性来提高可读性。

尽管第一个示例中的所有代码都在 Main 方法中,但实际上完成了两个不同的任务。第一个是设置环境;第二个是执行我们想要完成的任务(闪烁 LED)。因此,我们将添加两个方法来隔离这两个任务的代码。如果您使用过 Arduino,您应该已经熟悉这个概念。Arduino 程序称为 sketches,它们包含两个方法:setuploop。这些修改并不激进,所有代码与我们原始程序相同,只是我们将代码行移到了各自的方法中。图 1 包含修改后的代码。

图 1 – 添加 Setup 和 Loop 方法
  1. 第 13 行是一个 static 字段,用于存储控制 LED 电源的 OutputPort 对象。由于创建了两个方法,因此 LED 变量需要从两个方法中都可以访问。因此,创建了一个类级别的变量,该变量对两个方法都可见。该变量是 static 的,因为所有代码都从 Main 方法的 static 上下文中运行。
  2. 第 15 至 17 行包含 Main 方法。Main 方法包含对 SetupLoop 方法的调用。
  3. 第 20 和 21 行包含 Setup 方法的声明。Setup 方法用于放置所有与初始化环境相关的代码。在这种情况下,初始化一个输出端口到板载 LED 引脚,并将初始状态设置为 false(即关闭)。
  4. 第 24 至 29 行包含 Loop 方法的声明。将控制 LED 打开和关闭的代码已移至此方法。

由于 C# 是一种面向对象的语言,因此可以创建类来表示正在处理的真实世界对象。对于 LED 示例,我们将创建两个类。一个将是 abstract 基类,用于表示 LED。另一个将是我们对 LED 的特定实现。图 2 是 LED 的 abstract 表示的代码列表。

图 2 – LED 抽象基类
  1. 第 8 行是 abstract 类的声明,它将作为 LED 实现的基类。
  2. 第 11 和 12 行包含两个 protected 字段。pin 变量将存储 LED 连接到的 Cpu.Pin 或端口。isOn 变量将存储一个布尔值,表示 LED 的当前状态。
  3. 第 15 和 16 行包含两个属性来获取字段的值。在这种情况下,没有创建 set 方法,因为字段将通过其他方式设置。
  4. 第 19 和 20 行声明了用于打开或关闭 LED 的 abstract 方法。

现在已经创建了一个 abstract 类,就可以编写实现。我们的第一个实现将允许 LED 简单地开启或关闭;因此,我们可以将第一个实现称为 LedBinary。图 3 是 Ledbinary 的代码列表。

图 3:LedBinary 代码列表
  1. 第 5 行是类的声明,该类继承自 Led abstract 类。
  2. 第 7 行,声明了一个 private 只读字段,用于 OutputPort,它位于 Microsoft.Spot.Hardware 命名空间中。输出端口是控制 LED 电源引脚的类,可以将其从 Program 类中抽象出来。
  3. 第 14 至 16 行是我们的初始构造函数,它需要 LED 连接的引脚和 LED 的初始开启或关闭状态。
  4. 第 23 行是一个方便的构造函数,它需要 LED 连接的引脚,并将 LED 的初始状态设置为关闭。可以使用构造函数链(重载),并将参数传递给第 14 行的初始构造函数来完成工作。
  5. 第 28 行是另一个方便的构造函数,它将初始化板载 LED。同样,使用链式调用将必需的参数传递给第 14 行的初始构造函数。需要注意的是,通过创建此构造函数,我们将此类与 Netduino Plus 绑定,因为已添加了一个引用以使用提供板载 LED 关键字的枚举。
  6. 第 30 和 31 行包含 SetOn 方法的代码。该方法包含一个简单的 if 语句,用于检查 LED 是否已开启,如果未开启,则将 true 写入端口以供电,并将 LED 的 isOn 状态设置为 true
  7. 第 34 和 35 行包含 SetOff 方法的代码。该方法包含一个简单的 if 语句,用于检查 LED 是否已开启,如果已开启,则将 false 写入端口以断电,并将 LED 的 isOn 状态设置为 false

现在已经创建了 LED 类,就可以修改 Program 文件来使用新类。如图 4 所示,完成工作所需的代码行数没有减少(技术上讲,如果算上创建的类,总行数会增加),但代码可以说更具可读性。

图 4:修改 Program 文件以使用 Led 和 LedBinary 类
  1. 第 13 行包含 Led 类的一个 private static 字段。
  2. 第 15 至 17 行包含调用 SetupLoop 方法的 main 方法。
  3. 第 20 和 21 行包含 Setup 方法的声明,该方法实例化了一个新的 LedBinary 作为程序中使用的 Led 类。由于 LedBinaryLed 的子类,因此无需进行类型转换,并且我们不需要将字段声明为 LedBinary,因为我们需要访问的所有方法都在 Led 类中。
  4. 第 24 至 29 行包含 Loop 方法的声明,该方法用于打开和关闭 LED。在这种情况下,我们不再需要在方法中提供布尔值,只需调用 Led 类中的 SetOnSetOff 方法即可。

重新设计代码需要付出一些代价,不一定是通过添加 SetupLoop 方法,而是创建类会增加我们部署包的大小。图 5 显示了包含所有工作在 main 方法中的版本 1 代码的部署大小。部署大小总计为 1204 字节。图 6 显示了将工作分离到 SetupLoop 方法中的版本 2 代码的部署大小。版本 2 的部署大小与版本 1 相同,为 1204 字节。图 7 显示了添加了 LED 类的版本 3 代码的部署大小。版本 3 的部署大小为 2156 字节,由于 LED 类增加了额外的代码,比版本 1 和 2 增加了近 1000 字节(技术上讲,我还有第三个用于脉冲宽度调制的 LED 类,将在下一篇文章中讨论)。

图 5:版本 1 部署大小,仅 main 方法

图 6:版本 2 部署大小,Setup 和 Loop 方法

图 7:版本 3 部署大小,LED 类

对代码所做的更改并没有增加任何额外功能;然而,这些修改可以提高可读性,并且通过为 LED 添加额外的类,我们添加了一些可以在其他项目中使用的代码。为提高可读性而付出的代价是代码库部署大小略有增加,但这并不显著,因为 Netduino 上总共有 128 KB 的代码存储空间可用。

© . All rights reserved.