基于#define 名称的条件语句

标签 c arm stm32

我刚开始做一些 C(来自 Java)。我试图弄清楚该语言基于定义名称的条件方法是什么。

例如我有一个巨大的头文件,我不能(不应该)用很多定义来编辑它。

#define GPIO_OTYPER_OT_0                     ((uint32_t)0x00000001)
#define GPIO_OTYPER_OT_1                     ((uint32_t)0x00000002)
#define GPIO_OTYPER_OT_2                     ((uint32_t)0x00000004)
#define GPIO_OTYPER_OT_3                     ((uint32_t)0x00000008)
#define GPIO_OTYPER_OT_4                     ((uint32_t)0x00000010)
#define GPIO_OTYPER_OT_5                     ((uint32_t)0x00000020)

等等;

我想创建一个函数/声明(或解决方案的任何内容)来作用于定义的 _# 部分。

(伪代码)

void initialize(int X) {
  GPIOA->MODER |= GPIO_MODER_MODER%X_5;
  GPIOA->OTYPER &= ~GPIO_OTYPER_OT_%X;
  GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR%X;
  GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR5;
  GPIOA->ODR |= GPIO_ODR_ODR_%X;
}

其中 %X 是 int X

我能想到的就是每个 X 的 switch 语句,但 X 的范围很大,所以源文件会很大。

编辑: https://github.com/espruino/Espruino/blob/master/targetlibs/stm32f4/lib/stm32f411xe.h 是头文件。

最佳答案

使用ST的GPIO抽象层,可引用here .值得注意的是,参见 GPIO_InitTypeDef这为您提供了上述操作的结构,并且 GPIO_Init这实际上会做你想做的。初始化结构将引脚作为位掩码,所以正如@artless noise 在评论中建议的那样,你可以做 1<<X创建你的面具。所有特定于 MCU 的行为和寄存器映射都隐藏在您的代码之外。

如果您正在尝试实现自己的驱动层作为练习,或者因为您认为 ST 库不是很好,那么我仍然会看看他们是如何实现的 GPIO_InitC file .他们使用移位,但您会注意到在处理寄存器时,它并不总是像 1<<X 那样容易。 (不过,请注意,对于它们的配置结构, 总是那么简单)。一些寄存器的每个引脚都有多个位(模式:2 位,拉取配置:2 位,替代功能:4 位,拆分为多个寄存器)。

编辑:我并不是建议添加更多您还没有的库。您在其中引用头文件的库/代码库已经包含 ST 的外设库,因此(对我而言)使用它很有意义。

关于基于#define 名称的条件语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38817767/

相关文章:

c - 我怎样才能访问正在运行的程序的内存?

c - C语言有多少个一元运算符

security - ARM TrustZone,连接外围设备?

ios - 在 ARM 组件中使用堆栈指针(sp)

STM32 和 SD 卡(FATFS 和 SPI)

c - 我将 fscanf 与字符类一起使用时出错

c - ARM:是从 int 原子写/读吗?

c - 将stm32 ADC值写入SD卡

stm32 - 通过定时器和 GPIO/AF 引脚变化生成两个相反的 PWM 信号

c - 在 iTerm2 或 nano 中启用语法突出显示吗?