亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial Internet of Things >> 嵌入式

嵌入式固件提示:如何使用信号波形和其他文件数据在 C 中初始化数组

本文展示了如何使用文本文件中的值在 C 程序中初始化数组。

本文展示了如何使用文本文件中的值在 C 程序中初始化数组。数据不存储在源文件中。在编译程序时读取文件。考虑一维和多维数组。示例还展示了如何控制将数组放入 RAM 或非易失性存储器中以及选择用于初始化的数据文件。

示例中使用的编译器是 GCC for ARM,以 32 位微控制器为目标。所有示例均使用标准 C 语言并使用此编译器。

初始化数组的基础

数组可以在“声明”时使用值进行初始化。此处显示了一个典型的声明。花括号内的值称为“初始化器”。


如果括号内未指定数组的大小,则大小将为初始值设定项的数量。如果初始值设定项少于数组大小,则将多余的元素设置为 0。初始值设定项数超过数组大小是错误的。

空白区域

初始化程序必须用逗号分隔。添加“空白”是可以的。在这种情况下,空白是“空白”或空格。空白字符集包括空白(或空格)、制表符、换行符、回车符、垂直制表符和换页符。换行符和回车符在 C 源代码中用于指示行的结束。我知道表单提要但垂直选项卡?

通常,C 不关心语句是否包含空格或在另一行继续。这里的语句等同于上面的语句。经常会看到许多用于大型数组的初始化程序行。甚至可能是页面。在某些时候,我们可能会说,“有没有更好的方法?”


从文件初始化数组

C 源代码在编译前通过预处理器运行。 C 预处理器的一个常用功能是“文件包含”。这是 Kernighan 和 Ritchie 合着的著名著作《C 程序设计语言》中的一句话。

“文件包含使处理 #defines 的集合变得容易 和声明(除其他外 ).”

我为“除其他外”添加了斜体。虽然我们通常包含“.c”和“.h”文件,但预处理器并不关心文件的扩展名。任何文本文件都可以。因此,以下语法可用于初始化数组。


该文件不得包含任何有时为了格式化文档而隐藏的特殊字符。把事情简单化。没有富文本格式。没有列标题。只有数字、逗号和空格。这是使用 Windows 记事本创建的文件。


这是用调试器显示的内存中的数组。在这种情况下,阵列位于 RAM 中,如 Location 列中的高地址所示。


在非易失性存储器中存储数组并选择数据文件

在上面的例子中,数组是一个全局变量,没有指定放置数组的位置。编译器和链接器假定程序可以修改数组,并将其放置在 RAM 中。初始值在非易失性存储器(“NVM”,通常是闪存)中,RAM 中的数组由在主程序之前运行的代码根据这些数据初始化。程序不会访问 NVM 中的这些数据。如果数组不会被修改(它是一个“常量”),它只会放在 NVM 中并由程序直接访问。这可以节省经常供不应求的 RAM。告诉编译器和链接器一个数组不会被改变并在 NVM 中定位它通常是用“const ”预选赛。这是一个示例并查看结果。位置列显示它在内存映射中的低位,对于该微控制器来说是闪存。


#define#if 预处理语句可用于提供用于定位数组和选择用于初始化的数据文件的选项。这是一个示例,它提供了在 RAM 或 NVM 中定位数组的选择。


#if 构造是“条件包含”的一个例子。在这种情况下,它控制“const ” 限定符在声明数组时使用。之所以有效,是因为声明可以在多行上,或者换句话说,空格是可以的。

下面是一个使用条件包含来选择要初始化的文件的例子。


使用大型数组进行测试

我有一个描绘噪声波形的大随机数据文件,并用它来测试 NVM 中大型阵列的初始化。这是数据和声明的图。



这是文件的开头。


原始 csv 文件在值后没有逗号。这些可以通过使用可以在查找/替换操作中使用表达式的编辑器轻松添加。在本例中,我使用了行分隔符“\R”的表达式。查找是“\R”,替换是“,\R”。一次查找/替换操作添加了 10,000 个值的所有逗号。

一切都很好,编译速度非常快!这是内存中数组的开头。调试器很好地将显示分解为每组 100 个元素。


