ICR1时间是否会错误地同步到溢出计数器



我有一个Atmega328p,我想对它进行编程,以精确捕获输入事件的时间。

然而,现在我想到了一个问题,我的代码是否能在所有情况下都工作。我认为,这个问题更多地与Atmega平台上中断的一般处理有关。

所以我的代码看起来是这样的(总结(:

volatile uint16_t overflow = 0;
ISR(TIMER1_CAPT_vect) {
uint16_t captureCount = ICR1;
uint32_t t = ((uint32_t) overflow << 16) | captureCount;
}
ISR(TIMER1_OVF_vect) {
overflow++;
}

当输入事件在中断ISR(TIMER1_CAPT_ect(内发生时,这应该捕捉到,此外,计时器1的溢出与其他中断一起计数。据我所知,ICR1准确地存储了输入事件发生时timer1的时间,然后在短时间后触发中断,通知代码该事件发生,然后我使用当前溢出计数器计算实时。

我从这个答案中知道,中断中的代码不会被另一个中断(例如溢出中断(中断,所以溢出和captureCount加在一起形成t是";原子"/"线程安全";。但我现在想知道的是,如果ICR1由当前timer1值设置,并且紧接着发生溢出,在ISR通知我的代码(timer1_CAPT_ect(之前,会发生什么。这样一来,可能是溢出中断在事件捕获中断之前运行。这将导致溢出计数器增加1,但ICR1仍然保持与旧溢出范围相对应的时间,从而给出错误的t.的可能性

因此,通常只有在触发事件捕获中断之前触发溢出中断时才会出现此问题,尽管真正的捕获事件(当ICR1设置为当前timer1时(发生在溢出之前。

这就引出了一个总体问题:中断的处理顺序是否与Atmega上发生的实际真实事件相同?

尤其是关于我对时间1的两次中断?

ATmega328P数据表听起来地址越低的中断优先级越高。因此,如果多个中断试图同时运行,我希望AVR选择地址最低的一个并运行它

来自第6.7节,复位和中断处理:

矢量的完整列表如第11节所示"中断;第49页。该列表还确定了不同中断的优先级。地址越低,优先级越高。RESET具有最高优先级,其次是INT0–外部中断请求0。

如果AVR按照您的建议运行,并记住每次中断发生的顺序,则需要大量额外的机器。

如果我们转到上面引用的数据表的第11节,我们会看到计时器1捕获中断的优先级高于计时器1溢出中断(因为它的地址较低(。

最新更新