0% found this document useful (0 votes)
176 views122 pages

Unit III AP Part 1 Interfacing

The document discusses interfacing various devices with an ARM7 microcontroller including interfacing LEDs by controlling GPIO pins, interfacing a 16x2 LCD to display text by sending command and data signals, and interfacing a 4x4 keypad to read button presses and send input signals to the microcontroller. Code examples and diagrams are provided to illustrate the interfacing of each device.

Uploaded by

Makrand Kakatkar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
176 views122 pages

Unit III AP Part 1 Interfacing

The document discusses interfacing various devices with an ARM7 microcontroller including interfacing LEDs by controlling GPIO pins, interfacing a 16x2 LCD to display text by sending command and data signals, and interfacing a 4x4 keypad to read button presses and send input signals to the microcontroller. Code examples and diagrams are provided to illustrate the interfacing of each device.

Uploaded by

Makrand Kakatkar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 122

UNIT III

Unit III : Real World Interfacing with ARM7 Based


Microcontroller -1
1. Interrupt structure of LPC2148

2. Interfacing with LED, LCD, GLCD, KEYPAD


3. Simple LPC2148 GPIO Programming
examples
4. Using timers of LPC2148 to generate delay
5. serial communication programming for transmission and reception from
computer,
6. programming for UART.
1.A Interfacing with LEDs

Introduction
 Current passing through the LED should be
limited to maximum forward current (IF).
 To find the value of this resistor, we use the
forward voltage and forward current.
We design a circuit with 5V supply and forward
current of 20mA. We use a red LED here.
R = (5 – 2)/10mA = 300 ohms(Use 270 ohms)

2
1.A Interfacing with LEDs
LED pin connections & interfacing diagram

3
1.A Interfacing with LEDs
ALGORITHM Flowchart
1. Initialize the ports of LPC 2148.
2. Make the port lines high to glow LED.
3. Call delay.
4. Make the port lines low to glow LED off.
5. Call delay.
6. Go to step 2.

4
1.A Embedded C code for LED Interfacing
#include<lpc21xx.h> // header file

void delay_led(void) // delay function


{
unsigned int j;
for(j=0;j<1000000;j++);
return;
}

int main (void)


{
IODIR0 = 0x000FF000; /* Define direction of port 0 as (output) I/O pins */
while (1) /* Loop forever */
{
IOSET0=0x000FF000; /* turn LEDs ON */
delay_led(); /* Call Delay */
IOCLR0=0x00FF0000; /* turn LEDs OFF */
delay_led(); /* Call Delay */
}
}
5
1.B 16 X 2 LCD Interfacing
Introduction
 LCD16x2 has two lines with 16 character in each line.
 LCD16x2 generally used for displaying parameter values and string in
embedded application.
 LCD 16x2 is 2 lines, 16 characters with each character having 5x8
pixel matrix

Most of the 16x2 LCDs


use a Hitachi HD44780
or a compatible
controller.

LCD16x2 6
1.B 16 X 2 LCD Interfacing

7
1.B 16 X 2 LCD Interfacing
LCD Commands

While interfacing LCD16x2 with any

controller, firstly we need to initialize

LCD16x2.

For that we need to send some commands.

Also to clear display or for changing position

we need to send commands.

So basically we can say that LCD16x2 can be

controlled by using commands

8
1.B 16 X 2 LCD Interfacing
LCD Interfacing Details
16x2 LCD
Description Signal
EN W/R
LCD LPC21xx
D0 ~D7 RS

LCD D0 P0.12
LCD D1 P0.13
P0.12
LCD D2 P0.14
P0.19 LCD D3 P0.15
LCD D4 P0.16
P1.20
LCD D5 P0.17
P1.21 LCD D6 P0.18
LCD D7 P0.19
LPC 2148 LCD RS P1.20
Fig.- Interfacing of LPC-2148 with 16x2 LCD LCD EN P1.21 9
Timing Diagram

Command Data Mode


Mode

• RS=0 • RS=1
• Command • Data
• En=1 • En=1
• DELAY • DELAY
• EN=0 • En=0

The R/w input allows the user to read or write


The RS pin is used to select one of these registers. information to LCD.
 RS (Register Select): If ‘1’, data register is selected.  R/W (Read/write): while reading ,R/W=’1’.
10
If ‘0’, command register is selected. while writing, R/W=’0’.
Algorithm for interfacing 16 X 2 LCD
1. Define an array in which data on lcd is to be 6. For data function
writtenchar array[]="SCOE PUNE"; a. clear all data lines D0 to D7
2. Use PINSEL 0,1,2 for GPIO. Set pins P0.12 b. RS=1
(D0) to P0.19(D7) to output for sending data or c. EN = 1
command to LCD using IODIR0 d. Delay
e. Send Data lcddata
3. Set pins P1.20 (RS) to P1.21(EN) to output for
f. Delay
sending data or command to LCD using IODIR1
g. EN = 0
4. For command function h. delay
a. clear all data lines D0 to D7 7. In main function
b. RS=0 a. Initialize pins P0.12 to P0.19 and P1.21
c. EN = 1 lcdcmd & P1.20 as output
d. Delay b. Call commands to initialize lcd
e. Send Commands c. Send cmd 0x80 (to send data on 1st
f. Delay line) or 0xC0 (to send data on 2nd line)
g. EN = 0 d. To display data use:
h. delay for(i=0;i<4;i++) { //for(i=5;i<9;i++)
5. Initialize LCD by sending command as below
i. Cmd 0x38, 8 bit mode; 2 lines lcddata(array[i]);
ii. Cmd 0x06, entry mode (increment cursor) delay(1000);
iii. Cmd 0x0C, display ON cursor OFF }
iv. Cmd 0x01 ,clear display 11
12
#include<lpc21xx.h> void lcddata(unsigned int data ) lcdcmd(0x01);
unsigned char array[]="SCOE PUNE"; { delay(100);
unsigned int i=0; IOCLR0=0x000ff000; lcdcmd(0x0e);
void lcdcmd(unsigned int cmd); IOSET1 = 1<<20;
void lcddata(unsigned int data);
delay(100);
IOSET1 = 1<<21;
void delay(unsigned int itime); delay(100);
lcdcmd(0x80); Display
IOSET0 = ch<<data;
void delay(unsigned int itime) delay(100); SCOE on 1st line
delay(100);
{ IOCLR1 = 1<<21; for(i=0;i<4;i++)
int i,j; delay(100); Data {
for(i=0;i<itime;i++) } Function lcddata(array[i]);
for(j=0;j<200;j++); Delay
Function delay(1000);
}
int main() }
GPIO
{ lcdcmd(0xc0); Display
void lcdcmd(unsigned int cmd ) Mode
{ PINSEL0=0X00000000; delay(100); PUNE on 2nd line
IOCLR0=0x000ff000; PINSEL1=0X00000000; for(i=5;i<9;i++)
IOCLR1 = 1<<20; // RS =0 PINSEL2=0X00000000; {
IOSET1 = 1<<21; // EN =1 IODIR0=0X000FF000; Set pin lcddata(array[i]);
as o/p
delay(100); IODIR1=0X00300000; delay(1000);
IOSET0 = ch<<cmd; // send cmd lcdcmd(0x38); }
delay(100); delay(100); return 0;
IOCLR1 = 1<<21; // EN = 0 Initialize
lcdcmd(0x06); LCD }
delay(100);
Command delay(100);
}
Function
13
/* LCD: RS---P1.20, EN---P1.21 and Data—P0.12 to P0.19 */
1.C 4 X 4 Keypad Interfacing: Introduction
Interfacing with KEYPAD
 Switch is the most widely used input device.
 When a switch is pressed either low or high signal is given to
