【问题标题】:Accuracy of Timer1 as real time clock with PIC Interrupts on 16F*Timer1 作为实时时钟的精度,PIC 中断在 16F*
【发布时间】:2011-06-25 08:50:29
【问题描述】:

我使用 C 和 BoostC 编译器。我担心我的代码有多准确。下面的配置以或多或少的 1Hz 滴答作响,(用 LED 肉眼测试)。 (它为 16f74 上的 Timer1 使用了一个 32kHz 的外部手表晶体)。

希望有人能告诉我...

下面的代码是否需要任何调整?测量最近 CPU 时钟周期的精度的最简单方法是什么?我是否需要弄脏组装以可靠地确保 1Hz 信号的准确性?

希望执行定时器处理程序(和其他)所花费的时间甚至没有出现,因为定时器总是在计数。只要处理程序的执行时间永远不会超过 1/32kHz 秒,那么 1Hz 信号是否会具有 32kHz 晶体的精度?

谢谢

#define T1H_DEFAULT 0x80
#define T1L_DEFAULT 0
volatile char T1H = T1H_DEFAULT;
volatile char T1L = T1L_DEFAULT;

void main(void){

    // setup 
    tmr1h = T1H;
    tmr1l = T1L;
    t1con = 0b00001111; // — — T1CKPS1 T1CKPS0 T1OSCEN NOT_T1SYNC TMR1CS TMR1ON
    // ...

    // do nothing repeatedly while no interrupt
    while(1){}
}

interrupt(void) {

    // Handle Timer1
    if (test_bit(pir1, TMR1IF) & test_bit(pie1, TMR1IE)){

            // reset timer's 2x8 bit value
            tmr1h = T1H;
            tmr1l = T1L;

            // do things triggered by this time tick

            //reset T1 interrupt flag 
            clear_bit(pir1, TMR1IF);

    } else 

    ... handle other interrupts

}

【问题讨论】:

标签: c timer real-time pic microchip


【解决方案1】:

我可以看到一些改进...

您在中断中的计时器启动不准确。 当你在中断中设置定时器计数器时...

    tmr1h = T1H;
    tmr1l = T1L;

...然后您覆盖不利于准确性的当前值。 ...只需使用:

tmr1h = T1H;  //tmr1h  must be still 0!

或者更好,只需设置 tmr1h 寄存器的第 7 位。 编译器必须将此命令编译为单个 asm 指令,如...

bsf    tmr1h, 7

...避免丢失 tmr1 寄存器中的数据。因为如果这是用多条指令完成的,硬件可以在执行 read-modify-write 之间增加计数器值。

【讨论】:

  • 谢谢,我明白你在说什么,但由于定时器仅以 32kHz 递增,因此在写入计时器值会变脏吗?
  • 你没有告诉我们主CPU频率。如果 CPU 时钟是 4MHz,而指令周期是 1MHz,那么这只有 30 个指令时钟,并且中断延迟可能远远超过 30 个指令时钟,特别是在您处理更多不同的中断时。
  • 谢谢,抱歉,我知道这正在走向电子领域,但请您详细说明什么是中断延迟?仅仅是 ISR 代码执行吗?还是有某种额外的硬件延迟?
  • 当然有一些硬件延迟,但这只需要几个程序循环。主要问题是当程序执行另一个中断(如 UART 中断或任何其他中断)时是否发生 tmr1 溢出事件。在这种情况下,TMR1 溢出事件正在等待当前挂起的中断完成作业并再次打开中断。之后,将执行下一个由硬件优先级表等待的中断。当然在主要时间 tmr1 正在运行。因此,这种情况可能需要不可预测的 CPU 时钟数。
猜你喜欢
  • 2012-01-25
  • 1970-01-01
  • 2010-12-28
  • 2014-10-16
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
相关资源
最近更新 更多