我有一个 PIC24F Curiosity Board (PIC24FJ128GA204),我正在尝试使用 TIM1 获得准确的第二次计时。作为源,我使用的是辅助振荡器,它使用 32678 kHz xtl。
定时器配置了32个周期,对应1毫秒
void TMR1_Initialize (void)
{
//TMR1 0;
TMR1 = 0x0000;
//Period = 0.001 s; Frequency = 32000 Hz; PR1 32;
PR1 = 0x0020;
//TCKPS 1:1; TON enabled; TSIDL disabled; TCS External; TECS SOSC; TSYNC enabled; TGATE disabled;
T1CON = 0x8006;
IFS0bits.T1IF = false;
IEC0bits.T1IE = true;
tmr1_obj.timerElapsed = false;
}
因此,每 1 ms 调用一次以下中断,其中 ms 的计数存储在 uint32_t 变量中
void __attribute__ ( ( interrupt, no_auto_psv ) ) _T1Interrupt ( )
{
tmr1_obj.count++;
tmr1_obj.timerElapsed = true;
IFS0bits.T1IF = false;
}
在主循环中,我对 tmr1_obj.count 变量进行了繁忙的等待,当它达到 1000 时,在 UART 中发送一条消息。
int main(void)
{
// initialize the device
SYSTEM_Initialize();
TMR1_Start();
char msg[] = "A\r\n";
while (1)
{
// Add your application code
int value = TMR1_SoftwareCounterGet();
if (value == 1000) {
printf("%s", msg);
TMR1_SoftwareCounterClear();
}
}
return -1;
}
在 UART 的另一端,我有一个应用程序,它读取消息并记录收到消息的时间以及相对于前一条消息的毫秒差异。
问题是我为每条消息累积了约 8 毫秒。
22:05.026 1008
22:06.035 1009
22:07.045 1010
22:08.054 1008
22:09.063 1008
怀疑它可能与 UART 传输经常中断有关,我尝试每 10 秒而不是 1 秒发送一次消息。延迟一直累积到每 10 秒约 80 毫秒。
最后,32 个滴答声可能不对应于 1 毫秒,而是对应于 1.x 毫秒。为了测试我把周期改成了32768,也就是1秒。我预计结果大致相同,但事实并非如此
31:15.216 999
31:16.216 999
31:17.216 1000
31:18.216 999
31:19.216 999
31:20.215 999
31:21.216 1000
似乎周期会影响计时器的准确性。我不明白怎么做。是不是每次中断都会丢失一些微秒?我在数据表上没有看到任何内容,但我找不到任何其他解释。