C语言 嵌入式if条件中“#ifdef”行的逻辑是什么?

xxe27gdn  于 2023-01-16  发布在  其他
关注(0)|答案(1)|浏览(155)

在下面的代码中,我有一个efr32fg14评估板的按钮示例。
它们使用#ifdef命令检查是否定义了BSP_GPIO_LED1_PORT变量。
BSP_GPIO_LED1_PORT是命令所需的端口号。如果下面的代码中使用#ifdef的逻辑是正确的呢?

#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "bsp.h"

// Push-buttons are active-low
#define PB_PRESSED (1)

/**************************************************************************//**
 * @brief GPIO initialization
 *****************************************************************************/
void initGPIO(void) 
{
  // Enable GPIO clock
  CMU_ClockEnable(cmuClock_GPIO, true);

  // Configure PB0 and PB1 as input
  GPIO_PinModeSet(BSP_GPIO_PB0_PORT, BSP_GPIO_PB0_PIN, gpioModeInput, 0);
  GPIO_PinModeSet(BSP_GPIO_PB1_PORT, BSP_GPIO_PB1_PIN, gpioModeInput, 0);

  // Configure LED0 and LED1 as output
  GPIO_PinModeSet(BSP_GPIO_LED0_PORT, BSP_GPIO_LED0_PIN, gpioModePushPull, 0);
#ifdef BSP_GPIO_LED1_PORT
  GPIO_PinModeSet(BSP_GPIO_LED1_PORT, BSP_GPIO_LED1_PIN, gpioModePushPull, 0);
#endif
}

/**************************************************************************//**
 * @brief  Main function
 *****************************************************************************/
int main(void) 
{
  // Chip errata
  CHIP_Init();

  // Initializations
  initGPIO();

  while (1) 
  {
    // Set the state of LED0
    if (GPIO_PinInGet(BSP_GPIO_PB0_PORT, BSP_GPIO_PB0_PIN) == PB_PRESSED)
    {
      // LED0 On
      GPIO_PinOutSet(BSP_GPIO_LED0_PORT, BSP_GPIO_LED0_PIN);
    }
    else
    {
      // LED0 Off
      GPIO_PinOutClear(BSP_GPIO_LED0_PORT, BSP_GPIO_LED0_PIN);
    }

#ifdef BSP_GPIO_LED1_PORT
    // Set the state of LED1
    if (GPIO_PinInGet(BSP_GPIO_PB1_PORT, BSP_GPIO_PB1_PIN) == PB_PRESSED)
    {
      // LED1 On
      GPIO_PinOutSet(BSP_GPIO_LED1_PORT, BSP_GPIO_LED1_PIN);
    }
    else
    {
      // LED1 Off
      GPIO_PinOutClear(BSP_GPIO_LED1_PORT, BSP_GPIO_LED1_PIN);
    }
#endif
  }
}

我尝试查找#ifdef定义,以了解代码中此命令的逻辑。

hfyxw5xn

hfyxw5xn1#

#ifdef是预处理器指令(而不是“command”),用于 * 条件编译 *。
如果条件(在本例中为defined BSP_GPIO_LED1_PORT)为false,则从编译中删除条件与相应的#endif之间的代码,以便不为源代码的该部分生成代码。
在这种情况下,“逻辑”似乎是有条件地构建支持一个或两个LED的代码。即与LED0相关的代码 * 总是 * 包括在内,而与LED1相关的代码被排除在外,除非BSP_GPIO_LED1_PORT
因此,为了支持LED1,您可能需要一个头文件,其中包含(例如):

#define BSP_GPIO_LED1_PORT gpioPortA

或者你可以使用命令行swithc,比如GCC、CLANG和其他编译器中的-D BSP_GPIO_LED1_PORT=gpioPortA。注意defined/!defined是布尔状态,宏本身不需要有值,但这里它实际上是GPIO的端口标识符。
注意,存在对应的#ifndef(if-not-defined),并且两者都可以具有#else部分和零个或多个#elif(else-if)部分。
但是#ifdef/#ifndef是相当不灵活的。在C89中,添加了更有用的defined运算符,以便您可以使用#if和更复杂的表达式,例如:

#if defined BSP_GPIO_LED1_PORT && defined BSP_GPIO_LED1_PIN

#if表达式允许布尔表达式来控制条件编译,而不仅仅是defined/!defined#ifdef自C89以来一直是冗余的,但似乎不会消失。

相关问题