Anda di halaman 1dari 26

Timer Counter in ARM7(LPC2148)

By-
Aarav Soni
What is Timer ?

Timer is fully depend upon the oscillator that attached externally to the
microcontroller because it uses the frequency of oscillator to operate.
When we trigger timer it start from initial value and run up to decided
value stored by user in special function registers. When it reach its
maximum value, it overflows and a certain bit is decided to show over flow
in SFR(special function register) also called flag bit.
Some timers also used prescalar technique to enhance its limits.
Suppose a timer is of 8 bit so it can achieved up to = 256 (2^8)
for 16 bit so it can achieved up to = 65536 (2^16).
For 32 bit so it can achieved up to = 2^32.
Timer in LPC2148
The LPC2148 has two functionally identical general purpose timers:
Timer0 and Timer1.
Both Timer/Counter with a programmable 32-bit Prescaler.
Counter or Timer operation.
Up to four 32-bit capture channels per timer, that can take a snapshot of the
timer value when an input signal transitions. A capture event may also
optionally generate an interrupt.
Four 32-bit match registers that allow:
Continuous operation with optional interrupt generation on match.
Stop timer on match with optional interrupt generation.
Reset timer on match with optional interrupt generation
Up to four external outputs corresponding to match registers, with the
following capabilities:
Set low on match.
Set high on match.
Toggle on match.
Do nothing on match.
Capture Register: As the name suggests it is used to Capture Input signal.
When a transition event occurs on a Capture pin , it can be used to copy the
value of TC into any of the 4 Capture Register or to genreate an Interrupt.
Hence these can be also used to demodulated PWM signals.

Match Register:
A Match Register is a Register which contains a specific value set by the
user. When the Timer starts every time after TC is incremented the value in
TC is compared with match register. If it matches then it can Reset the Timer
or can generate an interrupt as defined by the user. We are only concerned
with match registers in this PPT.
How Timers in LPC2148 ARM7 Microcontroller
Works?

The heart of timers of the LPC2148 Microcontroller is a


32-bit free running counter, which is designed to count
cycles of the Peripheral Clock (PCLK) or an external
clock, this counter is programmable with 32-bit
prescaler.

Prescale Timer
PCLK Counter Counter
The tick rate of the Timer Counter (TC) is controlled by the 32-bit number
written in the Prescaler Register (PR) in the following way.

There is a Prescale Counter (PC) which increments on each tick of the


PCLK.

When it reaches the value in the Prescaler register, the timer count is
incremented and the Prescaler Counter (PC) is reset, on the next PCLK.

This cause the timer counters to increment on every PCLK when PR=0,
every 2 PCLKs when PR=1, etc.
The Match register values are continuously compared to the
Timer Counter value, when the two values are equal, actions
( Match pin / Interrupt ) can be triggered automatically
Timer Control Register (TCR, TIMER0:
T0TCR)

Timer Control register used to control the timer control functions. Well
enable, disable and reset Timer Counter (TC) through this register
Count Control Register (CTCR, TIMER0: T0CTCR)

The Count Control Register (CTCR) is used to select between


Timer and Counter mode, and in Counter mode to select the
pin and edge(s) for counting.
Timer Counter (TC, Timer0: T0CR):
This is the main counting register. Timer Counter increments when PC
reaches its maximum value as specified by PR. If timer is not reset
explicitly(directly) or by using an interrupt then it will act as a free running
counter which resets back to zero when it reaches its maximum value
which is 0xFFFFFFFF.
Prescale Register (PR, TIMER0: T0PR):
The 32-bit Prescale Register specifies the maximum value for the Prescale
Counter.
Prescale Counter Register (PC, TIMER0: T0PC):
This register increments on every PCLK(Peripheral clock). This register
controls the resolution of the timer. When PC reaches the value in PR , PC
is reset back to 0 and Timer Counter is incremented by 1.
Hence if PR=0 then Timer Counter Increments on every 1 PCLK. If PR=9
then Timer Counter Increments on every 10th cycle of PCLK. Hence by
selecting an appropriate prescale value we can control the resolution of the
timer.
Match Registers (MR0 - MR3):
The Match register values are continuously compared to the Timer Counter
value. When the two values are equal, actions can be triggered automatically.
The action possibilities are to generate an interrupt, reset the Timer Counter, or
stop the timer. Actions are controlled by the settings in the MCR register.
Match Control Register (MCR, TIMER0: T0MCR)
This register is used to control which all operations can be done when the value
in MR matches the value in TC. Bits 0,1,2 are for MR0 , Bits 3,4,5 for MR1
and so on.. Heres a quick table which shows the usage:
For MR0: (Match Register 0)
Bit 0 : Interrupt on MR0 i.e trigger an interrupt when MR0 matches TC.
Interrupts are enabled when set to 1 and disabled when set to 0.
Bit 1 : Reset on MR0. When set to 1 , TC will be reset when it matched MR0.
Disabled when set to 0.
Bit 2 : Stop on MR0. When set to 1 , TC & PC will stop when MR0 matches
TC.
Similarly bits 3-5 , 6-8 , 9-11 are for MR1 , MR2 , MR3 respectively.
Interrupt Register (IR, TIMER0: T0IR):
The Interrupt Register consists of four bits for the
match interrupts and four bits for the capture
interrupts.
How to calculate value of prescaler ?
Basic Step for Timer

Set appropriate value in TxCTCR


Define the Prescale value in TxPR
Set Value(s) in Match Register(s) if required
Set appropriate value in TxMCR if using Match registers / Interrupts
Reset Timer Which resets PR and TC
Set TxTCR to 0x01 to Enable the Timer when required
Reset TxTCR to 0x00 to Disable the Timer when required

