I have a PIC24F Curiosity Board (PIC24FJ128GA204) and I'm trying to get an accurate second timing with the TIM1. As a source I'm using the secondary oscillator, which uses a 32678 kHz xtl.
The timer is configured with a 32 period, which corresponds to 1 ms
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;
}
So, every 1 ms the following interrupt is called, where the count of ms is stored on a uint32_t variable
void __attribute__ ( ( interrupt, no_auto_psv ) ) _T1Interrupt ( )
{
tmr1_obj.count++;
tmr1_obj.timerElapsed = true;
IFS0bits.T1IF = false;
}
In the main loop I do a busy wait on the tmr1_obj.count variable, and when it reaches 1000 a message is sent in 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;
}
On the other side of the UART I have an application that reads the message and logs the time when it was received and the difference in milliseconds with respect to the previous message.
The problem is that I have an accumulation of ~8ms for each message.
22:05.026 1008
22:06.035 1009
22:07.045 1010
22:08.054 1008
22:09.063 1008
Suspecting it could be something related to the UART transmission being often interrupted I tried to send the message every 10 seconds instead of 1. The delay was consistently accumulated to ~80ms each 10 seconds.
Finally, it could be that the 32 ticks do not correspond to 1 ms but to 1.x ms. To test that I changed the period to be 32768, that is, 1 second. I expected the results to be roughly the same, but they weren't
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
It seems that the period affects the accuracy of the timer. And I don't understand how. Could it be that for each interruption some microseconds were lost ? I don't see anything on the data sheet, but I can't find any other explanation.