controller depending upon the circuit designing.
 This approach requires one pin for a single switch.
 With increasing requirement of input devices, more numbers of
controller pins are required which may not be available all the
time.
 To reduce number of required pins, we can arrange keys in matrix
form.
 In matrix keypad, keys are connected in rows and columns.
 When any switch is pressed, rows and columns come into contact
which is detected by controller to identify which key has been
pressed. 14
1.C 4 X 4 Keypad Interfacing: Algorithm
For identify the pressed key, we have to follow given procedure.
1. Set output port (Rows) and input port (Columns).
2. Ground first row and set rest of the rows.
3. Read input port, if all are 1s, no switch in that row is pressed. Whenever any key
is pressed, one of the input pin will be grounded by pressed key. By reading input
pins, we can identify the column in which key has been pressed.
4. Now ground second row and set all others rows at logic 1 and see whether any
key has been pressed in that row or not. Continue same process until you find out
in which row, key is pressed.
5. Once we know column and row in which key has been pressed, we can identify the
pressed key easily.
15
1.C 4 X 4 Keypad Interfacing: Scanning &
Identifying Key

16
1.C 4 X 4 Keypad Interfacing: Grounding &
Reading Columns

17
1.C 4 X 4 Keypad Interfacing: Grounding &
Reading Columns .. cont

