我正在用 C 语言对 STM32 进行编程,并利用 CMSIS 文件编写了一个自定义读取函数,让我的生活更轻松。
uint32_t ReadBits(volatile uint32_t *Reg, uint32_t Mask)
{
uint32_t tmp = *Reg & Mask; // temporary reg holding isolated values
uint32_t position = __builtin_ctz(Mask); // Find the trailing amount of 0's
return tmp >> position;
}
但是,当我在中断内调用此函数时,它会触发hardfault_handler。我是这样实现的:
void EXTI4_15_IRQHandler(void)
{
while(ReadBits(&GPIOC->IDR, GPIO_IDR_ID6) == 0)
{
GPIOB->ODR = GPIO_ODR_OD2; // Stall interrupt and keep LED on
}
GPIOB->ODR = 0; // Turn LED off
EXTI->FPR1 &= EXTI_FPR1_FPIF6; // Clear flag
}
有两点需要注意:
((GPIOC->IDR >> GPIO_IDR_ID6_Pos) & 0b1) == 0
替换 while 语句的内部时,根本没有戏剧性。确认是函数调用。这里有什么问题?如何保持自定义函数的易用性并保持稳定性?请忽略 ISR 内 while 语句的阻塞性质,我知道这不是一个好的做法,这只是一个测试项目。
我确定问题与调用和运行函数的开销有关,但不确定。
但是,通过将 ReadBits 函数重新实现为 #define 宏,问题就得到了解决,并且代码也同样易于使用。看起来像这样:
#define ReadBits(REG, MASK) (((REG) & (MASK)) >> __builtin_ctz(MASK))