构建#define 指令数组
Building an Array of #define Directives
我有一些微控制器代码使用了一些头文件,其中 GPIO 引脚定义如下:
#define PA3 GPIO(GPIO_PORTA, 3)
使用 IDE,我可以导航到 GPIO
的实现,我发现:
#define GPIO(port, pin) ((((port)&0x7u) << 5) + ((pin)&0x1Fu))
其中 pin
定义为:
const uint8_t pin
和 port
是一个 enum
定义为:
enum gpio_port { GPIO_PORTA, GPIO_PORTB, GPIO_PORTC, GPIO_PORTD, GPIO_PORTE }
我想创建一个包含所有 GPIO 定义(PA3
、PA4
等)的数组,可以通过串行端口传递的整数对其进行索引。
我尝试了以下方法:
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'
我什至可以声明一个宏数组吗?如果是这样,我将如何记录我正在使用的类型?
谢谢。
#define
语句执行文本替换,它们没有固有类型。如您所述,GPIO
不是有效类型,它是一个似乎计算引脚 numbers/addresses 的宏(实际上 GPIO
未定义,而 GPIO(a,b)
是宏)。
如果你想存储其中许多的数组,那么你需要知道它们的计算结果都是什么实际类型。鉴于 GPIO
宏 returns 一个 port
和一个 pin
值的总和,其中 port
是一个枚举,其基础类型是 int
(从技术上讲,它是特定于实现的整数类型 - 请参阅 What is the underlying type of a c++ enum?)并且 pin
是 uint8_t
,数组值的实际类型也将是整数类型 - 具体取决于哪个类型关于您的实施和可能值的范围。
不,您不能创建这样的宏数组。
如果要根据输入执行特定的宏,则需要使用 if-else
或 switch
语句。如果输入是一个整数,你可以这样做:
switch( input )
{
case 0: PA3; break;
case 1: PA4; break;
case 2: PA21; break;
...
}
你post的数组是完全合法的,我想你没有测试过。无论如何,最好用一个可测试的例子来问,(见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
d 它的方式,并且抱怨没有调用的两个参数宏 GPIO
完全没有参数。
您必须测试您的代码...并发送 1. 您期望的...和 2. 您得到的...因为错误应该是显而易见的,如果您只是停下来阅读它。
您的问题的解决方案是将宏 GPIO
重命名为 GPIO_BITS
,例如...然后更改所有定义:
#define GPIO_BITS(port, pin) ((((port)&0x7u) << 5) + ((pin)&0x1Fu))
...
#define PA3 GPIO_BITS(GPIO_PORTA, 3)
所以遇到数组定义时,类型名没有尝试展开为宏
我有一些微控制器代码使用了一些头文件,其中 GPIO 引脚定义如下:
#define PA3 GPIO(GPIO_PORTA, 3)
使用 IDE,我可以导航到 GPIO
的实现,我发现:
#define GPIO(port, pin) ((((port)&0x7u) << 5) + ((pin)&0x1Fu))
其中 pin
定义为:
const uint8_t pin
和 port
是一个 enum
定义为:
enum gpio_port { GPIO_PORTA, GPIO_PORTB, GPIO_PORTC, GPIO_PORTD, GPIO_PORTE }
我想创建一个包含所有 GPIO 定义(PA3
、PA4
等)的数组,可以通过串行端口传递的整数对其进行索引。
我尝试了以下方法:
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'
我什至可以声明一个宏数组吗?如果是这样,我将如何记录我正在使用的类型?
谢谢。
#define
语句执行文本替换,它们没有固有类型。如您所述,GPIO
不是有效类型,它是一个似乎计算引脚 numbers/addresses 的宏(实际上 GPIO
未定义,而 GPIO(a,b)
是宏)。
如果你想存储其中许多的数组,那么你需要知道它们的计算结果都是什么实际类型。鉴于 GPIO
宏 returns 一个 port
和一个 pin
值的总和,其中 port
是一个枚举,其基础类型是 int
(从技术上讲,它是特定于实现的整数类型 - 请参阅 What is the underlying type of a c++ enum?)并且 pin
是 uint8_t
,数组值的实际类型也将是整数类型 - 具体取决于哪个类型关于您的实施和可能值的范围。
不,您不能创建这样的宏数组。
如果要根据输入执行特定的宏,则需要使用 if-else
或 switch
语句。如果输入是一个整数,你可以这样做:
switch( input )
{
case 0: PA3; break;
case 1: PA4; break;
case 2: PA21; break;
...
}
你post的数组是完全合法的,我想你没有测试过。无论如何,最好用一个可测试的例子来问,(见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
d 它的方式,并且抱怨没有调用的两个参数宏 GPIO
完全没有参数。
您必须测试您的代码...并发送 1. 您期望的...和 2. 您得到的...因为错误应该是显而易见的,如果您只是停下来阅读它。
您的问题的解决方案是将宏 GPIO
重命名为 GPIO_BITS
,例如...然后更改所有定义:
#define GPIO_BITS(port, pin) ((((port)&0x7u) << 5) + ((pin)&0x1Fu))
...
#define PA3 GPIO_BITS(GPIO_PORTA, 3)
所以遇到数组定义时,类型名没有尝试展开为宏