0

我想同时使用 ATmega 64微控制器的 8 位定时器。

我使用以下代码来声明它们的比较中断:

.org 0x0012 ; Timer2  8 bit counter
     rjmp TIM2
.org 0x001E ; Timer0 8 bit counter
    rjmp TIM1

我注意到,如果我输入第一个中断(0x0012),第二个计时器将不起作用......它的中断永远不会产生。为什么会发生这种情况,我该如何解决?

我还注意到一些奇怪的事情。如果我颠倒他们的顺序,我会得到错误:

.cseg 中的错误 3 重叠:addr=0x1e 与 0x1e:0x1f 冲突

4

1 回答 1

4

在 ATmega 上,其他中断在任何中断向量的执行期间都被阻止。

由于各种原因,这是一个有用的功能。这可以防止中断自身中断,防止由于递归导致的潜在堆栈溢出,并允许专门为低延迟中断留出特殊寄存器而无需先保存它们,并确保处理程序是原子的,以及其他原因.

然而,有时显式使用可重入中断很有用,尤其是在缺乏中断优先级的 ATmega 上。为此,只需添加一条 SEI 指令来设置中断使能标志。

但是,在执行此操作时,您必须非常小心以避免上述问题。通常这意味着任何使用的寄存器都必须保留在堆栈中,并且在重入部分开始之前需要禁用中断本身。

至于您的地址重叠问题,我怀疑问题在于您的汇编程序以字节为单位计算其程序地址,而数据表中的中断向量地址是用字指定的(例如,定时器 2 比较中断将位于 0x24 而不是 0x12) . 您还需要注意在完成向量的定义后返回主代码段,否则任何后续代码都将简单地运行到其他向量中。

于 2012-01-23T17:56:54.013 回答