【问题标题】:Reconfigure timer during timer interrupt interrupt 8051定时器中断中断期间重新配置定时器 8051
【发布时间】:2013-09-24 11:00:01
【问题描述】:

我正在使用 SDCC 编译器。

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

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

以下是问题:

  1. 在 Timer0 自己的中断处理程序执行期间,是否可以在模式 2 自动重载模式下为 Timer0 重新配置 TL0 和 TH0?

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

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

【问题讨论】:

  • 我查看了 sdcc 编译 C 代码后生成的 HEX 文件,似乎在执行任何中断例程之前 TH0 和 TL0 没有被压入堆栈。
  • 另外,我尝试通过它的中断例程重新配置 timer0 并且它可以工作。

标签: c timer interrupt 8051 sdcc


【解决方案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,您不必担心堆栈或任何其他函数参数传递机制会干扰它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    • 2020-08-04
    • 2018-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多