C 在定时器中断期间重新配置定时器8051

C 在定时器中断期间重新配置定时器8051,c,timer,interrupt,8051,sdcc,C,Timer,Interrupt,8051,Sdcc,我正在使用SDCC编译器 我试图实现的是在Timer0自己的中断处理程序中,在模式2自动重新加载中重新配置Timer0。下面是C代码: void reconf(void) __interrupt(1){ TR0=0; TH0=0xC0; TL0=0xC0; TR0=1; } 以下是问题: 在自己的中断处理程序执行过程中,是否可以在模式2自动重新加载模式下为定时器0重新配置TL0和TH0 是否有必要在重新配置期间停止计时器0,因为它 在中断期间没有运行吗 TH0

我正在使用SDCC编译器

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

void reconf(void)  __interrupt(1){
    TR0=0;
    TH0=0xC0;
    TL0=0xC0;
    TR0=1;
}
以下是问题:

  • 在自己的中断处理程序执行过程中,是否可以在模式2自动重新加载模式下为定时器0重新配置TL0和TH0

  • 是否有必要在重新配置期间停止计时器0,因为它 在中断期间没有运行吗

  • TH0和TL0值是否在中断例程之前推入堆栈 开始?如果将这些值推入堆栈,然后在例程处理程序执行期间重新配置这些值,这些值是否会被 从中断退出时堆栈中的POPed值


  • 在回答您的问题之前,我认为有必要指出什么是
    TR0
    TH0
    TL0
    。它们不是函数的局部变量,也不是堆栈上的变量(假设您有一个调用堆栈,而大多数8051应用程序都没有——查找内存覆盖)。这些是特殊功能寄存器,通常缩写为SFR。可以,但出于问题的目的,可以从范围的角度将它们视为全局变量

  • 您可以随时修改
    TL0
    TH0
    寄存器,包括在计时器0外围设备的中断处理程序中

  • 无需停止计时器来修改其值,但请注意,在进行此操作时,计时器将继续计数。如果您在写入时正处于较低字节的滚动状态,则可能会出现问题,因为最终可能会出现与预期不同的计时器值

    <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
    
    //计时器递增到0x12fe
    TH0=0xff;//计时器现在为0xffff
    //计时器增量为0x0000
    TL0=0x52;//计时器现在为0x0052
    //计时器递增到0x0053
    
    您试图将计时器设置为0xff52,但最终结果为0x0052。这是一个极端的例子,但风险是存在的。通过先编写
    TL0
    ,然后再编写
    TH0
    ,可以降低风险,但关闭计时器是最简单的解决方案

  • 既然您现在知道
    TL0
    TH0
    是具有全局作用域的SFR,您就不必担心堆栈或任何其他函数参数传递机制会干扰它们


  • 我研究了sdcc在编译C代码后生成的十六进制文件,似乎在执行任何中断例程之前,TH0和TL0都没有被推入堆栈。此外,我还尝试通过它的中断例程重新配置timer0,它可以工作。