建立#define指令数组

时间:2018-07-10 22:32:11

标签: c arrays c-preprocessor

我有一些使用某些头文件的微控制器代码,其中的GPIO引脚定义如下:

#define PA3 GPIO(GPIO_PORTA, 3)

使用IDE,我可以导航到GPIO的实现,并且发现:

#define GPIO(port, pin) ((((port)&0x7u) << 5) + ((pin)&0x1Fu))

pin的定义为:

const uint8_t pin

portenum,定义为:

enum gpio_port { GPIO_PORTA, GPIO_PORTB, GPIO_PORTC, GPIO_PORTD, GPIO_PORTE }

我想创建一个包含所有GPIO定义(PA3PA4等)的数组,这些数组可以由通过串行端口传递的整数索引。

我尝试了以下操作:

GPIO knavePinList[] = {PA3, PA4, PA21, PB4, PHY_RESET_PIN, PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9};

但这显然不起作用,因为GPIO不是公认的C类型,实际上是一个宏。尝试构建时,我收到以下错误消息:

unknown type name 'GPIO'

我什至可以声明一个宏数组吗?如果是这样,我将如何记录我正在使用的类型?

谢谢。

3 个答案:

答案 0 :(得分:2)

#define语句执行文本替换,它们没有固有类型。如您所述,GPIO不是有效的类型,它是一个似乎在计算引脚号/地址的宏(实际上GPIO是未定义的,而GPIO(a,b)是宏)。

如果要存储其中许多数组,则需要知道它们全部求值的实际类型。假设GPIO宏返回一个port和一个pin值的和,其中port是一个枚举,其基础类型为int(从技术上讲,它是实现特定的整数类型-请参见enter image description here,而pinuint8_t,数组值的实际类型也将是整数类型-具体取决于您的实现,可能值的范围。

答案 1 :(得分:1)

否,您无法创建这样的宏数组。

如果要基于输入执行特定的宏,则需要使用if-elseswitch语句。如果输入是整数,则可以执行以下操作:

switch( input )
{
  case 0: PA3; break;
  case 1: PA4; break;
  case 2: PA21; break;
  ...
 }

答案 2 :(得分:1)

您发布的数组完全合法,我认为您尚未对其进行测试。无论如何,最好问一个可测试的示例(请参见How to create a Minimal, Complete, and Verifiable example),但要提供以下代码:

GPIO knavePinList[] = {PA3, PA4, PA21, PB4, PHY_RESET_PIN, PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9};

将生成一个完全合法初始化的整数数组,其中包含您从宏扩展的常量的按位值。尝试使用

cpp source.c | more

查看数组声明实际上是如何扩展的。顺便说一句,您的代码中还有另一个不同的问题...您正在使用相同的标识符GPIO来指示GPIO宏名称和类型数组元素,因此当宏处理器遇到它时,它看不到任何参数,这不是您#define对其进行的方式,并且抱怨两个参数宏GPIO根本没有任何参数被调用

您必须测试您的代码...,然后发送1.您期望的结果...和2.您获得的结果...,因为如果您只是停下来阅读它,错误应该是显而易见的。

您的问题的一种解决方案是将宏GPIO重命名为GPIO_BITS,然后更改所有定义:

#define GPIO_BITS(port, pin) ((((port)&0x7u) << 5) + ((pin)&0x1Fu))

...

#define PA3 GPIO_BITS(GPIO_PORTA, 3)

因此,当您遇到数组定义时,不会尝试将类型名称扩展为宏。