首页 > 新能源汽车

ARM在mbed集成开发环境上的设计——第2部分:程序设计和结构

来源:新能源汽车网
时间:2023-03-17 16:14:15
热度:

ARM在mbed集成开发环境上的设计——第2部分:程序设计和结构在嵌入式系统中有许多不同的开发方法。如第 1 部分所述,mbed 无需安装软件,也不需要额外的开发硬件来程序。所有的

在嵌入式系统中有许多不同的开发方法。如第 1 部分所述,mbed 无需安装软件,也不需要额外的开发硬件来程序。所有的软件工具都放在网上,只要能上网就可以编译。

值得注意的是,有一个 C++ 编译器和一组广泛的软件库用于驱动外围设备。因此,也如第 1 部分所述,无需编写代码来配置外设,这在某些系统中可能非常耗时。

但是,尽管本书并不假定您具备任何 C 或 C++ 知识,但如果您具备这些知识,您将获得优势。

mbed 编译器和 API 
mbed 开发环境使用 ARM RVDS(RealView 开发套件)编译器,当前版本为 4.1。该编译器与 mbed 相关的所有功能都可以通过mbed 门户获得。

让 mbed 与众不同的一件事是它带有一个应用程序编程接口 (API)。简而言之,这是一组编程构建块,以 C++ 实用程序的形式出现,允许快速可靠地设计程序。因此,我们将使用 C 或 C++ 编写代码,但会利用 API 的功能。

使用 C/C++ 
如前所述,mbed 开发环境使用 C++ 编译器。这意味着所有文件都将带有 .cpp (Cplusplus) 扩展名。然而,C 是 C++ 的一个子集,并且更易于学习和应用。这是因为它没有使用 C++ 更的“面向对象”方面。

通常,C 代码将在 C++ 编译器上进行 C 编译,但反之则不然。C 通常是任何低复杂度或中等复杂度的嵌入式程序的语言,因此在这里很适合我们。因此,为简单起见,我们的目标是在我们开发的程序中仅使用 C。然而,应该认识到,mbed API 是用 C++ 编写的,并充分利用了该语言的特性。当我们遇到任何基本特征时,我们的目标是概述它们。

程序设计和结构 
处理嵌入式系统设计项目时会遇到许多挑战。首先考虑软件设计结构通常是明智的,尤其是对于大型多功能项目。不可能将所有功能编程到一个控制循环中,因此应该仔细考虑将代码分解为可理解的功能的方法。特别是,它有助于确保实现以下目标:

该代码是可读的,结构化的和文档化的该代码可以以模块化形式测试性能开发重用现有代码实用程序以缩短开发时间该代码设计支持多个工程师在一个项目上工作可以有效地实施未来的代码升级。

正如此处所讨论的,有多种 C/C++ 编程技术可以考虑这些设计要求,包括:函数、流程图、伪代码和代码重用。

函数的作用 
函数是较大程序中的一部分代码。函数执行特定的任务,相对独立于主代码。函数可用于操作数据;如果程序中需要多个类似的数据操作,这将特别有用。函数可以输入数据值,函数可以将结果返回给主程序。因此,函数对于编码数学算法、查找表和数据转换以及可能对多个不同并行数据流进行操作的控制功能特别有用。也可以使用没有输入或输出数据的函数,只是为了减少代码大小并提高代码的可读性。图 6.1 说明了一个函数调用。

使用函数有几个优点。首先,一个函数只写,编译到一个内存区域,而不管从主程序中调用它的次数如何,因此减少了程序内存。函数还允许设计干净且易于管理的代码,允许软件在多个抽象级别上结构良好且可读。函数的使用还支持模块化编码的实践,软件工程师团队通常需要开发大型和应用程序。因此,使用函数编写代码允许一名工程师开发特定的软件功能,而另一名工程师可能负责其他事情。

然而,使用函数并不总是完全有益。存储程序位置数据和从函数跳转返回的执行时间开销很小,但这应该只在大多数时间关键的系统中考虑。此外,可以在函数中“嵌套”函数,这有时会使软件难以遵循。C 函数的一个限制是只能从函数返回一个值,并且不能将数据数组传递给函数或从函数传递数据数组(只能使用单值变量)。因此,使用功能和模块化技术需要在开始编程之前设计和评估经过深思熟虑的软件结构。


图 6.1:函数调用

使用流程图定义代码结构 使用 
流程图来指示程序流程的操作和功能的使用通常很有用。可以在编码之前使用流程图设计代码流。图 6.2 显示了一些使用的流程图符号。


图 6.2:示例流程图符号

例如,采用以下软件设计规范:
设计一个程序来连续递增七段数字发光二极管 (LED) 显示器的输出(如图6.3所示,与第 1 部分中使用的类似)通过数字 0 到 9,然后重置回 0 继续计数。这包括:

使用函数将十六进制计数器字节 A 转换为相关的七段 LED 输出字节 B。输出 LED 输出字节以点亮正确的段 LED。如果计数值大于 9,则复位为零。延迟 500 毫秒,以确保 LED 输出以易于看到的速率递增。



图 6.3:七段显示

七段显示器的输出已在前面的第 1 部分中讨论过,特别是在表 3.4 中。一个可行的软件设计如图 6.4所示。


图 6.4:七段显示计数器的示例流程图设计

