是否可以在此代码中使用重复结构?

Is it possible to use a repetition structure in this code?

我想要的是优化我的这部分代码。它只是在重复自己,但我不知道如何使用我使用的定义在这里使用重复结构。

我定义了 GPIO_Ports 和引脚。 这一直持续到 SEL8。

if (out & (1 << 0)) {
    GPIO_SetBits(SEL0_GPIO_Port, SEL0_Pin);
} else {
    GPIO_ResetBits(SEL0_GPIO_Port, SEL0_Pin);
}

if (out & (1 << 1)) {
    GPIO_SetBits(SEL1_GPIO_Port, SEL1_Pin);
} else {
    GPIO_ResetBits(SEL1_GPIO_Port, SEL1_Pin);
}

if (out & (1 << 2)) {
    GPIO_SetBits(SEL2_GPIO_Port, SEL2_Pin);
} else {
    GPIO_ResetBits(SEL2_GPIO_Port, SEL2_Pin);
}

我们不知道使用的变量类型。代码可能如下所示:

#include <assert.h>

// Indexas valid are from 0 to 8, some 9
#define IDX_MAX 9

typedef /* insert the type of SELx_GPIO_Port here */ gpio_port_type;

static gpio_port_type get_gpio_port_from_idx(size_t idx) {
  const gpio_port_type ports[] = {
    SEL0_GPIO_Port,
    SEL1_GPIO_Port,
    SEL2_GPIO_Port,
    SEL3_GPIO_Port,
    SEL4_GPIO_Port,
    SEL5_GPIO_Port,
    SEL6_GPIO_Port,
    SEL7_GPIO_Port,
    SEL8_GPIO_Port,
  };
  static_assert(IDX_MAX == sizeof(ports)/sizeof(*ports));
  assert(idx < sizeof(ports)/sizeof(*ports));
  return ports[idx];
}

typedef /* insert the type of SELx_Pin here */ pin_type ;

static pin_type get_sel_pin_from_idx(size_t idx) {
  const pin_type pins[] = {
    SEL0_Pin,
    SEL1_Pin,
    SEL2_Pin,
    SEL3_Pin,
    SEL4_Pin,
    SEL5_Pin,
    SEL6_Pin,
    SEL7_Pin,
    SEL8_Pin,
  };
  static_assert(IDX_MAX == sizeof(pins)/sizeof(*pins));
  assert(idx < sizeof(pins)/sizeof(*pins));
  return pins[idx];
}

void set_out(int out) {
   for (size_t i = 0; i < IDX_MAX; ++i) {
        (
           (out & (1 << i)) ? GPIO_SetBits : GPIO_ResetBits
        )(get_gpio_port_from_idx(i), get_gpio_pin_from_idx(i));
    }
}

前两个函数分别将 0 到 8 范围内的静态索引映射到 SELx_GPIO_Port 和 SELx_Pin 变量。之后,set_out 函数检查输入变量 int out 中的每一位,并根据该位是否已设置调用 GPIO_SetBitsGPIO_ResetBits。我使用了三元运算符,如果函数有不同的原型,或者是宏,你可以:

void set_out(int out) {
   for (size_t i = 0; i < IDX_MAX; ++i) {
        if (out & (1 << i)) {
            GPIO_SetBits(get_gpio_port_from_idx(i), get_gpio_pin_from_idx(i));
        } else {
            GPIO_ResetBits(get_gpio_port_from_idx(i), get_gpio_pin_from_idx(i));
        }
    }
}