SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] &=
~((uint32_t)0x0F) <<
(0x04 * (EXTI_PinSourcex & (uint8_t)0x03));
SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] |=
(((uint32_t)EXTI_PortSourceGPIOx) <<
(0x04 * (EXTI_PinSourcex & (uint8_t)0x03)));
这是STM32F4板标准库中的一段代码。我了解每一个操作,但是整个代码确实很混乱。请接受挑战,以更直观的方式告诉我它的含义。
为了简单起见,请尝试解释
EXTI_PinSourcex
为0x01
且EXTI_PortSourceGPIOx
也为0x01
时的情况。任何意见表示赞赏,在此先感谢。
最佳答案
啊,按位运算符数学。
如果将其分解成一些片段并“未优化”某些语言语法,则更容易理解。让我们也更容易理解更大的变量卷积:SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02] &= ~((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03));
变成:
#define cfgval_shift_2r (SYSCFG->EXTICR[EXTI_PinSourcex >> 0x02])
cfgval_shift_2r = (cfgval_shift_2r) & ~((uint32_t)0x0F) << (0x04 * (EXTI_PinSourcex & (uint8_t)0x03));
解开一些常量的按位数学运算(例如
~((uint32_t)0x0F)
):cfgval_shift_2r = (cfgval_shift_2r) & 0xFFF0 << (0x04 * (EXTI_PinSourcex & 0x03));
现在,我们有了一些更容易阅读的东西。
EXTI_PinSourcex
== 0x00
:// cfgval_shift_2r = SYSCFG->EXTICR[0], because 0 shifted any number of bits is always 0
SYSCFG->EXTICR[0] = (SYSCFG->EXTICR[0]) & 0xFFF0 << (0x04 * (0 & 0x03));
// \ == 0 /
SYSCFG->EXTICR[0] = (SYSCFG->EXTICR[0]) & 0xFFF0;
因此,这将获取
SYSCFG->EXTICR[0]
的值,并简单地屏蔽掉最低有效字节并将其分配回该值。EXTI_PinSourcex
== 0x01
:// cfgval_shift_2r = SYSCFG->EXTICR[0], because (0x01 >> 0x02) == 0
SYSCFG->EXTICR[0] = (SYSCFG->EXTICR[0]) & 0xFFF0 << (0x04 * (0x01 & 0x03));
// \ == 0x04 * 0x01 == 0x04 /
SYSCFG->EXTICR[0] = (SYSCFG->EXTICR[0]) & 0xFFF0 << 0x04;
因此,这将采用
SYSCFG->EXTICR[0]
的值,将最低有效字节屏蔽掉,将所有内容向左移4位,然后将其分配回该值。您可以对第二个操作应用类似的细分。