如何在C中通过宏写入8位数据?

How to write 8 bit data by macro in C?

我为stm32写TFT LCD驱动,我需要写8位数据到LCD。我在 mcufriend 的库中找到了这个宏,但我不确定它是如何工作的以及如何编辑它。有人可以写下如何编写这样的宏及其工作原理吗?

mcufriend 库中的宏:

#define write_8(d) { \
GPIOA->regs->BSRR = 0x0700 << 16; \
GPIOB->regs->BSRR = 0x0438 << 16; \
GPIOC->regs->BSRR = 0x0080 << 16; \
GPIOA->regs->BSRR = (((d) & (1<<0)) << 9) \
           | (((d) & (1<<2)) << 8) \
           | (((d) & (1<<7)) << 1); \
GPIOB->regs->BSRR = (((d) & (1<<3)) << 0) \
           | (((d) & (1<<4)) << 1) \
           | (((d) & (1<<5)) >> 1) \
           | (((d) & (1<<6)) << 4); \
GPIOC->regs->BSRR = (((d) & (1<<1)) << 6); \
}

这看起来像 STM32duino 语法:

PORT->regs->REGISTER = value

REGISTER为BSRR,位设置复位寄存器。如果设置了相应的位,您分配给它的值会将 PORT 的引脚 0-15 设置为高电平。第 16-31 位与 BRR 寄存器的第 0-15 位作用相同;如果设置了该位,则相应的引脚设置为低电平。如果某位为零,则对应引脚的状态不变。

让我们看看宏中的每个单独赋值。


GPIOA->regs->BSRR = 0x0700 << 16;

这会将引脚 GPIOA8、GPIOA9 和 GPIOA10 设置为低电平。 ((1<<8) | (1<<9) | (1<<10) == 0x0700,BSRR 的高 16 位将相应位设置为低。)


GPIOB->regs->BSRR = 0x0438 << 16;

这会将引脚 GPIOB3、GPIOB4、GPIOB5 和 GPIOB10 设置为低电平。


GPIOC->regs->BSRR = 0x0080 << 16;

这会将引脚 GPIOC7 设置为低电平。


GPIOA->regs->BSRR = 
         (((d) & (1<<0)) << 9)
       | (((d) & (1<<2)) << 8)
       | (((d) & (1<<7)) << 1);

如果设置了 d 的第 0 位,则引脚 GPIOA9 设置为高电平。
如果设置了 d 的第 2 位,则引脚 GPIOA10 设置为高电平。
如果 d 的第 7 位被设置,则引脚 GPIOA8 被设置为高电平。


GPIOB->regs->BSRR = 
         (((d) & (1<<3)) << 0)
       | (((d) & (1<<4)) << 1)
       | (((d) & (1<<5)) >> 1)
       | (((d) & (1<<6)) << 4);

如果设置了 d 的第 3 位,则引脚 GPIOB3 设置为高电平。
如果设置了 d 的第 4 位,则引脚 GPIOB5 设置为高电平。
如果设置了 d 的第 5 位,则引脚 GPIOB4 设置为高电平。
如果设置了 d 的第 6 位,则引脚 GPIOB10 设置为高电平。


GPIOC->regs->BSRR =
         (((d) & (1<<1)) << 6);

如果设置了 d 的第 1 位,则引脚 GPIOC7 设置为高电平。


前三行将引脚 GPIOA8、GPIOA9、GPIOA10、GPIOB3、GPIOB4、GPIOB5、GPIOB10 和 GPIOC7 设置为低电平。

其余行将引脚 GPIOA9、GPIOC7、GPIOA10、GPIOB3、GPIOB5、GPIOB4、GPIOB10 和 GPIOA8 设置为高电平,前提是 d 中的相应位已设置。

换句话说,如果 d 中相应的位 0-7 被设置,宏将引脚 A9、C7、A10、B3、B5、B4、B10、A8 设置为高,如果清除则设置为低.

我会冒险猜测该宏用于使用 8 位并行总线与外围设备(可能是显示器)通信,引脚 A9 对应于发送的每个并行字节的最低有效位,引脚 A8到最重要的位;上面列出的其他引脚之间。