LPC2148 timer not quite running in real time

Hello!

I am running a custom built board based around a LPC2148 MCU. This board is being used for real time control applications and, in order to achieve what I hoped would be precise timing, I have set up timer0 to generate an interrupt when it matches MR0 which has been loaded with the desired time. All of this works, however, over a 120 second run, I clocked 127 seconds using a stop watch.

I am using a 12 Mhz crystal with a PLL multiplier of 5 resulting in an internal clock of 60 Mhz. Since this loop only runs at 4 Hz, my match register is loaded with:

60000000/4 = 15000000

Anyone have any idea why this would run a tad slow? The ISR code that gets executed each second is quite simple so I don’t think it’s struggling to finish execution within 250 ms.

By the way, I ordered a single version of this board from BatchPCB and, exactly one month later, I received three at no extra charge. Thank you BatchPCB!

Do you perhaps have the timer configured to halt when the match occurs? The delay between the interrupt occurring, and you restarting the timer in the ISR, would explain the slow timing. You want the timer to either reset itself on match, or continue running (in which case you’d add 15,000,000 to the match register value each time to prepare it for the next interrupt).

I’ll have to look in to this. As of now it is set up as follows:

VICIntEnable = BIT4; // Enable interrupt for Timer0

T0MR0 = 15000000; // Match register, 0.25 seconds

T0MCR = BIT0; // Interrupt on TC=MR0

T0TCR = BIT0; // Start the timer

Then we enter the main loop and wait for the interrupt. In the ISR, the first lines are:

// Reset interrupt

T0IR = 0x01;

// Reset Timer

BITSET(T0TCR,1);

BITCLR(T0TCR,1);

where BITSET and BITCLR are macros to do the obvious. The last line is:

VICVectAddr = 0; // Acknowledge Interrupt

Would it matter than I am using the default interrupt location, i.e. VICDefVectAddr = ISR? This is the only interrupt for the system and this was the simplest to set set up.

Thanks for the quick reply.

If you reset the timer in the ISR, an unknown number of clock cycles later than the actual match condition, you can’t possibly get accurate timing. Set T0MCR so that the reset is automatically done when the match occurs, and NEVER touch the timer itself afterwards.

Thank you very much for the suggestion. I need to run to dinner but I will try this post-Mexican and report the results. Thanks again for your help!

Also verify whether you need to set the match register to 15000000 or to 15000000 - 1 (I think the latter, but better be sure and check the user manual). This wouldn’t explain a 7 second difference on a 120 second test run of course.