So today we are going to discuss about timers. LPC2148 have two 32bit timers. By 32 bit I mean it’s registers are 32bit wide. In other controllers it could be 8 or 16 bit also.
Timing is very important part of a microcontroller programming. We certainly can not depend on delay functions because no matter how precise they are, they are not accurate. For eg- DHT11, a temperature sensor, works only if we give it specific pulses for specific amount of time(in microseconds and milliseconds).We will learn about it later in the blog. But for now we will use timer for controlling blinking of LED with different time interval.
Before going to the program, let’s go through some important registers we are going to use in timer.
[vc_message message_box_style=”3d” message_box_color=”sandy_brown” icon_fontawesome=”fa fa-first-order”]
TCR- Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR.
TC- Timer Counter. The 32-bit TC is incremented every PR+1 cycles of PCLK(Peripheral Clock). The TC is controlled through the TCR. We will set the delay required here.
PR- Prescale Register. The Prescale Counter (below) is equal to this value, the next clock increments the TC and clears the PC.
PC- Prescale Counter. The 32-bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface.
CTCR- Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting. We are mostly going to use timer mode.[/vc_message]
That’s it regarding registers. One important thing before we go to main programming section, as I mentioned that I have 12 MHz oscillator providing clk input but LPC2148 have capability to reach upto 60MHz. So through some PLLs (Phase Locked Loops) setting, I set my PCLK (Peripheral clock) to 60 MHz and than divide it accordingly.
[vc_message message_box_style=”3d” message_box_color=”chino” icon_fontawesome=”fa fa-first-order”]
1. Enable in timer mode by writing 0 (clearing bits) to bit 0 and 1 of TxTCR register.
2. Set the Prescale value in TxPR. This is very important as this will decide your delay interval.
formula used to get prescale value is
Let’s say I want the delay of 1ms and I have pclk of 15MHz so according to the formula,
void timer_init (void);
void timer0 (uint32_t count);
int main ()
PINSEL0=0; // setting normal GPIO functions
IODIR0|=(1<<16); // pin 0.16 as o/p
pll_init (); // initialise clocks
VPBDIV=0x00; // pclk=cclk/4=15MHz
timer_init (); //initialise timer 0
IOSET0=(1<<16); // led on
timer0 (500); //wait for 500ms
IOCLR0=(1<<16); //led off
timer0 (500); // wait for 500ms
void timer_init (void) // timer 0 initialisation
T0CTCR=0x00; // start in timer mode
T0PR= ((15000000/1000)-1); // formula is COUNT=(P.F X TIME DELAY IN SEC) - 1 and pclk=cclk/4 for us
T0TCR=(1<<1); // reset timer
void timer0 (uint32_t count)
T0TC=0; // set 0 to TC counter
T0TCR=(1<<1); //reset timer
T0TCR=(1<<0); // enable timer
while (T0TC<count); // wait untill TC counter reaches our defined value
T0TCR=0x00; // disable timer
PLL0CON = 0x01; //Enable PLL
PLL0CFG = 0x24; //Multiplier and divider setup M is (5-1=4) because we need 60 Mhz and we have 12 so 5 is multiplier. P is 2. so 0x24.
PLL0FEED = 0xAA; //Feed sequence
PLL0FEED = 0x55; // feed sequence
while(!(PLL0STAT & 0x00000400)); //is locked?
PLL0CON = 0x03; //Connect PLL after PLL is locked
PLL0FEED = 0xAA; //Feed sequence
PLL0FEED = 0x55; //Feed sequence
/* Control Pclk using VPBDIV register
VPBDIV=0x00 APB bus clock (PCLK) is one fourth of the processor clock (CCLK)
VPBDIV=0x01 APB bus clock (PCLK) is the same as the processor clock (CCLK)
VPBDIV=0x02 APB bus clock (PCLK) is one half of the processor clock (CCLK)
VPBDIV=0x03 Reserved. If this value is written to the APBDIV register, it has no effect (the previous setting is retained). */
NOTE: Here PC will increment and it will reach PR in 1ms and TC will increment by 1. This will keep going on for 500 times and we will get a delay of 500ms.
LED should be blinking every 500ms now.
In the same way if you want the delay of 1 second, formula will be COUNT=(15000000 *1)-1).
Check out this video for full tutorial and result