如何在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到最重要的位;上面列出的其他引脚之间。
我为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到最重要的位;上面列出的其他引脚之间。