我想同时在 ST2M32F103REY Cortex M3 上使用通用定时器的溢出、比较匹配和捕获功能。CC1 配置为比较匹配,CC3 配置为捕获。IRQ 处理程序如下所示:
void TIM3_IRQHandler(void) {
if(TIM3->SR & TIM_SR_UIF){
TIM3->SR &= ~TIM_SR_UIF;
// do something on overflow
}
if(TIM3->SR & TIM_SR_CC1IF) {
TIM3->SR &= ~TIM_SR_CC1IF;
// do something on compare match
}
if(TIM3->SR & TIM_SR_CC3IF) {
TIM3->SR &= ~TIM_SR_CC3IF;
// do something on capture
}
}
原则上,它工作得很好,但有时似乎跳过了一部分。我的理论是,这是因为重置 IRQ 标志的操作,例如TIM3->SR &= ~TIM_SR_UIF
,不是原子的*,因此可能会发生例如在加载和存储之间发生的 TIM_SR_CC1IF 被覆盖的情况。
* 指令的反汇编如下
8012e02: 8a13 ldrh r3, [r2, #16]
8012e06: f023 0301 bic.w r3, r3, #1
8012e0a: 041b lsls r3, r3, #16
8012e0c: 0c1b lsrs r3, r3, #16
8012e0e: 8213 strh r3, [r2, #16]
- 这合理吗?TIM3->SR寄存器的内容可以在IRQ处理程序执行过程中改变吗?
- 是否有可能对 TIM3->SR 寄存器进行原子读写?
- 还有其他合适的解决方案吗?
顺便说一句:有一个类似的问题,但问题是关于保护多个进程或内核的访问,而不是保护软件和硬件的同时访问。