18
/* Keypad Connection:
P0.2,P0.3,P0.4,P0.5 ---Col---Read Lines
P0.6,P0.7,P0.8,P0.9 ---Row---Scan Lines
LCD: RS---P0.28; EN---P0.29
Data--P1.16 to P1.23 */ 19
1.C 4 X 4 Keypad Interfacing: Code
#include<lpc21xx.h> IO0PIN=0x00000380; // First Scan Line(row),
void lcdcmd(unsigned int);
//R1=0,R2=R3=R4=1
void lcddata(unsigned int);
void delay_lcd(void); if(( IO0PIN & 0x0000003C)!= 0x0000003C))
int main(void) {

{ while(1) switch(IO0PIN & 0x0000003C) // ALL COLUMN =>1

{ // set P1.16~P1.23 AS O/P dir {


case 0x00000038 : lcddata(“C");break; // 1110
IODIR1=0x00ff0000;
case 0x00000034 : lcddata(“D");break; //1101
// set P0.2~P0.9 & P0.28 & P0.29 AS O/P dir
case 0x0000002C : lcddata(“E");break; //1011
IODIR0=0x300003c0; // ROW AS O/P dir
case 0x0000001C : lcddata(“F");break; //0111
lcdcmd(0x38);
lcdcmd(0x0e); }
lcdcmd(0x01); } /* Keypad Connection:
lcdcmd(0x06); P0.2,P0.3,P0.4,P0.5 ---Col---Read Lines
lcdcmd(0x83); P0.6,P0.7,P0.8,P0.9 ---Row---Scan Lines
lcdcmd(0xC0); LCD: RS---P0.28; EN---P0.29
Data--P1.16 to P1.23 */ 20
1.C 4 X 4 Keypad Interfacing: Code

IO0PIN=0x0000340;// Second Scan Line(row) IO0PIN=0x000002c0;// Third Scan Line(row)


//R2=0,R1=R3=R4=1 //R3=0,R1=R2=R4=1
if(( IO0PIN & 0x0000003C)!= 0x0000003C) ) if(( IO0PIN & 0x0000003c )!= 0x0000003c)
{ {
switch(IO0PIN & 0x0000003C) switch(IO0PIN & 0x0000003c)
{ {
case 0x00000038 : lcddata(“8");break; case 0x00000038 : lcddata("4");break;
case 0x00000034 : lcddata(“9");break; case 0x00000034 : lcddata("5");break;
case 0x0000002c : lcddata(“A");break; case 0x0000002c : lcddata("6");break;
case 0x0000001c : lcddata(“B”);break; case 0x0000001c : lcddata("7");break;
} }
} }
21
IO0PIN=0x000001c0; // Four Scan Line(row) void lcdcmd(unsigned int cmddata) void lcddata(unsigned int outdata)
//R4=0,R1=R2=R3=1 { {
if(( IO0PIN & 0x0000003c )!= 0x0000003c) IOCLR1=0x00ff0000; IOCLR1=0x00ff0000;

{ IOCLR0=0x10000000; IOSET0=0x10000000;

switch(IO0PIN & 0x0000003c) cmddata=cmddata<<16; outdata=outdata<<16;


IOSET1=cmddata; IOSET1=outdata;
{
IOSET0=0x20000000; IOSET0=0x20000000;
case 0x00000038 : lcddata("0");break;
delay_lcd(); delay_lcd();
case 0x00000034 : lcddata("1");break;
IOCLR0=0x20000000; IOCLR0=0x20000000;
case 0x0000002c : lcddata("2");break;
delay_lcd(); delay_lcd();
case 0x0000001c : lcddata("3");break;
return; return;
}
} }
}
delay_lcd(); void delay_lcd(void)
} {
} int j;
for(j=0;j<10000;j++);
return;
}

22
Keypad(4x3)and LCD interfacing with ARM7 (1)

 The design uses a 4×3 keypad


to take input and a 16×2 LCD
to display the input value fed
by the keypad
 Making the rows of the
keypad as input and column as
output or vice versa.
 In this method each row will
be made low one at a time and
the corresponding logic
transition in column value will
be monitored by the
Microcontroller.

23
Keypad(4x3)and LCD interfacing with ARM7 (2)

#include<lpc21xx.h> void lcd(unsigned char a,int b) //LCD Subroutine


void delay(void); {
void lcd(unsigned char,int b); IOSET0=a<<0;
char keypad(void); IOSET0=b<<8;
char c; IOSET0=1<<9;
int main(void) delay();
{ IOCLR0=1<<9;
PINSEL0=PINSEL2=0; IOCLR0=b<<8;
IODIR0=0x000003ff; IOCLR0=a<<0;
IODIR1=0x00780000; }
lcd(0x38,0);
lcd(0x0f,0); void delay(void) //Delay loop
while(1) {
{ unsigned int i;
c=keypad(); //Obtaining values from keypad for(i=0;i<=20000;i++);
lcd(c,1); }
}
}

24
Keypad(4x3)and LCD interfacing with ARM7 (3)
char keypad(void) //Keypad Scan
{ IOCLR1|=(1<<20);
while(1) IOSET1|=(1<<21)|(1<<22)|(1<<19);
{ if(!(IOPIN1&(1<<16)))
IOCLR1|=(1<<19); //Making row1 LOW {
IOSET1|=(1<<20)|(1<<21)|(1<<22); //Making rest of the while(!(IOPIN1&(1<<16)));
rows '1' return '4';
if(!(IOPIN1&(1<<16))) //Scan for key press }
{ if(!(IOPIN1&(1<<17)))
while(!(IOPIN1&(1<<16))); {
return '1'; //Returning value to display while(!(IOPIN1&(1<<17)));
} return '5';
if(!(IOPIN1&(1<<17))) }
{ if(!(IOPIN1&(1<<18)))
while(!(IOPIN1&(1<<17))); {
return '2'; while(!(IOPIN1&(1<<18)));
} return '6';
if(!(IOPIN1&(1<<18))) }
{
while(!(IOPIN1&(1<<18)));
return '3';
} 25
Keypad(4x3)and LCD interfacing with ARM7 (4)

IOCLR1|=(1<<21); IOCLR1|=(1<<22);
IOSET1|=(1<<22)|(1<<20)|(1<<19); IOSET1|=(1<<19)|(1<<20)|(1<<21);
if(!(IOPIN1&(1<<16))) if(!(IOPIN1&(1<<16)))
{ {
while(!(IOPIN1&(1<<16))); while(!(IOPIN1&(1<<16)));
return '7'; return '*';
} }
if(!(IOPIN1&(1<<17))) if(!(IOPIN1&(1<<17)))
{ {
while(!(IOPIN1&(1<<17))); while(!(IOPIN1&(1<<17)));
return '8'; return '0';
} }
if(!(IOPIN1&(1<<18))) if(!(IOPIN1&(1<<18)))
{ {
while(!(IOPIN1&(1<<18))); while(!(IOPIN1&(1<<18)));
return '9'; return '#';
} }
}
} 26
Interfacing KS0108 based JHD12864E Graphics LCD
• There are many displays out there based on KS0108 or compatible

display controller.
• We will look at the working of the display, the hardware setup and
programming with ARM7 (LPC2148).

• Unlike a 16 x 2 display, this does not have a character map for

ASCII values stored on its ROM.

• However it allows us the flexibility of creating fonts like Arial, times

new roman etc.

• We could also display bit-map images on it and stretching it little

further we can make GUI's and little animation.


27
Features of JHD12864E LCD Module

28
Internal block diagram of a KS0108B
(NT7108C) based 128x64 pixel GLCD module

29
Internal block diagram of a KS0108B
(NT7108C) based 128x64 pixel GLCD module

30
Explanation
 The two halves of the display can be individually accessed through the chip select
pins (CS1 and CS2) of the two NT7108C drivers. Each half consists of 8 horizontal
pages (0-7) which are 8 bits (1 byte) high. This is illustrated in the drawing below.

 Starting from page 0 on the left half (/CS1


= 0) if you transmit one data byte, it will
appear on the first column of page 0.
 If you repeat this 64 times, then switch to
the second half, and repeat until 128th
position is reached, the first 8 display lines
will be plotted.
 The next 8 lines can be plotted similarly by
switching to page address 1. The total
amount of bytes needed for a complete
display frame (128×64 pixels) is,
therefore, 2 * 64 pixels * 8 bits = 1024
bytes.
31
GLCD Pin Configuration

1. As per the name it has 128pixels on X-


axis and 64-pixels on Y-axis.
2. Further the X-axis is divided into two
parts of 64 pixels each and controlled by
unique contoller/driver IC as shown in 32
fig.
Page, Line and Column Selection …..1
Chip Selection: CS2-CS1 CHIP SELECT LINE
The required page can be selected using FUNCTION
CS1,CS2 pins as shown below. 00 None
01 Page0
10 Page1
11 Both Pages

Page Selection X3X2X1 Page Selection


To select the lines we need to send the
command/line address to GLCD. 000 Page0 (Address = 0xB8) /* Set x address (page=0) */
The line address starts from 0xb8 and goes till 001 Page1 (Address = 0xB9) /* Set x address (page=1) */
0xbf as shown below. /* Set x address (page=2) */
010 Page2 (Address = 0xBA)
011 Page3 (Address = 0xBB) /* Set x address (page=3) */

100 Page4 (Address = 0xBC) /* Set x address (page=4) */

101 Page5 (Address = 0xBD) /* Set x address (page=4) */


/* Set x address (page=6) */
110 Page6 (Address = 0xBE)
/* Set x address (page=7) */
111 Page7 (Address = 0xBF)
Page, Line and Column Selection …..2
 To set the cursor position(0-63) we need to send its address to GLCD.
 The cursor positions address starts from 0x40 and goes till 0x7f as
shown below.

Y6-Y1:Line Selection

000000 = Cursor Position 0 (Address = 0x40) Set Y address (column=0) */


000001 = Cursor Position 1 (Address = 0x41) Set Y address (column=0) */
000010 = Cursor Position 2 (Address = 0x42) Set Y address (column=0) */
. .
111111 = Cursor Position 63 (Address = 0x7F) Set Y address (column=0) */

34
Display Control Instructions
Set Y Address
Y Address of display data RAM is set in
Y Address counter. Whenever
write/read operation is executed, Y
Address counter gets automatically
incremented by one.
Set X Address (Page)
X Address (page) of display data RAM
needs to be set in X Address Register.
Here, user needs to increment page
through program after every Y Address
overflow occurs on current page. Note
that if X Address (page) is not
incremented after Y Address overflow
occurs, then overwrite will occur on
current page
Set Display Start Line (Z Address)
Z Address of display data RAM is set in
Display Start Line Register. It is used
to set row (0 - 63) line from where data
will be displayed on screen. Usually it
GLCD_Command(0x3E); /* Display OFF */ sets to 0 i.e. data will be displayed from
0th (first line) top start line.
GLCD_Command(0x3F); /* Display ON */
Writing to GLCD 128x64

 Above figure shows X (Row) and Y (Column) address to select location for data
write. Two controllers control each half of display.
 Each half of display has vertical 64 pixels‟ addresses which are accessed by Y
address from 0x40 to 0x7F. These two controllers alternatively selected by
CS1 and CS2 pins to select either half of display for write,
 To select left half of display we need to make CS1 = 1, CS2 = 0.
 To select right half of display we need to make CS1 = 0, CS2 = 1.
 X address is shown in above figure as page 0 – 7. Each page contains 8 rows. 36
Display Data on GLCD
 To display data on LCD we need to write it on LCD data pins.
 After providing proper address we can send data to GLCD.
 Data value is directly mapped by pixels to glow. Accordingly, we need to send data.

 figure shows data print on GLCD


for which,
 We need to set Y address
from where we need to write
i.e. here it is from first
location, so address is 0x40.
 Then we need to set X
address to first page i.e.
0xB8.
 And write data as shown in
above figure to data pins. It
will print as in figure.

37
GLCD Interfacing Details Description Signal
LCD LPC2148
D0 P0.12
D1 P0.13
D2 P0.14
D3 P0.15
D4 P0.16
D5 P0.17
D6 P0.18
D7 P0.19
RS P1.20
EN P1.21
CS1 P1.22
CS2 P1.23
GRST P1.24
RW P1.25
38
Steps to program GLCD:
Initialization
To initialize the display, we need to do steps given below,
- Send Display OFF command i.e. 0x3E
- Send Y address e.g. here 0x40 (Start address).
- Send X address (Page) e.g. here 0xB8 (Page0).
- Send Z address (Start line) e.g. here 0xC0 (from 0th line).
- Now send Display ON command i.e. 0x3F

Command Write Data Write


To write command, we need to do steps given below, To write data, we need to do steps given below,
- Send command on data pins. - Send Data on data pins.
- Make RS = 0 (Command Register) and RW = 0 (Write - Make RS = 1 (Data Register) and RW = 0 (Write
Operation). Operation).
- Make High to Low transition on Enable pin of - Make High to Low transition on Enable pin of
minimum 1 us period. minimum 1us period.
39
128x64 pixel GLCD interfacing with LPC 2148
#include"lpc214x.h"
#define LCD_PORT 0x000FF000 // Pins P0.12 ~ P0.19
#define EN 1<<21 // Pin P1.21
#define RS 1<<20 // Pin 1.20
#define CS1 1<<22 // Pin 1.22
#define CS2 1<<23 // Pin 1.23
#define GRST 1<<24 // Pin 1.24
#define RW 1<<25 // Pin 1.25
#define LCD_SHIFT 12 // data/cmd to be sent on P0.12 to P0.19
char H[]={0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00};
char E[]={0x7F, 0x49, 0x49, 0x49, 0x41, 0x00}; /* 5x7 Font including 1 space to display HELLO WORLD */

char L[]={0x7F, 0x40, 0x40, 0x40, 0x40, 0x00};


char O[]={0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00};
char W[]={0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00};
char R[]={0x7F, 0x09, 0x19, 0x29, 0x46, 0x00};
40
char D[]={0x7F, 0x41, 0x41, 0x22, 0x1C, 0x00};
void delay(int cnt) /* Function to send the command to LCD */
{ void Glcd_CmdWrite(char cmd)
int i; {
for(i=0;i<cnt;i++); IOCLR0 = LCD_PORT;
} IOSET0 = cmd<<LCD_SHIFT; //Send the Command
IOCLR1 = RS; // Send LOW pulse on RS pin for selecting Command register
IOCLR1 = RW; // Send LOW pulse on RW pin for Write operation
IOSET1 = EN; // Generate a High-to-low pulse on EN pin
delay(100);
void Glcd_SelectPage0() IOCLR0 =EN ;
{// CS1=1, CS2=0 delay(100);
IOSET1=CS1; }
IOCLR1= 0;
/* Function to send the command to LCD */
}
void Glcd_DataWrite(char dat)
{
IOCLR0 = LCD_PORT;
IOSET0 = data<<LCD_SHIFT; //Send the Command
IOSET1 = RS; // Send LOW pulse on RS pin for selecting Command register
void Glcd_SelectPage1()
IOCLR1 = RW; // Send LOW pulse on RW pin for Write operation
{// CS1=0, CS2=1
IOSET1 = EN; // Generate a High-to-low pulse on EN pin
IOCLR1=CS1;
delay(100);
IOSET1= 1;
IOCLR1 =EN ;
}
delay(100);
} 41
Glcd_SelectPage0(); // Display HELLO on Page0, Line1
int main()
{PINSEL0 = 0; //set pins as GPIO Glcd_CmdWrite(0xb8); /* Set x address (page=0) */
PINSEL1 = 0; Glcd_DisplayChar(H);
PINSEL2 = 0;
IODIR0 = LCD_PORT; //set pins as output Glcd_DisplayChar(E);
IODIR1 = RS | EN | CS1 | CS2 | GRST | RW; Glcd_DisplayChar(L);
IOSET1 = GRST | CS1 | CS2;
IOCLR1 = RW | RS | EN; Glcd_DisplayChar(L);

/* Select the Page0/Page1 and Turn on the GLCD */ Glcd_DisplayChar(O);


Glcd_SelectPage0();
Glcd_CmdWrite(0x3f); // Display On
Glcd_SelectPage1(); Glcd_SelectPage0(); // Display HELLO on Page0, Line1
Glcd_CmdWrite(0x3f); // Display On
delay(100); Glcd_CmdWrite(0xbF); /* Set x address (page=0) */
/* Select the Page0/Page1 and Enable the GLCD */ Glcd_DisplayChar(W);
Glcd_SelectPage0(); Glcd_DisplayChar(O);
Glcd_CmdWrite(0xc0); // Start Line 0
Glcd_SelectPage1(); Glcd_DisplayChar(R);
Glcd_CmdWrite(0xc0); // Start Line 0 Glcd_DisplayChar(L);
delay(100);
Glcd_DisplayChar(D);}
42
UNIT III

Unit III : Real World Interfacing with ARM7 Based


Microcontroller -1

1. Interrupt structure of LPC2148


2. Interfacing with LED, LCD, GLCD, KEYPAD
3. Simple LPC2148 GPIO Programming examples
4. Using timers of LPC2148 to generate delay
5. serial communication programming for transmission and
reception from computer,
6. programming for UART.
Introduction to Interrupts
 To start with , first lets see : what interrupts, IRQs and ISRs .

• “An interrupt is a signal sent to the CPU which indicates that a system event has
a occurred which needs immediate attention“

• An „Interrupt ReQuest„ i.e an „IRQ„ can be thought of as a special request to the CPU
to execute a function when an interrupt occurs.

• This function or „small piece of code‟ is technically called an „Interrupt Service


Routine„ or „ISR„. So when an IRQ arrives to the CPU , it stops executing the code
current code and start executing the ISR.

44
Introduction to Interrupts
 Vectored and Non-Vectored Interrupts
 The term „Vectored„ means that the CPU is aware of the address of the ISR
when interrupt occurs and Non-Vectored means that CPU doesn‟t know the
address of the ISR and it needs to be supplied.
1. For the Vectored Stuff , the System maintains a table called IVT or
Interrupt Vector Table which has ISR addresses.
2. On the other hand Non-Vectored ISRs doesn‟t point to a unique ISR and
instead CPU needs to be supplied with the address of the „default‟ or
say.. a „common‟ ISR.
3. In LPC214x this is given by a register called „VICDefVectAddr„. The user
must assign the address of the default ISR.

45
Interrupts in LPC214x
 Interrupts in LPC214x are handled by Vectored Interrupt

Controller(VIC)

 Features of VIC

• 32 interrupt request inputs

• 16 vectored IRQ interrupts

• 16 priority levels dynamically assigned to interrupt requests

• Software interrupt generation

46
Vector Interrupt Controller (VIC) Features
 VIC accepts 32 interrupt request inputs, LPC 2148 uses 22 of 32 interrupts
• Interrupts are classified into 3 categories:
1. Fast Interrupt Request i.e FIQ : which has highest priority
2. Vectored Interrupt Request (IRQ): which has „middle‟ priority between
FIQ and Non-Vectored IRQ.
3. Non-Vectored IRQ : which has the lowest priority.
Note:
The programmable assignment scheme means –
Priorities of interrupts from the various peripherals can be dynamically assigned
and adjusted.
OR
Any of the 22 interrupts can be assigned to FIQ/ VIRQ/ NVIRQ 47
Vector Interrupt Controller (VIC) Features
Therefore we can classify Interrupts into two types :
1. Fast IRQs or FIQs
2. Normal IRQs or IRQs which can be further classified as : Vectored IRQ and
Non-Vectored IRQ.

 Any of the 22 interrupts can be assigned to FIQ/ VIRQ/ NVIRQ


 FIQ:
1. Generally, only one interrupt is assigned, VIC provides ISR address.
2. If more than one request is assigned to FIQ, the VIC ORs the requests to
produce the FIQ signal to the ARM processor.
3. But if more than one request is assigned to FIQ class, then VIC has
to identify which FIQ source(s) is requesting an interrupt.

48
Vector Interrupt Controller (VIC)
Features:
 VIRQ & NVIRQ:
1. VIC has 16 VIRQ slots, Slot0 – Slot15. Only 16 of the 32 requests can
be assigned to this category. Any IRQ configured interrupts can
be assigned IRQ slots.
2. Slot 0 has the highest priority and slot 15 has the lowest.
3. Interrupts configured as IRQ, not assigned as VIRQ slot, is
assigned as NVIRQ
4. VIRQ & NVIRQ interrupts are combined and VICIRQ is
generated.

Programs can handle 1 FIQ, 16 VIRQ, 1 NVIRQ (total 18 ) interrupts


49
In Short we should remember following points

• The VIC ORs the requests from all vectored and non-
vectored IRQs to produce the IRQ signal .
• If any of the vectored IRQs are requesting, the VIC provides
the address of the highest-priority requesting IRQs service
routine, otherwise it provides the address of a default
routine that is shared by all the non-vectored IRQs.
• All registers in the VIC are word registers.

50
Table 1

VIC has plenty of registers. Most of the registers that are used to configure interrupts.
Each bit corresponding to a particular interrupt source and this mapping is same for all
of these registers.
What I mean is that bit 0 in these registers corresponds to Watch dog timer interrupt ,
bit 4 corresponds to TIMER0 interrupt .. and so on.

51
LPC2148 Interrupt Related Registers or VIC
Registers
Now we will have a look at some of the important Registers that are used to implement
interrupts in lpc214x:

52
1. Interrupt Select register
(VICIntSelect - 0xFFFF F00C)

• This is a read/write accessible register.


• This register classifies each of the 32 interrupt
requests as contributing to FIQ or IRQ.

• 0 = The interrupt request with this bit number is assigned to the IRQ category.
• 1 = The interrupt request with this bit number is assigned to the FIQ category.

53
2. Interrupt Enable register
(VICIntEnable - 0xFFFF F010)

• This register controls which of the 32 interrupt


requests and software interrupts contribute to FIQ or IRQ.

During read, 1s indicate interrupt requests or software interrupts that are enabled to
contribute to FIQ or IRQ.
During write, ones enable interrupt requests or software interrupts to contribute to FIQ or
IRQ, zeroes have no effect. 54
3. Interrupt Enable Clear register
(VICIntEnClear - 0xFFFF F014)

• This register allows software to clear one or more bits in the Interrupt
Enable register.

• 0= No effect;
• 1= Clears the corresponding bit in the Interrupt Enable register, thus disabling interrupts
for this request.
55
4. IRQ Status register
(VICIRQStatus - 0xFFFF F000)
.
• This register reads out the state of those interrupt requests that are
enabled and classified as IRQ.
• It does not differentiate between vectored and
non-vectored IRQs

• 1 indicates a corresponding interrupt request being enabled, classified as IRQ, and


asserted.

56
5. FIQ Status register
(VICFIQStatus - 0xFFFF F004)

• This is a read only register. This register reads out the state of those interrupt requests
that are enabled and classified as FIQ.
• If more than one request is classified as FIQ, the
FIQ service routine can read this register to see which request(s) is (are) active.

• 1 indicates a corresponding interrupt request being enabled, classified as FIQ, and


asserted.

57
6. Software Interrupt register
(VICSoftInt - 0xFFFF F018)

• The contents of this register are ORed with the 32 interrupt requests from
the various peripherals.

• 31:0 bits: 0 = No effect; 1= Force interrupt

58
7. Software Interrupt Clear register
(VICSoftIntClear - 0xFFFF F01C)

• This register allows software to clear one or more bits in the Software
Interrupt register.

• 31:0 bits: 0 = Leaves bit as it is in Software Int. Register.


1= Clears that interrupt in Software Int. Register.
59
8. Vector Control registers 0-15
(VICVectCntl0-15 - 0xFFFF F200-23C)
• Each of these registers controls one of the 16vectored IRQ slots. Slot 0
has the highest priority and slot 15 the lowest. Note that disabling a
vectored IRQ slot in VICVectCntl registers does not disable the interrupt
itself, the interrupt is simply changed to the non-vectored form.

60
10. Vector Address registers 0-15
(VICVectAddr0-15 - 0xFFFF F100-13C)
• These are a read/write accessible registers. These registers
hold the addresses of the Interrupt Service routines (ISRs) for
the 16 vectored IRQ slots.

61
11. Default Vector Address register
(VICDefVectAddr - 0xFFFF F034)
• This is a read/write accessible register. This register
holds the address of the Interrupt Service routine (ISR)
for non-vectored IRQs.

62
12. Protection Enable register
(VICProtection - 0xFFFF F020)

• This is a read/write accessible register. It controls access


to the VIC registers by software running in User mode.

63
UNIT III
Unit III : Real World Interfacing with ARM7 Based
Microcontroller -1
1. Interrupt structure of LPC2148
2. Interfacing with LED, LCD, GLCD, KEYPAD
3. Simple LPC2148 GPIO Programming examples

4. Using timers of LPC2148 to generate delay


5. serial communication programming for transmission and reception from
computer,
6. programming for UART.
Timers in LPC2148 ARM7 Microcontroller
● The LPC2148 has two functionally identical general purpose
timers: Timer0 and Timer1.
● These both timers are 32-bit along with 32-bit prescaler.
● Timer allows us to generate precise time delay.

32 bit Timer Counter with 32 bit Prescaler


● 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.
Timer block diagram
Timer Registers Description
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.
69
Timer Registers
4) TCR : Timer Control Register – This register is used to
enable , disable and reset TC.
a. When bit0 =1, timer is enabled and when 0 it is
disabled.
b. When bit1 is set to 1 TC and PC are set to zero
together in sync on the next positive edge of PCLK.
Rest of the bits of TCR are reserved.

5) CTCR : Count Control register – Used to select


Timer/Counter Mode.
a. For our purpose we are always gonna use this in Timer
Mode. When the value of the CTCR is set to 0×0
Timer Mode is selected. 70
REGISTERS USED IN TIMERS:
T0TCR:This register is used to control the functions of the Timer0. Enable
and reset operations of the Timer0 register can be controlled by this register.
T0PR:This is a 32 bit Prescale register which holds the maximum value
which the Prescale counter can take.
T0PC:This is a 32 bit Prescale counter which specifies the division value of
the processor clock before feeding it to the timers. The value in the register
increments with every input pulse or Processor clock fed into it. Prescale
register T0PR gives the max value this T0PC register can take. When
reaching the max count T0PC register gets reset on the next Processor
clock.
T0TC:A 32 bit timer counter is incremented whenever Prescale
counter T0PC value reaches its maximum level given in the Prescale
register T0PR.
T0MR0:These register stores the value which should be compared
to the T0TC register. Operations specified based on the T0MCR will
be performed whenever a match encounters.
T0MCR:The Match control register is used to specify the operation
whenever a match occurs between the value stored in T0MR0 and
T0TC register.
T0IR:Interrupt register which consists bits for match and capture
interrupts. Writing will reset the interrupts in this register.
Timer Features
 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
 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.

73
Match Registers
r What is a Match Register anyways ?
r Ans: A Match Register is a Register which contains a
specific value set by the user.
r When the Timer starts – every time after TC is
incremented the value in TC is compared with match
register.
r If it matches then it can Reset the Timer or can
generate an interrupt as defined by the user.
r Match Registers can be used to:
m Stop Timer on Match and trigger an optional interrupt.
m Reset Timer on Match and trigger an optional interrupt.
m To count continuously and trigger an interrupt on match.
74
Timer Registers
MCR : Match Control register – 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:
m 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.
m Bit 1 : Reset on MR0. When set to 1 , TC will be reset when it matched
MR0. Disabled when set to 0.
m Bit 2 : Stop on MR0. When set to 1 , TC & PC will stop when MR0 matches
TC.
m Similarly bits 3-5 , 6-8 , 9-11 are for MR1 , MR2 , MR3
respectively.
75
Timer…
Pin description…

r MAT0.3..0 & MAT1.3..0 (Output)


r External Match Output 0/1- When a
match register 0/1 (MR3:0) equals the
timer counter (TC), this output can either
toggle, go low, go high, or do nothing.
r The External Match Register (EMR)
controls the functionality of this output.

76
Capture Registers
r What are Capture Registers ?
Ans: 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 generate an Interrupt.
• . CAP0.3..0 & CAP1.3..0 (Input)
Capture Signals- A transition on a this (capture)
pin is found, it loads one of the Capture Registers
with the value in the Timer Counter and optionally
generate an interrupt.

77
Timer…
Pin description…
List of all CAPTURE signals, together with pins
on where they can be selected:
Capture 0:
• CAP0.0 (3 pins) : P0.2, P0.22 and P0.30
• CAP0.1 (1 pin) : P0.4
• CAP0.2 (3 pin) : P0.6, P0.16 and P0.28
• CAP0.3 (1 pin) : P0.29
Capture 1:
• CAP1.0 (1 pin) : P0.10
• CAP1.1 (1 pin) : P0.11
• CAP1.2 (2 pins) : P0.17 and P0.19
• CAP1.3 (2 pins) : P0.18 and P0.21 78
Timer Calculations
1. The delay or time required for 1 clock cycle at „X‟ MHz is given
by :

2. Hence in our case when PR=0 i.e TC increments at every PCLK,


the delay required for TC to increment by 1 is:

3. Similarly when we set PR = 59999 the delay in this case will be:

• which boils down to 1/1000 = 0.001 Seconds


• Hence the delay required for TC to increment by 1
will be 1mS.
79
CALCULATION OF TIME DELAY:
Peripheral Frequency = CPU Clock / VPB divider
Since we are using Default 1/4 divider here our peripheral frequency will be
Peripheral Frequency = 20 MHz / 4 = 5MHz
Then we have to calculate T0MR0 (count) value to generate required delay by
matching
Count = (5MHz * Required time delay) – 1
= (5,000,000 * 100ms) – 1
= (5,000,000 * .1) -1
= 4,99,999
Now count 499999 gives the T0MR0 value to generate 100ms delay. So to make
it as one sec we have to multiply it with 10. And that we can use it in the
Prescale register T0PR, thus we can generate a delay of 1 sec using this.
PCLK = 30MHz
Hence, we will load T0PR with a value 29, so that the TC will
increment after every 30 PCLK rising edges.
30MHz/30 = 1MHz, which gives 1µsec time.

To get 100msec time, we will have to load T0MR with 100000

(1 µsec * 1000 = 1msec, 1msec * 100 = 100msec. Hence, 1000 *


100 = 100000)
This will give us a delay of 100msec.
STEPS TO PROGRAM TIMERS:
1. Reset timer0 initially to deactivate counting.
2. Load calculated values in the Prescaler register T0PR and
Match register T0MR0.
3. Initialize T0PC and T0TC registers.
4. Select operations using match registers when match is
encountered.
5. Start the Timer by enabling it through T0TCR register.
6. Wait till the interrupt and then clear the flag by writing T0IR
register.
Delay program using timers

void delayMS(unsigned int milliseconds) //Using Timer0


{
T0TCR = 0x02; //Reset Timer, 0b0000 0010

T0TCR = 0x01; //Enable timer or start counter 0,


0b 0000 0001

while(T0TC < milliseconds); //wait until timer counter


//reaches the desired delay

T0TCR = 0x00; //Disable timer, 0b0000 0000


} Main Program 83
This code LED’s connected to the Port 0 are toggled with 1 sec time delay.
#include<lpc21xx.h>
void delay(void);
int main(void)
{
PINSEL0=0;
IODIR0=0x0000000F;
while(1)
{
IOSET0=0x0000000F;
delay();
IOCLR0=0x0000000F;
delay();
}
}
void delay(void)
{
T0TCR=(1<<1); //Reset Timer0
T0MR0=499999; //Loading match register value
T0PR=10; //Loading Prescalar register value
T0PC=T0TC=0;
T0MCR=(1<<0)|(1<<2); //Generates interrupt and reset on match
T0TCR=(1<<0); //Starting Timer
while(!(T0IR&(1<<0))); //Waiting for interrupt
T0IR=(1<<0); //Clearing interrupt
}
UNIT III
Unit III : Real World Interfacing with ARM7 Based
Microcontroller -1
1. Interrupt structure of LPC2148
2. Interfacing with LED, LCD, GLCD, KEYPAD
3. Simple LPC2148 GPIO Programming examples
4. Using timers of LPC2148 to generate delay

5. serial communication programming for


transmission and reception from computer,
6. programming for UART.
Unit 3: LPC2148 Serial
Port Programming

Prof: M. N. Kakatkar
Sinhgad College of Engineering, Pune
Email: [email protected]
Introduction to UART Basics
 In this topic we will go through the basics of
UART(SERIAL) programming for LPC214x family of
microcontrollers.
Introduction
 Computers transfer data in two ways: Parallel and Serial.
 Parallel: Eight or more data lines, few feet only, short time
 Serial: Single data line, long distance
 The PIC18 has serial communication capability built into it.
Basics of Serial Communication
 The byte of data must be converted to serial bits using a
parallel-in-serial-out shift register

Serial versus Parallel Data Transfer


Basics of Serial Communication (cont‟d)
 The receiving end must be a serial-in-parallel-out shift
register and pack them into a byte.
 Two methods of serial data communication: Asynchronous
and Synchronous

Transfers a block of
Transfers a single byte at data at a time
a time
Half-and Full-Duplex Transmission
Start and Stop Bits
 In the asynchronous method, each character is placed
between start and stop bits (framing)

MSB LSB

Framing ASCII ‘A’ (41H)


Data Transfer Rate
 Rate of data transfer: bps (bits per second)
 Another widely used terminology for bps is baud rate
 For Asynchronous serial data communication, the baud rate
is generally limited to 100,000bps
RS232 Standard
 Standard for serial comm (COM port)
1: -3V to -25V;
0: +3V to +25V
 Reason: for long distance wired line

 Input-output voltage are not TTL compatible


 So, we need MAX232/233 for voltage converter.
Commonly known as line drivers
RS232 Pins
Connectors:
Minimally, 3 wires: RxD, TxD, GND
Could have 9-pin or 25-pin

DB-25 DB-9
25-Pin Connector 9-Pin Connector
RS232 Pins (cont‟d)

IBM PC DB-9 Signals


Data in Data out
Pin 1 – Data Carrier Detect (DCD)
Pin 2 – Received Data (RxD)
Pin 3 – Transmitted Data (TxD)
Pin 4 – Data Terminal Ready (DTR)
Pin 5 – Signal Ground (GND)
Pin 6 – Data Set Ready (/DSR)
Pin 7 – Request to Send (/RTS)
Pin 8 – Clear to Send (/CTS)
DB-9 Pin 9 – Ring Indicator (RI)
9-Pin Connector
 Uart uses TxD(Transmit) Pin for sending Data and
RxD(Receive) Pin to get data. UART sends & receives data
in form of chunks or packets. These chunks or packets are
also referred to as „transmission characters‟. The
structure of a UART data packet is as shown below :
UART block in our LPC214x
microcontroller
 LPC214x has 2 UART blocks which are UART0 and UART1.
 For UART0 the TxD pin is P0.0 and RxD pin is P0.1 and in
 UART 1 the TxD pin is P0.8 and RxD pin is P0.9

 Before we can use these pins to transfer data , first we need to


configure and initialize the UART block in our LPC214x microcontroller.

Pins: TxD RxD


UART0 P0.0 P0.1
UART1 P0.8 P0.9
Registers used for UART Programming in LPC214x
Data Related Registers :
1. U0RBR – Receiver Buffer Register (READ ONLY!):
• This register contains the top most byte(8-bit data chunk) in the Rx FIFO i.e the
oldest received data in FIFO.
• To properly read data from U0RBR , the DLAB(Divisor Latch Access) bit in U0LCR
register must be first set to 0.
• Also , as per the user manual “The right approach for fetching the valid pair of
received byte and its status bits is first to read the content of the U0LSR register,
and then to read a byte from the U0RBR.” (Note : If you are using 7,6 or 5 Bits for
data then other remaining bits are automatically padded with 0s)

2. U0THR – Transmit Holding Register (WRITE ONLY!):


• U0THR contains the top most byte in Tx FIFO and in this case its the newest(latest)
transmitted data.
• As in the case with U0RBR , we must set DLAB=0 to access U0THR for write
operation.
Control and Status Registers :

1) U0FCR – FIFO Control Register : Used to control Rx/Tx FIFO operations.

