我想在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]
顺便说一下:There is similar question但是那个是关于保护多个进程或核心的访问,而不是保护软件和硬件的同时访问。
答案 0 :(得分:2)
reference manual(CD00171190)的 15.4.5 部分指出TIMx->SR
中的所有位都在 rc_w0 模式下工作(或保留)
根据programming manual(PM0056):
读取/清除(rc_w0):软件可以通过写入0来读取和清除该位。写入“1”对位值没有影响。
这意味着您可以简化代码以完全避免读取 - 修改 - 写入周期,而只需使用TIM3->SR = ~TIM_SR_UIF
。
许多应用笔记使用读 - 修改 - 写来清除中断,例如Keil的示例,但这是不必要的,并且可能有危险,正如您所经历的那样。 在ST应用笔记 DM00236305 (第1.3.2节)中,仅使用了写操作。
但请注意,使用 NVIC 时,用于重置的寄存器为 rc_w1 。