Unit 4
Unit 4
LPC2148
System control block
Pin Description of System Control
Block
Cont…
System Control Registers
Cont..
System control block function PLL
Phase Locked Loop
• PLL is a closed loop system to generate high frequency
by multiplying with given factor to the input frequency.
• There are two PLL modules in the LPC2148
microcontroller.
• The PLL0 is used to generate the CCLK clock (system
clock) .
• The PLL1 has to supply the clock for the USB at the
fixed rate of 48 MHz.
• PLL interrupts are only available for PLL0 and not for
PLL1.
• Input clock to both the PLLs must be between 10Mhz
to 25Mhz strictly.
Cont….
• The input frequency is multiplied: 10 MHz to
60 MHz for the CCLK and 48 MHz for the USB
clock using CCO.
• The multiplier can be an integer value from 1 to
32.
• The CCO (current control oscillator) range- 156
MHz to 320 MHz, so there is an additional divider
in the loop to keep the CCO within its frequency
range while the PLL is providing the desired
output frequency.
Symbols
FOSC Frequency of the crystal oscillator
• The same concern is present with the PLL1 and the USB.
• Both PLLs are turned off and bypassed following a chip Reset
and when by entering Power-down mode.
• The program must configure and activate the PLL, wait for the
PLL to Lock, then connect to the PLL as a clock source.
PLLCON
PLLCFG
PLLSTAT
PLL Feed Register
PLLCON
PLL Interrupt
// This pgm for 60Mhz clk & 60Mhz pclk
void set_pll(void)
{
PLL0CON=0x01;
// PPLE=1 & PPLC=0 so it will be enabled but not connected after FEED
sequence
PLL0CFG=0x24;
// set the multipler to 5 (i.e actually 4) i.e 12x5 = 60 Mhz (M - 1 = 4), Set P=2 since
we want FCCO in range So , Assign PSEL =01 in PLL0CFG as per the table.
PLL0FEED=0XAA; //feed
PLL0FEED=0X55;
while((PLL0STAT&(1<<10))==0);
// check whether PLL has locked on to the desired freq by reading the lock bit in
the PPL0STAT register
PLL0CON=0x03;
//enable & connect pll
PLL0FEED=0XAA;
PLL0FEED=0X55;
VPBDIV = 0x01;
// PCLK is same as CCLK i.e 60Mhz
}
Timer
Features:
A 32-bit Timer/Counter with a programmable 32-bit
Prescaler.
Counter or Timer operation Timer/Counter0 and
Timer/Counter1 are functionally identical except for
the peripheral base address.
Four 32-bit capture channels/ timer
– Take a snapshot of the timer value when an input signal
transitions. Optionally generate an interrupt.
Four 32-bit match registers- allow:
o Continuous operation with optional interrupt
generation on match.
o Stop / Reset timer on match with optional interrupt
generation.
PCLK and VPDIV Register
• All of the timers are driven by PCLK which is
the Peripheral Clock. The system is generally
driven by the CCLK or Crystal Clock.
• PCLK is derived from CCLK which is the
processor clock.
• If CCLK = 60MHz, VPBDIV register determines
the rate of PCLK. VPBDIV is not the same as
the prescaler register although its action is
similar.
• VPBDIV is an 8-bit register and only the lower
two bits of it are used.
Cont..
Note:
PCLK goes into a prescaler which further scales
the clock going to the timer. The output of the
prescaler actually drives the timer register.
Timer
No of Timers : 2 (Timer 0 & Timer 1)
• The Timer/Counter is designed to count cycles
of the peripheral clock (PCLK) or externally-
supplied clock, and
• Can optionally generate interrupts or perform
other actions at specified timer values
Two timer/counters named Timer0 and Timer1.
Each timer has the following features:
• A 32-bit Timer/Counter with a programmable
32bit Prescaler.
• The prescaler allows the user to divide the
clock.
• Counter or Timer operation.
• Four 32-bit capture channels per timer that
take a snapshot of the timer value when an
input signal transitions.
• A capture event may also optionally generate
an interrupt.
Timer Register
1. PR : Prescale Register (32 bit) – Stores the maximum
value of Prescale counter after which it is reset.
2. PC : Prescale Counter Register (32 bit) – This register
increments on every PCLK(Peripheral clock).
a. This register controls the resolution of the timer.
b. When PC reaches the value in PR , PC is reset back to
0 and Timer Counter is incremented by 1.
c. If PR=9 then Timer Counter Increments on every 10th
cycle of PCLK. Hence by selecting an prescale value
we can control the resolution of the timer.
3. TC : Timer Counter Register (32 bit) – This is the main
counting register. Timer Counter increments when PC
reaches its maximum value as specified by PR.
Cont..
• For MR0:
– 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.
15:12
Timer Features
Four 32-bit match registers that allow:
• When the Timer starts – every time after TC is incremented the value
in TC is compared with match register.
Time Delay=(PR+1)(MR)/PCLK
PCLK=60MHz
• PR= Presale Register
• MR=Match Register
• PCLK= Peripheral Clock
Delay Generation Using Timers
Note:
}
//Blinking LED program using Timers for an efficient delay operation
#include<lpc214x.h>
/* Initialize the PLL0 and configure it to produce 60 MHz System Clock (CCLK) and Peripheral
Clock (PCLK) */
Void PLL(){
PLL0CON = 0x01;
PLL0CFG = 0x24;
PLL0FEED = 0xaa;
PLL0FEED = 0x55;
while (!(PLL0STAT & 0x00000400)); //while((PLL0STAT&(1<<10))==0);
PLL0CON = 0x03;
PLL0FEED = 0xaa;
PLL0FEED = 0x55;
VPBDIV = 0x01;
}
/* Function definition of delay function */
void timer()
{
T0CTCR=0X0000; //Timer Mode
T0PR=59; //Prescaler Value
T0MR0=1000000; //Match Register Value
T0MCR=0x04;
//TC and PC will be stopped and TCR[0] will be set to 0 if MR0
matches the TC.
T0TCR=0X02; //Reset Timer
T0TCR=0X01; //Timer ON
while(T0TC!=T0MR0);
T0TCR=0x0;
T0TC=0; //Timer OFF
}
int main()
{
PINSEL1=0x00;
/* Configure all pins of PORT 0 as outputs */
IO0DIR=0xFFFFFFFF;
PLL();
while (1)
0X00FF0000;
{ IO0SET=0xFFFFFFFF; // IO0SET |= (0xFF<<16)
timer();
0X00FF0000;
IO0CLR=0xFFFFFFFF; // IO0CLR |= (0xFF<<16)
timer();
}
}
PWM
Pulse Width Modulation (PWM) is a technique
by which width of a pulse is varied while keeping
the frequency constant.
LPC2148 supports two types of controlled PWM
outputs as,
7
Example 1
// Single Edge Control
// PWM channel 1 and PWM channel 2
• Let us set PWMMR0 as 150000(T=150000
PCLOCKS)
• PWMMR1=Ton=75000 PCLK// 50% Duty Cycle
• PWMMR2=Ton=100000 PCLK//66.66% Duty
cycle
Steps to program PWM
1. Select the PINSEL register according to which
PWM output pin is selected(PWM channel).
To select P0.0 PWM1, PINSEL[1:0]=10
P0.7 PWM2, PINSEL[15:14]=10
2. Configure TCR to enable the Counter for incrementing the TC,
TC and Prescale to reset, and Enable the PWM block.
• PWMPR=0
4. Configure MCR to reset the TC whenever it matches MR0.
X / (60 * 10^6).
• If the Prescale is considered, then X = PR + 1. So, when we consider
the Prescale value to be 59, then we get a delay of
int main()
{
PINSEL1=(0x04<<8); // pin P0.21 the channel 5 of PWM connect LED to this pin
while(1)
{
if( !((IO1PIN) & (1<<16)) ) // Check P1.16
{
PWMMR5 = 2500; //T-ON=25% , Hence 25% Bright
PWMLER = (1<<5) ; //Update Latch Enable bit for PWMMR5
}
else if( !((IO1PIN) & (1<<17)) ) // Check P1.17
{
PWMMR5 = 5000; //50% Bright
PWMLER = (1<<4);
} 5
}
}
void initPWM(void)
{
PINSEL0 = (PINSEL0 & ~(1 << 16)) | (1 << 17); // Select PWM4 output for Pin0.8
PWMPCR = 0x0; //Select Single Edge PWM - by default its single Edged so this line can be removed
PWMPR = 60-1; // 1 micro-second resolution
PWMMR0 = 10000; // 10ms period duration
PWMMR5 = 500; // 0.5ms - pulse duration i.e width (Brigtness level)
PWMMCR = (1<<1); // Reset PWMTC on PWMMR0 match
PWMLER = (1<<0)|(1<<5); // update MR0 and MR5
PWMPCR = (1<<13); // enable PWM output
PWMTCR = (1<<1) ; //Reset PWM TC & PR
PWMTCR = (1<<0) | (1<<3); // enable counters and PWM Mode
//PWM Generation goes active now - LED must be 25% Bright after boot!!Now you can get the PWM output at Pin P0.21!
}
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
}
Program
Write a Program to generate a double edge
controlled PWM on PWM3 (P0.1)
Watchdog Timer
Introduction
• Watchdog Timer (WDT) can be helpful to automatically reset the system
whenever a timeout occurs.
• System reset is required for preventing failure of the system in a situation
of a hardware fault or program error.
• There are countless applications where the system cannot afford to get
stuck at a point (not even for a small duration of time). For example, in a
radar system, if the system hangs for 5 minutes, it can result in serious
repercussions (an enemy plane or missile may go undetected resulting in
huge losses).
• The system should be robust enough to automatically detect the failures
quickly and reset itself in order to recover from the failures and function
normally without errors.
• One can manually reset the system to recover from errors. But it is not
always feasible to manually reset the system, especially once it has been
deployed.
• To overcome such problems, a watchdog timer is necessary to
automatically reset the system without human intervention.
Watchdog Timer
• A WDT is a hardware that contains a timing
device and clock source. A timing device is a
free-running timer, which is set to a certain
value that gets decremented continuously.
When the value reaches zero, a short pulse is
generated by WDT circuitry that resets and
restarts the system.
LPC2148 Watchdog Timer
LPC2148 has an inbuilt watchdog timer. The watchdog when
enabled generates a system reset if the user program fails to
feed (or reload) the watchdog within a predetermined amount
of time.
• The watchdog consists of a fixed divide by 4 prescalar and a 32-bit counter. The
clock is fed to the timer through the prescalar.
• The counter can be loaded with any value between 0xFF and 0xFFFFFFFF. If the
counter is loaded with any value less than 0xFF, the counter is initialized with a
value 0xFF.
• The watchdog needs to be fed with a pre-determined sequence of 0xAA followed
by 0x55 before watchdog timer underflows to prevent reset/interrupt.
Associated Registers
• WDMOD(watchdog mode register)
• WDTC(Timer Constant)
• WDFEED(Feed Register)
• WDTV(Timer value register)
Steps to program WDT
WDMOD Register
Cont..
This bit is set when the watchdog times out.It is cleared by software.
• Bit 3 – WDINT (Watchdog Interrupt Flag)
This bit is set when the watchdog times out. This bit is cleared when any reset
occurs. It is a read only bit
WDTC
WDFEED
WDTV
Block Diagram of WDT
Program
• Write an embedded C program to show the
operation of Watchdog timer by creating the
hanging of the system in the program.
Program
Steps given below:
• Set the watchdog timer constant reload value in the
WDTC register.
• Select the mode using the WDMOD register
• Start the watchdog by feeding it with 0xAA followed by
0x55 in the WDFEED register
• Make sure to feed the watchdog again before the timer
counter underflows in order to prevent reset/interrupt
• The Watchdog Time-Out Flag (WDTOF) can be
monitored to determine if the watchdog has caused
reset condition. The WDTOF flag must be cleared using
software.
Program
• Write an embedded C program to show the
operation of Watchdog timer by creating the
hanging of the system in the program.
Consider the watchdog time interval be
139ms. Indicate the reset of the system by
turning ON the LED connected to P0.16.
#include<lpc214x.h>
void delay(int x)
{
while(x--);
}
int main()
{
IO0DIR=(1<<16)|(0xF<<0);
if(WDMOD & 0x04)
{
IO0CLR=(1<<16);
IO0SET=(1<<16);
delay(500);
IO0CLR=(1<<16);
delay(500);
}
WDTC=0X000000ff;
WDMOD=0X00000003;
WDFEED=0X000000AA;
WDFEED=0X00000055;
while(1)
{
}
}
Vectored Interrupt Controller(VIC)
VIC LPC2148
Register in VIC
VICIntSelect (R/W)
VICIntEnable (R/W)
VICIntEnClr (R/W)
VICIRQStatus (Read)
VICFIQStatus (Read)
VICSoftInt
VICSoftIntClear
VICVectCntI0 to VICVectCntI15
Important Note
VICVectAddr0 to VICVectAddr15
VICVectAddr
program
• Write an embedded C program to blink LED’s
using timer0 interrupt.
#include <lpc214x.h>
void initClocks(void);
void initTimer0(void);
__irq void timer0ISR(void);
int main(void){
initClocks(); // Initialize PLL to setup clocks
initTimer0(); // Initialize Timer0
IO0DIR = (1<<10); // Configure pin P0.10 as Output
IO0PIN = (1<<10);
T0TCR = (1<<0); // Enable timer
while(1); // Infinite Idle Loop
}
void initTimer0(void)
{
T0CTCR = 0x0; //Set Timer Mode
T0PR = 60000-1; //Increment T0TC at every 60000 clock cycles //60000 clock cycles @60Mhz = 1 mS
T0MR0 = 500-1; //Zero Indexed Count-hence subtracting 1
T0MCR = (1<<0) | (1<<1);//Set bit0 & bit1 to Interrupt & Reset TC on MR0
VICVectAddr4 = (unsigned )timer0ISR; //Pointer Interrupt Function (ISR)
VICVectCntl4 = (1<<5) | 4; //(bit 5 = 1)->to enable Vectored IRQ slot //bit[4:0]) -> this the source number
VICIntEnable = (1<<4); // Enable timer0 interrupt
T0TCR = (1<<1); // Reset Timer
}
__irq void timer0ISR(void)
{
long int readVal;
readVal = T0IR; // Read current IR value
IO0PIN ^= (1<<10); // Toggle LED at Pin P0.10
T0IR = readVal; // Write back to IR to clear Interrupt Flag
VICVectAddr = 0x0; // End of interrupt execution
}
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
External Interrupts
Associated Registers
1. EXTMODE
2. EXTPLOLAR
3. EXTINT
Program
• Write an embedded C program to toggle LED’s
using external interrupt
#include<LPC2xx.h>
void Ext_Int()__irq
{
IO0SET|=(1<<17);
delay();
IO0CLR|=(1<<17);
delay();
EXTINT=0x01 //clear interrupt
VICVectAddr=0x00 // ISR execution completed
}
int main()
{
PINSEL1=0X01; // P0.16 EXTERNAL INTERRUPT 0
IO0DIR|=(1<<17);
EXTMODE=0X0; // LEVEL SENSITIVE
EXTPOLAR=0X01; // HIGH LEVEL SENSITIVE
VICVectCntI0=0x20 | 14 // 5th bit for enable interrupt
VICIntSelect=0x0; // IRQ interrupt
VICIntEnable=0x00004000 // Enable 14th pin for EXTINT0
while(1);
}