Note: where x denote which timer we want to use.


Function for initializing timer0

void initTimer0(void)
{
/*Assuming that PLL0 has been setup with CCLK =
60Mhz and PCLK also = 60Mhz.*/
T0CTCR = 0x0; // Select timer
T0PR = 60000-1; //(Value in Decimal!) - Increment T0TC
at every 60000 clock cycle
//count begins from zero hence subtracting 1
//60000 clock cycles @60Mhz = 1 mS
T0TCR = 0x02; //Reset Timer
}
Function for generating delay

void delay(unsigned int milliseconds) // Using Timer0


{
T0TCR = 0x02; //Reset Timer
T0TCR = 0x01; //Enable timer
while(T0TC < milliseconds); //wait until timer counter
reaches the desired delay
T0TCR = 0x00; //Disable timer
}
Program for PLL

void initClocks(void)
{
PLL0CON = 0x01; //Enable PLL
PLL0CFG = 0x24; //Multiplier and divider setup
PLL0FEED = 0xAA;//Feed sequence
PLL0FEED = 0x55;
while(!(PLL0STAT & 0x00000400)); //is locked?
PLL0CON = 0x03; //Connect PLL after PLL is locked
PLL0FEED = 0xAA;//Feed sequence
PLL0FEED = 0x55;
VPBDIV = 0x01;// PCLK is same as CCLK i.e.60 MHz
}
Using interrupt method generating delay

#include <lpc214x.h>
#define MR0I (1<<0) //Interrupt When TC matches MR0
#define MR0R (1<<1) //Reset TC when TC matches MR0
#define DELAY_MS 500 //0.5 Seconds Delay
#define PRESCALE 60000 //60000 PCLK clock cycles to increment TC by 1
void delayMS(unsigned int milliseconds);
void initClocks(void); // PLL Function
void initTimer0(void);
__irq void T0ISR(void); //Interrupt function ISR
int main(void)
{
initClocks(); //Initialize CPU and Peripheral Clocks @ 60Mhz
initTimer0(); //Initialize Timer0
IO0DIR = 0xFFFFFFFF; //Configure all pins on Port 0 as Output
IO0PIN = 0xF;
T0TCR = 0x01; //Enable timer
while(1); //Infinite Idle Loop //return 0; //normally this wont
execute ever :P
}
void initTimer0(void)
{
//----------Configure Timer0-------------
T0CTCR = 0x0;
T0PR =60000; //Fosc= 60 Mhz
T0MR0 = DELAY_MS-1;
//(Value in Decimal!) Zero Indexed Count - hence subtracting 1
T0MCR = MR0I | MR0R; //Set bit0 & bit1 to High which is to :
Interrupt & Reset TC on MR0
//----------Setup Timer0 Interrupt-------------
VICVectAddr4 = (unsigned )T0ISR; //Pointer Interrupt Function (ISR)
VICVectCntl4 = 0x20 | 4; //0x20 (i.e bit5 = 1) -> to enable
Vectored IRQ slot //0x4 (bit[4:0]) -> this the source number -
here its timer0 which has VIC channel mask # as
VICIntEnable = 0x10; //Enable timer0 int
T0TCR = 0x02; //Reset Timer
}
__irq void T0ISR(void)
{
long int regVal;
regVal = T0IR; //Read current IR value
IO0PIN = ~IO0PIN; //Toggle the state of the Pins
T0IR = regVal; //Write back to IR to clear Interrupt Flag
VICVectAddr = 0x0; //This is to signal end of interrupt
execution
}
/* TOGGLE LEDS FROM P0.0 TO P0.15 WITH EXACT DELAY OF 3SEC */

#include<lpc21xx.h>
void delay(void);
int main()
{
VPBDIV=0X02; //30MHZ//
PINSEL0=0X00000000;
IODIR0=0X000000FF;
IOCLR0=0X000000FF;
while(1)
{
IOSET0=0X000000FF;
delay();
IOCLR0=0X000000FF;
delay();
}
}
void delay(void)
{
T0PR=30000;
T0MR0=3000;
T0TC=0x00000000;
T0TCR=0X01; //START TIMER//
while(T0TC !=T0MR0); //1 SEC//
T0TCR=0X02; //STOP TIMER/
}
/* TOGGLE LEDS FROM P0.0 TO P0.7 WITH EXACT DELAY OF 2 SEC BY
USING T0MR3.TOGGLE LEDS FROM P0.15 TO P0.23 WITH EXACT
DELAY OF 5 SEC BY USING T1MR2. */

#include<lpc21xx.h>
void delay1(void);
void delay2(void);
int main()
{
VPBDIV=0X02; //30MHZ//
PINSEL0=0X00000000;
IODIR0=0X00FF00FF;
IOCLR0=0X00FF00FF;
while(1)
{
IOSET0=0X00FF00FF;
delay1();
IOCLR0=0X00FF00FF;
delay2();
}
}
void delay1(void)
{
T0PR=30000;
T0MR0=1000;
T0TC=0x00000000;
T0TCR=0X01; //START TIMER//
while(T0TC !=T0MR0); //1 SEC//
T0TCR=0X02; //STOP TIMER/
}
void delay2(void)
{
T1PR=30000;
T1MR2=2000;
T1TC=0x00000000;
T1TCR=0X01; //START TIMER//
while(T1TC !=T1MR2); //2 SEC//
T1TCR=0X02; //STOP TIMER//
}

Thanks

For any suggestion,


Please contact me on-
Mail id- a.soniarav@gmail.com
Facebook- https:www.facebook.com/arav.soni.98
Twitter- https://twitter.com/AaravSoni1