流程图使我们能够可视化代码的操作顺序,并判断程序的哪些部分可能需要多的关注或花费多的精力来开发。它们还有助于与非工程师交流潜在设计,这可能是设计满足非常详细规范的系统的关键。伪代码 
伪代码由简短的英语短语组成,用于解释程序中的特定任务。理想情况下,伪代码不应包含任何特定计算机语言的关键字。伪代码应该写成一系列连续的短语;我们甚至可以绘制箭头来显示循环过程。缩进可用于显示伪代码中的逻辑程序流。

编写伪代码可以节省程序开发的编码和测试阶段的时间,还有助于设计人员、编码人员和项目经理之间的沟通。一些项目可能使用伪代码进行设计,其他项目可能使用流程图,还有一些是两者的结合。

图 6.4 中流程图所示的软件设计也可以用 如下图 6.5所示的伪代码来描述

请注意,函数 SegConvert( ) 和 Delay( ) 是在别处定义的,例如在由不同工程师编写的单独的“实用程序”文件中。函数 SegConvert( ) 可以实现一个简单的查找表或多个 if 语句,将合适的值分配给 B。


图 6.5:七段显示计数器的示例伪代码

使用 mbed 上的函数 
实现七段显示计数器。下面的程序示例 6.1显示了一个程序,它实现了图 6.4 中的流程图和图 6.5 中所示的伪代码所描述的设计。

程序示例 6.1:七段显示计数器

它应用了第 1 部分的程序示例 3.5 中首次使用的一些技术,但不仅限于这些技术。主要设计要求是使用七段显示从 0 到 9 连续计数并循环返回到 0。BusOut 对象和 A 和 B 变量的声明以及 SegConvert() 函数原型出现在程序的早期。可以看出,main() 程序函数之后是 SegConvert() 函数,该函数在主代码中定期调用。行内通知

   B=SegConvert(A); // 调用函数返回 B

B 可以立即接受 SegConvert() 函数的返回值。

请注意下面一行的 SegConvert( ) 函数,它应用了 return 关键字:

   返回 SegByte;

这一行导致程序执行返回到函数被调用的点,将值 SegByte 作为其返回值。一旦你开始编写提供返回值的函数,它就是一个重要的技术。请注意,SegByte 已在程序清单的早期声明为函数原型的一部分。

将一个七段显示器连接到 mbed 并执行程序示例 6.1。七段 LED 显示屏的接线图如前面第 1 部分的图 3.10 所示。验证显示屏输出是否连续从 0 计数到 9,然后重置回 0。通过交叉引用流程图和伪代码确保您了解程序的工作原理先前显示的设计。

函数重用 
现在我们有了将十进制值转换为七段显示字节的函数,我们可以毫不费力地使用多个七段显示来构建项目。例如,我们可以通过简单地定义其 mbed BusOut 声明并调用与之前相同的 SegConvert() 函数来实现第二个七段显示(图 6.6 )。


图 6.6:用 mbed 控制两个七段显示

只需将主程序代码修改为程序示例 6.2中所示的代码,就可以实现一个从 00 计数到 99 的计数器程序。请注意,在此程序中还需要复制(重用)先前在程序示例 6.1 中定义的 SegConvert( ) 函数例子。另请注意,使用的编程方法略有不同;这里我们使用两个 for 循环来计算每个十位和单位值。


程序示例 6.2:两位七段显示计数器

使用两个七段显示器,引脚连接如图 6.6 所示,执行程序示例 6.2 并验证显示器输出从 00 连续计数到 99 然后重置回 0。回顾程序设计并熟悉用于计数十位的方法和个位数字,每个数字从 0 到 9。

更的程序还可以从主机终端应用程序读取两个数值,并将这些数值显示在连接到 mbed 的两个七段显示器上。因此,根据用户按键的要求,该程序可以显示 00 到 99 之间的任何整数。

示例程序设计使用四个函数来实现主机终端在七段显示器上的输出。四个函数如下:

SegInit( ) e 设置和初始化七段显示HostInit( ) e 设置和初始化主机终端通信GetKeyInput( ) e 从终端应用程序获取键盘数据SegConvert( ) 将十进制整数转换为七段显示数据字节的函数。

我们将使用 mbed 通用串行总线 (USB) 接口与主机 PC 和两个七段显示器进行通信,就像之前的练习一样。

现在,我们次遇到使用 ASCII 代码传递键盘数据和显示字符的方法。术语 ASCII 指的是美国信息交换标准代码,用于将字母数字字符定义为 8 位值。每个字母字符(低位和高位大小写)、数字(0e9)和标点字符的选择都由标识字节描述,即“ASCII 值”。因此,例如,当按下计算机键盘上的某个键时,其 ASCII 字节将传送到 PC。与显示器通信时也是如此。

数字字符的 ASCII 字节将高四位设置为值 0x3,低四位表示按下的数字键的值(0x0 到 0x9)。因此,数字 0e9 在 ASCII 中表示为 0x30 到 0x39。

要将键盘返回的 ASCII 字节转换为常规十进制数字,需要删除高四位。我们通过将 ASCII 代码与位掩码进行逻辑与运算来实现这一点,该数字的位设置为 1,我们希望在 ASCII 中保留一个位,并设置为 0,我们希望将位强制为 0。在这种情况下,我们应用位掩码 0x0F。逻辑 AND 应用运算符“&”并出现在以下行中:

   返回(c&0x0F);// 应用位掩码转换为十进制,并返回

程序示例 6.3中显示了示例函数和程序代码。



程序示例 6.3:基于主机按键的两位数七段显示

再次,应添加函数 SegConvert( ),如程序示例 6.1 所示,以编译程序。