Timer 16/32 bit wrong counting

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by member_lpc11xx on Tue Mar 03 09:13:51 MST 2015
Hello everybody,

I get this issue with timer peripheral counting.

I’m using a LPC1112FD20, with the IRC oscillator as clock reference, by-passing the PLL. So I’ve a Main Clock running at 12MHz, SYSAHBCLKDIV=3 therefore a System Clock of 4MHz.
I also set the 16 bit timer TMR16B0 to generate an output pwm, with timer peripheral base clock running at 1MHz, square wave period of  1ms and variable duty cycle 50%. Here is the code:

               LPC_SYSCON ->SYSAHBCLKCTRL |= CT16B0_CLK_ENABLE;                        
               LPC_TMR16B0 ->PR = (SYSTEM_CORE_CLOCK() / 1000000);           //    Base time of the timer: 1us                       
               LPC_TMR16B0 ->MR3 = 1000;                                                                //    PWM period:                 1ms      -->>      f = 1KHz
               LPC_TMR16B0 ->MCR = (1 << 10);                                                         
               LPC_TMR16B0 ->PWMC = (1 << 1);                                                       
               LPC_TMR16B0 ->MR1 = 500;                                                   //    Default PWM: 50%                                                            
               LPC_TMR16B0 ->TC = 0;                                                             
               LPC_TMR16B0 ->TCR = TCR_TIMER_ENABLE;

[u]The issue is that measuring the output square wave with a scope, I get different frequency from the nominal one: 802Hz instead of 1KHz.[/u] Duty cycle is right: 50%.

So, I started making some tests: keeping the same system clock source and configuration, changing the base time of the timer (modifying the prescale to make TMR16B0 working at different frequencies) I get these results:

     Base time of the timer:                10us      (f = 100KHz)                                                 Output PWM frequency:         968 Hz
     Base time of the timer:                20us      (f = 50KHz)                                                   Output PWM frequency:         970 Hz
     Base time of the timer:                100us    (f = 10KHz)                            Output PWM frequency:      909 Hz                                  

RESULT: pwm frequency changes if timer frequency change.

After that, I’ve tried to change the System Clock: SYSAHBCLKDIV register is now setted to 1, so that System Clock is equal to Main Clock: 12MHz (my doubt was that maybe the core frequency was too slow to execute assembly instruction of generating a pwm).
TMR16B0 configuration is the same as in the code above: in this way, core clock is 12 times faster than timer clock (so there will not be problem about instruction execution time). What I find is this:

     System Clock:                                   12MHz                                                                           Output PWM frequency:         920 Hz

RESULT: also changing System Clock (3 times faster) I’m unable to reach 1KHz as pwm frequency.

What I’ve done now is to change pwm period, from 1KHz to 2 and 4KHz. Following what I get:

Pwm frequency setted:               2KHz                                                                               Output PWM frequency:         1.59 KHz
Pwm frequency setted:              4KHz                                                                               Output PWM frequency:         3.21 KHz

RESULT: measured output pwm frequency is wrong, but is proportional with setted frequency (1.59KHz is 2 times 802Hz, 3.21KHz is 4 times 802Hz)

Now, my doubt is Main Clock doesn’t work in the right way, clocking a signal with a wrong frequency. To check this I set a GPIO as output pin and toggling it every time a SysTick interrupt occurs. SysTick in configured so that it runs at 1 KHz.
The measured square wave I get toggling this pin has a frequency of 501Hz, therefore the System Tick Timer is working at a frequency of  2*501 = 1002 Hz, like I expect.

RESULT: Main Clock seems to work correctly

I’ve changed also the clock generation register, so that the PLL is now used with an output frequency equal to the input one: it could be IRC frequency is not well synchronized and PLL could improve precision.

RESULT: No difference. PWM output frequency always equal to  ≈800Hz

As last test, I would like to clockout the Main Clock (running at 12MHz) but I’m unable to make it working: I’m pretty sure the pin configuration and CLKOUT register are setted in the right way, but I can’t see any significant square wave on pin 0.1.
I’ve tried making the same attempts with the 32 bit timer TMR32B0, but same results. I’ve just done other few tests to find out problem with timing precision. This time I’ve used LPC-Link as demo board for trials, with a LPC1114FBD48/302 mounted on it. What I could see is substantially the same result as previous: pwm frequency (generated by the 16 bit timer peripheral) accuracy depends on core working frequency.
Conclusion: I think it’s a  timer  peripheral problem.

I have searched on the website, and in particular on the LPCWare forum, if other people has got the same issue, but no interesting thread were found. So I would like to know if you have yet a solution for this problem or if you know which is the reason/cause of this wrong behaviour.

Thanks to all of you who can help me