多维数组

如果数据是按两个或多个维度组织的怎么办?让我们看一个声明为 uint16_t test[2][3] 的二维数组 .在 C 中,右下标 (3) 是一个一维数组,其元素在内存中是连续的。左下标 (2) 表示这些三元素数组中有两个。这是六个元素的内存安排:

[0,0] [0,1] [0,2] [1,0] [1,1] [1,2]

内存中的排序很重要,因为通过增加右下标来访问内存中的连续元素比通过增加左下标来访问元素要快,这需要“跳跃”通过内存。如果数组包含两个包含 1,000 个元素的向量,则组织应该是 test[2][1000] 以获得最快的访问速度。

下面是一个初始化二维数组的例子。请注意,初始化器与额外的花括号组合在一起,将右下标的一维数组的初始化器分组。


这种格式对只能包含数字、逗号和空格的数据文件造成了问题。如果省略额外的花括号会怎样?


编译器通过首先填充右下标的初始化程序从左到右填充数组。我正在使用的编译器发出警告:“缺少初始化程序周围的大括号 ”。如果初始值设定项的数量与数组中的元素数量完全相同,则没有问题。但是,如果不相等,如果没有大括号作为引导,则不清楚如何填充数组。

可以使用多个 #include 从多个文件填充数组 声明。这是一个示例,其中初始化完全用一对大括号括起来。我省略了前面示例中显示的详细信息。


在联合中初始化数组

联合是一个变量,它可以保存共享相同内存的不同类型的对象,编译器会跟踪这些对象,就好像它们是不同的东西一样。这种安排对于内存不足的嵌入式应用程序可能很有用。这是一个带有 vector[6] 的示例 一维和矩阵[2][3] 有两个维度。它们是两个数组,它们在内存中占据相同的位置。


初始化联合的规则是联合中的第一件事(vector[6] ) 充满了初始值设定项。如果数组的顺序颠倒了,编译器会发出警告,因为初始化程序没有完全用花括号括起来。注意 #include 周围的花括号 加倍。我认为外部集合包含联合的所有初始化器,内部集合用于数组类型。

这是文件。我有两行,但没关系。只是更多的空白。


这是内存中的数组。注意 vector[ ] 的起始位置 和 矩阵[ ][ ] 都是一样的。


还有其他方法可以从只有数字、逗号和空格的单个文件中初始化多维数组吗?请通过添加评论告诉我们。

额外提示:字符串

字符串呢?下面是一个初始化字符串的例子。


#include 引号内不起作用。我的编辑器知道 C 语法,给了我很多问号和波浪线。新行和 #include 的字符 本身就是初始化器!可怜的编辑很困惑。这个乱码可以编译,但字符串填充的是我们在这里看到的字符,而不是文件中的字符。


解决办法是在文件中加引号。


然后,使用这样的语句。


请注意,文件名周围的引号是 #include 的一部分 语法并且不控制初始值设定项。这是 RAM 中的结果。


重要的是要注意,这些示例都应该理论上 使用任何编译器。但是,某些示例可能并不常见,并且可能会引起某些编译器的问题。如果您发现问题,请在评论中告诉我们。


嵌入式

  1. 云及其如何改变 IT 世界
  2. 如何避免数据分析项目的陷阱
  3. ST 使用 STM32 神经网络开发人员工具箱将 AI 驱动到边缘和节点嵌入式设备
  4. DATA MODUL:具有高亮度和easyTouch功能的大型开放式框架显示器
  5. Microchip:24 位和 16 位 ADC,数据速率高达 153.6 kSPS
  6. Contrinex:云就绪智能传感器和带蓝牙接口的安全光幕
  7. C++ 中的数组 |声明 |初始化 |指向数组示例的指针
  8. C++ 动态分配数组的例子
  9. Java BufferedReader:如何通过示例在 Java 中读取文件
  10. 如何使用 Tech Data 和 IBM Part 2 实现物联网
  11. 如何使用技术数据和 IBM 第 1 部分使物联网成为现实
  12. Nexus Integra 与其他物联网和大数据平台的区别