首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当向预先标度的硬件计时器添加偏移量时,如何避免这一错误?

当向预先标度的硬件计时器添加偏移量时,如何避免这一错误?
EN

Stack Overflow用户
提问于 2017-02-17 22:27:13
回答 1查看 163关注 0票数 5

我正在写一个微控制器中断,需要在其硬件计时器中添加一个偏移量。然而,由于计时器预分频器的工作方式,这种朴素的方法可以根据中断执行相对于预分频器时钟的定时引入一个非逐个错误。

为此,我在ATmega328P (= arduino)上使用计时器1。我用/8预分频器以正常模式设置它,并且正在使用计时器捕获中断来触发这个中断;中断的目标是在触发输入捕获的事件之后,将计时器设置为完全溢出period周期(如果触发器发生在另一个中断或其他禁用中断的情况下)。

(我滥用PWM输出,在可变的交流相位偏移处触发两个主电源光三极管,而不需要消耗其上的所有CPU时间;中断是由主相的过零检测器触发的。)

ISR的代码如下所示:

代码语言:javascript
复制
uint_16 period = 16667;

ISR(TIMER1_CAPT_vect){
    TCNT1 = TCNT1 - ICR1 - period + (elapsed counter ticks during execution);
}

这里的临界间隔是从何时读取TCNT1到何时再次写入它之间的间隔。

据我所知,没有办法直接读取预分频器的状态,所以我认为不可能仅仅应用基于ISR定时的不同偏移量。

我可以在ISR (GTCCR |= _BV(TSM); GTCCR |= _BV(PSRSYNC); GTCCR &= ~_BV(TSM);)之前重置预分频器来同步,但这仍然会给计时器带来一个随机偏移,这取决于ISR的定时。

我正在考虑的另一种方法是使用计时器来生成与预分频器同步的中断。我已经在计时器1上使用两个输出比较寄存器,但是timer 0共享预分频器,这样就可以使用它了。但是,计时器中断的执行可能会被另一个中断或“cli”块推迟,所以这并不能保证工作正常。

我怎样才能写我的中断来避免这个错误?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-21 15:42:07

如果你把ISR写成

代码语言:javascript
复制
ISR(TIMER1_CAPT_vect){
    int counter = TCNT1 - ICR1 - period + 3;
    asm("nop");
    asm("nop");
    TCNT1 = counter;
}

TCNT1的写入应该在寄存器读取后整整24个周期进行,因此在相同的预分频器“相位”中进行。(必要时可调整nop的数目,例如由于不同的微控制器类型之间的差异)。然而,该解决方案不能考虑ICR1的设置与TCNT1读数之间的预分频器“相位”的变化。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42308445

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档