Bit 0 – FIFO Enable : 1 to Enable both Rx and Tx FIFOs and 0 to disable.

Bit 1 – Rx FIFO Reset : Writing a 1 will clear and reset Rx FIFO.

Bit 2 – Tx FIFO Reset : Writing a 1 will clear and reset Tx FIFO.

Bits [7 to 6] : Used to determine that how many UART0 Rx FIFO characters must be written
before an interrupt is activated.

[00] (i.e trigger level 0) for 1 character.


[01] (i.e trigger level 1) for 4 characters.
[10] (i.e trigger level 2) for 8 characters.
[11] (i.e trigger level 3) for 14 characters.
Others bits are reserved.
2) ULCR0/1 – Line Control Register : Used to configure the UART block (i.e the data
format used in transmission).
Divisor Latch Break Parity Select Parity Stop bit Word
Access Bit Control Enable select length
select
7 6 5 4 3 2 1 0

Bit [1 to 0] – Word Length Select : Used to select the length of an individual data chunk. [00] for 5 bit
character length. Similarly [01] , [10] , [11] for 6 , 7 , 8 bit character lengths respectively.

Bit 2 – Stop bit select : 0 for using 1 stop bit and 1 for using 2 stop bits.

Bit 3 – Parity Enable : 0 to disabled Partiy generation & checking and 1 to enable it.

Bit [5 to 4] – Parity Select : [00] to Odd-parity , [01] for Even-parity , [10] for forced
“1”(Mark) parity and [11] for forced “0”(Space) parity.

Bit 6 – Break Control : 0 to disable break transmission and 1 to enable it. TxD pin will be
forced to logic 0 when this bit is 1

Bit 7 – Divisior Latch Access bit : 0 to disable access to divisor latches and 1 to enable access.
3) U0LSR – Line Status Register : used to read the status of Rx and Tx
blocks.

Bit 0 – Receiver Data Ready(RDR) : 0 means U0RBR is empty(i.e Rx FIFO is empty) and 1 means
U0RBR contains valid data.

Bit 1 – Overrun Error(OE) : 0 means Overrun hasn‟t occured and 1 means Overrun has occured.
Overrun is the condition when RSR(Receive Shift Register)[See note 1] has new character assembled
but the RBR FIFO is full and the new assembled character is eventually lost since no data is written
into FIFO if its full. (Note: Reading U0LSR clears this bit)

Bit 2 – Parity Error(PE) : 0 mean no parity error and 1 mean a parity error has occured. When the
value of the parity bit in the recieved character is in wrong state then a parity error occurs. (Note:
Reading U0LSR clears this bit)

Bit 3 – Framing Error(FE) : 0 means no framing error has occured and 1 means that a framing error has
taken place. Framing error occurs when the stop bit of a received character is zero. (Note: Reading
U0LSR clears this bit)
Bit 4 – Break Interrupt : 0 means no Break Interrupt occurs and 1 means that it has occurred. A
Break Interrupt occurs when the RxD line is pulled low (i.e all 0s) i.e held in spacing state for 1 full
character after which Rx Block goes into Idle state. Rx Block gets back to active state when RxD pin
is pulled high (i.e all 1s) i.e held in marking state for 1 full character. (Note: Reading U0LSR clears this
bit)

Bit 5 – Transmit Holding Register Empty(THRE) : 0 means U0THR contains valid data and 1 means
its empty

Bit 6 – Transmitter Empty (TEMT) : 0 means U0THR and/or U0RSR contains valid data and 1 means
that both U0THR and U0RSR are empty.

Bit 7 – Error in RX FIFO(RXFE) : 0 means that U0RBR has no Rx Errors or Rx FIFO is disabled(i.e
0th bit in U0FCR is 0) and 1 means that U0RBR has atleast one error. (Note: This bit is cleared only if
U0LSR is read and there are no other subsequent errors in Rx FIFO .. else this bit will stay 1)
4) U0TER – Transmit Enable Register : This register is used
to enable UART transmission.

 When bit-7 (i.e TXEN) is set to 1 Tx block will be enabled


and will keep on transmitting data as soon as its ready.

 If bit-7 is set to 0 then Tx will stop transmission. Other


bits are reserved.
Interrupt Related Registers :

1) U0IER – Interrupt Enable Register: Set a bit to 0 to


disable and 1 to enable the corresponding interrupt.
Bit 0 – RBR Interrupt Enable
Bit 1 – THRE Interrupt Enable
Bit 2 – RX Line Status Interrupt Enable
Bit 3 – ATBOInt Enable
Bit 4 – ATEOInt Enable
Where ATBOInt = Auto Baud Time-Out Interrupt , ATEO = End
of Auto Baud Interrupt and rest of the bits are reserved.
2) U0IIR – Interrupt Identification Register: Refer User Manual
when in doubt. In some application the usage of this register might
get a bit complicated.
This register is organized as follows:
Bit 0 – Interrupt Pending : 0 means atleast one interrupt is pending ,
1 means no interrupts are pending. Note: This bit is ACTIVE LOW!
Bits [3 to 1] – Interrupt Identification : [011] is for Receive Line
Status(RLS) , [010] means Receive Data Available(RDA) , 110 is for
Character Time-out Indicator(CTI) , [001] is for THRE Interrupt.
Bits [7 to 6] – FIFO Enable.
Bit 8 – ABEOInt : 1 means Auto Baud Interrupt has successfully
ended and 0 otherwise.
Bit 9 – ABTOInt : 1 means Auto Baud Interrupt has Timed-out.
All others bits are reserved.
Baud Rate Setup related registers :
1) U0DLL and U0DLM – Divisor Latch registers:

 Both of them hold 8-bit values.


 These register together form a 16-bit divisor value which is used in baud
rate generation.
 U0DLM holds the upper 8-bits and U0DLL holds the lower 8-bits and the
formation is “[U0DLM:U0DLL]“.
 Since these form a divisor value and division by zero is invalid, the starting
value for U0DLL is 0x01 (and not 0x00) i.e the starting value in combined
formation is “[0x00:0x01]” i.e 0x0001.
 Please keep this in mind while doing baud-rate calculations.
 In order to access and use these registers properly, DLAB bit in
U0LCR must be first set to 1.
Baud Rate Setup related registers :
2) U0FDR – Fractional Divider Register :
This register is used to set the prescale value for baud rate generation. The input clock is the peripheral
clock and output is the desired clock defined by this register

31:8 MULVAL DIVADDVAL

Reserved 7 6 5 4 3 2 1 0

This register actually holds to different 4-bit values (a divisor and a multiplier) for prescaling which are:

Bit [7 to 4] – MULVAL : This is prescale multiplier


Bit [3 to 0] – DIVADDVAL : This is the value.
prescale divisor value. Even if fractional baud rate generator is not used
. this value if 0 then fractional baud rate
If the value in this register must be more than or
generator wont have any effect on Uart Baud equal to 1 else UART0 will not operate properly.
rate. Other Bits reserved

Remark from User manual : “If the fractional divider is active (DIVADDVAL > 0) and DLM = 0, the
value of the DLL register must be 2 or greater!”
UART Baud Rate Generation:
Note :
 In real world there are very less chances that you will get
the actual baudrate same as the desired baudrate.
 In most cases the actual baudrate will drift a little above
or below the desired baud and also, as the desired
baudrate increases this drift or error will also increase –
this is because of the equation itself and the
 limitations on MULVAL , DIVADDVAL! For e.g. if the
desired baud rate is 9600 and you get a baud like 9590 ,
9610 , 9685 , 9615 , etc.. then in almost all cases it will
work as required.
 In short , a small amount of error in actual baudrate is
generally tolerable in most systems.
The formula for calculating baud
rate is given as :

which can be further simplified to :

with following conditions strictly applied :


1. 0 < MULVAL <= 15 , Where PCLK is the Peripheral Clock value in Hz ,
2. 0 <= DIVADDVAL <= 15, U0DLM and U0DLL are the divisor registers and
if DIVADDVAL > 0 & DLM = 0 finally DIVADDVAL and MULVAL are part of the
then, DLL >= 2
Fractional baudrate generator register.

As it can been seen this formula has 2 prominent parts which are : A Base value and a Fractional
Multiplier i.e:
BaudRate = [ Base ] x [ Fraction(i.e. Prescale) ]

This Fractional Multiplier can be used to scale down or keep the base value as it is .. hence its very useful
for fine-tuning and getting the baudrate as accurate as possible.
Examples for calculating Baud Rates
1. We start with DLM=0 , DIVADDVAL=0 and MULVAL=1 and get an
initial value for DLM.
2. We will get a very close baudrate to the desired one. (if we are
lucky)
3. If not then we perform some finetuning using DLM , MULVAL and
DIVADDVAL and get a new value for DLM

Ex 1 : PCLK = 30Mhz and Required Baudrate is 9600 bauds for UART0

1. Lets start with U0DLM = 0 , DIVADDVAL = 0 and MULVAL = 1


2. We have PCLK = 30 Mhz = 30 x 106 Hz

UART0 Baud rate =

3. Substituting vales for U0DLM = 0 , DIVADDVAL = 0 and MULVAL = 1

UART0 Baud rate = =


;

U0DLL = = 195.3125
We get U0DLL = 195.3125 , since it must be an integer we use 195.

Let us calculate BaudRate Error as = Actual BaudRate – Desired BaudRate.

With U0DLL = 195 our actual baud rate will Now all we have to do is to get this error as low
be = 9615.38 with an error of +15.38 from as possible.
9600.

First lets compute the required fraction given This can be done by multiplying it by a suitable
as: fraction defined using MULVAL and
[Desired Baud / Actual Baud Rate]. = 9600/ DIVADDVAL – as given in equation.
9615.38 = 0.9984.
Now What?
The closest downscale value possible(<1) to
In short this is the value i.e 0.9984 that 0.9948 is 0.9375 when MULVAL=15 &
needs to be multiplied by baud value we got DIVADDVAL=1.
above to bring back it to ~9600. But 0.9375 is too less because
9615.38x0.9375 = 9014.42 which is way too
far.
This the value
we use

Luckily when U0DLL = 183 we get a baud rate of Now , one thing can be done is that we set
9605.53 i.e ~9605! Yea! MULVAL = 15 and now start decreasing U0DLL
from 195
For PCLK = 30Mhz and Required Baudrate is
9600 bauds for UART0

Hence the final settings in this case will be : PCLK = 30 x 106 Hz

U0DLL = 183

U0DLM = 0

MULVAL = 15

DIVADDVAL = 1
Examples for calculating Baud Rates
Ex 2 : PCLK = 60Mhz and Required Baudrate is 9600 bauds for UART0

1. Lets start with U0DLM = 0 , DIVADDVAL = 0 and MULVAL = 1


2. We have PCLK = 60 Mhz = 60 x 106 Hz

UART0 Baud rate =

3. Substituting vales for U0DLM = 0 , DIVADDVAL = 0 and MULVAL = 1

UART0 Baud rate = = ; Now What?

U0DLL = = 390.625 out of range since U0DLL is 8-bit!

Initially we made U0DLM „0‟, Now set U0DLM = 1 to get U0DLL in range

9600 = ; U0DLL = 135


We get U0DLL = 134.625 , since it must be an integer we use 135.

Let us calculate BaudRate Error as = Actual BaudRate – Desired BaudRate.

With U0DLL = 135 our actual baud rate will Now all we have to do is to get this error as low
be = 9590.79 with an error of -9.21 from as possible.
9600.

First lets compute the required fraction given Let us say this can be done by multiplying it by
as: a suitable fraction defined using MULVAL and
[Desired Baud / Actual Baud Rate]. = 9600/ DIVADDVAL – as given in equation.
9590.79 = 1.0009

Now What?
The fractional value we need to multiply our
current baud to get back to ~9600 is 1.0009 but Hence, in such case we have to use MULVAL =
that‟s out of range(>1) for a factor 15 and find new value for U0DLL..

This the value


we use

Here we get U0DLL = 110 which gives a baud of Now , one thing can be done is that we set
9605.53 which is ~9605! MULVAL = 15 and now start decreasing U0DLL
from 135
For PCLK = 60Mhz and Required Baudrate is
9600 bauds for UART0

Hence the final settings in this case will be : PCLK = 60 x 106 Hz

U0DLL = 110

U0DLM = 1

MULVAL = 15

DIVADDVAL = 1
Configuring and Initializing UART
 We will use the following configuration for UART0:
• BaudRate = 9600 buads (with PCLK=15Mhz)
• Data Length = 8 bits
• No Parity Bit
• and 1 Stop Bit
 In order to get bauds at 15Mhz PCLK we must use the following settings for
baud generation :

U0DLL = 97 ; U0DLM = 1 ; MULVAL = 0 ; DIVADDVAL=0


(You can convert these values to Hex =or= direclty use it in decimal
form)
Now , lets make a simple program to configure and initialize UART0

/* Select TxD for P0.0 and RxD for P0.1 */


// This is done by placing ‘01’ at bit positions 1:0 & 3:2 resp.
in Pinsel0 register

RxD TxD

PINSEL0 =x05
/* 8 bits, no Parity, 1 Stop bit, DLAB set to 1 */
//We now use Line Control Register (U0LCR) to configure the UART block (i.e the
data format used in transmission)

U0LCR = 3 | (1<<7) ; OR U0LCR = 0x83;

//Setting U0CLR Reg

/* 9600 Baud Rate @ 15MHz VPB Clock*/


U0DLL = 97;
// Use DLL register to set

U0LCR &= 0x03; // Set DLAB=0 to lock MULVAL and DIVADDVAL

//BaudRate is now ~9600 and we are ready for UART communication!


#include <stdio.h> /* prototype declarations for I/O functions */
#include <LPC21xx.H> /* LPC21xx definitions */
char msg[]={"\n\r Code for UART0"};
int main (void)
{
/* execution starts here*/

long int n;

PINSEL0 = 0x00000005; //set line ctrl reg. for UART0 with above parameters
U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
U0DLL = 97; /* 9600 Baud Rate @ 15MHz VPB Clock*/

U0LCR = 0x03; /* DLAB = 0 */


while(1)
{
n=0;
while(msg[n]!='\0') //chk end of msg
{
U0THR = msg[n++];
while(!(U0LSR&0x40));
}
}
}

You might also like