什么是结构体?

结构体(structure)是一种便捷的编程工具,用于将相关变量组合到单一位置。这一概念适用于大多数类C编程语言(包括C和C++),常用于嵌入式微控制器应用。

本工程简报以Arduino Braccio机械臂(图1)为案例,介绍结构体构造。该结构体封装了控制舵机所需的所有数据(成员)。包括:

  • 对象指针:Arduino myServo对象
  • char[10]:存储舵机通用名称的字符串,例如 “SHOULDER”
  • uint16_t:舵机最小限位
  • uint16_t:舵机最大限位
  • uint16_t:舵机归位位置
  • uint16_t:舵机指令值
  • float:舵机过渡累加器

1 :配备六个舵机的Arduino Braccio机械臂图像。该结构体封装了每个舵机的数据。

技术提示 :结构体的定义特性是其能容纳不同数据类型。本例中,结构体包含16位整数、浮点数、Arduino舵机对象地址,甚至描述舵机的ASCII字符串。

C C++ 中对象的关系

该结构体封装了单个舵机的相关信息。我们可以稍作引申,将该结构体描述为单个舵机的"类对象"容器。

若改用完全面向对象编程语言(如C++),则可使用"对象"这一称谓。这将需要我们将结构体与操作数据的方法相关联。

为保持清晰、简单和最大兼容性,我们将继续采用C语言实现。因此,我们将使用术语“类对象”,并通过一组设置器和获取器来操作结构体内部的数据。

为什么我应该使用结构体?

机械臂是结构体应用的绝佳案例研究,因为RC伺服系统为类对象封装提供了具体实例。六个独立的RC伺服系统代表了中等复杂程度。确实需要协调所有伺服系统的动作,以实现平稳可控的机械臂运动。

“为何使用结构体”这个问题的最佳答案,可以通过考虑将所有伺服系统从路径点A移动到路径点B所需的代码来解答。我们可以编写独立的代码来控制每个伺服系统。然而,构建操作伺服系统的函数具有明显优势:

  • 单一功能的函数处理多个伺服系统,使程序更易于调试。

  • 易于实现限制,如伺服系统的最小和最大位置。

  • 可扩展性强,因为添加额外的伺服系统相对容易。

  • 易于实现涉及所有伺服系统的可控机械臂运动。

如何使用结构体?

结构体包括定义和各种使用语句两部分。
这是机械臂的定义:

// Define the ServoData struct (private to this file)
typedef struct {
  Servo servo;                 // The servo object (from the Servo library)
  char name[10];               // ASCII name for the servo
  uint16_t minPulse;           // Minimum allowed pulse width
  uint16_t maxPulse;           // Maximum allowed pulse width
  uint16_t home;               // Home (default) position
  uint16_t cmd;                // Active servo command pulse width
  float transitionAccumulator;  // Intermediate value used when transitioning from one step to another.
} ServoData;

注意,该结构体保存了单个RC伺服系统的数据。然后,我们可以将伺服系统分组为一个“结构体数组”,如下所示。

static ServoData servos[NUM_SERVOS];

从那里,我们可以使用如下命令访问成员:

servos[servoID].cmd = 1000;

当我们想要将机械臂移动到初始位置时,这种技术的真正威力就显现出来了。由于成员高度有序,我们可以使用简单的FOR循环将结构体的初始位置复制到结构体的活动伺服命令位置中。随后调用updateAllServos()函数,该函数执行所有伺服系统的平稳可控运动,直到机械臂到达预定义的初始位置。

void HomeAllServos() {
  for (int i = 0; i < NUM_SERVOS; i++) {
    servos[i].cmd = servos[i].home;
  }
  updateAllServos();
}

技术提示 :考虑HomeAllServos()和updateAllServos()函数中体现的简洁性。简洁性体现在两者都操作共享的结构体数组。例如,可以以最小的代码更改添加新的伺服系统。故障排除大大简化,因为各种函数对结构体成员执行简单操作。

结语

机械臂提供了一个实实在在的例子,展示了结构体的强大功能和便利性。在C编程语言中,我们以编程方式将每个RC伺服器视为类似对象的封装,通过多个getter和setter函数来操作结构体成员。根据应用需求,您可能需要转向C++语言,将RC伺服器数据封装成完整的对象,并配备操作结构体成员的方法。无论采用哪种方式,结构体都代表了代码简化的关键要素,在嵌入式领域具有明确的应用价值。

目前机械臂仍处于开发阶段。敬请期待后续文章对代码技术的详细说明。

欢迎分享您在嵌入式代码中使用结构体的经验,加入讨论。欢迎就嵌入式开发中C与C++的经典之争发表见解。

相关信息

请点击以下链接获取相关实用信息: