2013-09-24 47 views
0

我正在使用SDCC编译器。在定时器中断中断期间重新配置定时器8051

我想要实现的是在模式2自动重新加载时,在自己的中断处理程序中重新配置Timer0。下面是C代码:

void reconf(void) __interrupt(1){ 
    TR0=0; 
    TH0=0xC0; 
    TL0=0xC0; 
    TR0=1; 
} 

这里的问题:

  1. 是否有可能自己的中断处理程序执行期间重新配置TL0和TH0,定时器0在模式2自动重载模式?

  2. 重新配置期间是否需要停止Timer0,因为它在中断期间没有运行?

  3. 在中断例程 启动之前,TH0和TL0值是否被压入堆栈?如果将这些值压入堆栈,然后在例程处理程序执行过程中重新配置这些值,这些值是否会从中断退出时从堆栈弹出的值覆盖 ?

+0

我查看了编译C代码后由sdcc生成的HEX文件,看起来TH0和TL0在执行任何中断例程之前没有被压入堆栈。 – distortedbsd

+0

而且,我试图通过它的中断例程来重新配置timer0,它可以工作。 – distortedbsd

回答

1

解决你的问题之前,我认为这是值得指出的是什么TR0TH0TL0是。它们是而不是变量局部于函数或坐在堆栈上(假设您有一个调用堆栈,大多数8051应用程序不会查找内存覆盖)。这些是特殊功能寄存器,通常缩写为SFR。您可以read more about SFRs,但出于您的问题的目的,您可以将其视为范围透视图中的全局变量。

  1. 您可以修改TL0TH0寄存器在任何时候,包括定时器0外设的中断处理程序中。

  2. 没有必要停止定时器来修改它的值,但要注意它会在你这样做的时候继续计数。这可能是一个问题,如果你正在编写,只要低位字节翻转,你可能会得到一个不同于你打算的计时器值。

    <previous code> // Timer increments to 0x12fe 
    TH0 = 0xff;  // Timer is now 0xffff 
           // Timer increments to 0x0000 
    TL0 = 0x52;  // Timer is now 0x0052 
           // Timer increments to 0x0053 
    

    您试图将计时器设置为0xff52,但您以0x0052结束。这是一个极端的例子,但风险在那里。编写TL0后跟TH0可以降低风险,但关闭计时器是最简单的解决方案。

  3. 由于您现在知道TL0TH0是具有全局作用域的SFR,所以您不必担心堆栈或任何其他函数参数传递机制会干扰它们。