0% found this document useful (0 votes)
15 views72 pages

Unit 3 ESD 2024

The document provides an overview of GPIO and interfacing with various components using the LPC2148 microcontroller, detailing its architecture, GPIO ports, and registers. It includes examples of programming for controlling LEDs, 7-segment displays, and other peripherals. The document emphasizes the configuration of GPIO pins and the use of specific registers for input/output operations.

Uploaded by

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

Unit 3 ESD 2024

The document provides an overview of GPIO and interfacing with various components using the LPC2148 microcontroller, detailing its architecture, GPIO ports, and registers. It includes examples of programming for controlling LEDs, 7-segment displays, and other peripherals. The document emphasizes the configuration of GPIO pins and the use of specific registers for input/output operations.

Uploaded by

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

UNIT 3

GPIO and Interfacing: General purpose input/output ports,


Interfacing of ADC, DAC, UART, I2C, LCD, stepper motor, LED,
keypad and 7-segment display using data sheets of a
microcontroller
GPIO IN LPC2148
• LPC2148 is a 32-bit Microcontroller based on the
ARM7TDMI-S Family. It is manufactured by NXP
Semiconductors (formerly Philips)
• It has an on-chip static RAM of 32kB and an on-
chip flash memory of 512kB.
• It has an embedded in-circuit emulator that helps
in real time debugging.
• LPC2148 has two 10-bit ADCs (ADC0 and ADC1) of
Successive Approximation type.
• It also has a 10-bit DAC of Resistor String type.
• General-purpose input/output (GPIO) is a pin on an IC (Integrated Circuit).
• It can be either input pin or output pin, whose behaviour can be controlled at the
run time.
• A group of these pins is called a port
• LPC2148 has two 32-bit General Purpose I/O ports: 1. PORT0 2. PORT1

• PORT0 is a 32-bit port


• Out of these 32 pins, 28 pins can be configured as either general purpose input or
output.
• 1 of these 32 pins (P0.31) can be configured as general-purpose output only.
• 3 of these 32 pins (P0.24, P0.26 and P0.27) are reserved. Hence, they are not
available for use. Also, these pins are not mentioned in pin diagram.
Note : The Port 0 pins do not have built-in pull-up or pull-down resistors. Hence, while
using GPIOs on Port 0, in some cases, we need to connect pull-up or pull-down
resistors externally.

• PORT1 is also a 32-bit port. Only 16 of these 32 pins (P1.16 – P1.31) are available
for use as general-purpose input or output.
Note: Most of the pins in both the I/O ports of the LPC2148 have more than one
function i.e. they are multiplexed with different functions.
Pin Function Select Registers in LPC2148:
• The configuration register is called PINSEL and is classified in to three registers:
PINSEL0, PINSEL1 and PINSEL2.
• These configuration registers are of 32-bit wide.
• Any pin on the LPC2148 can have a maximum of 4 functions. Hence in order to
select one of the four functions, two corresponding bits of the PINSEL register
are needed.
• So, a 32-bit PINSEL register can control 16 pins with 2-bits to control each pin.
1. PINSEL0 : - PINSEL0 is used to configure PORT0 pins P0.0 to P0.15.
2. PINSEL1 : - PINSEL1 is used to configure PORT0 pins P0.16 to P0.31.
3. PINSEL2 : - PINSEL2 is used to configure PORT1 pins P1.16 to P1.31.

GPIO registers that control the GPIO operations:


• Fast and Slow GPIO Registers
• There are 5 Fast (also called Enhanced GPIO Features Registers) GPIO
Registers and 4 Slow (also called Legacy GPIO Registers) GPIO Registers
available to control PORT0 and PORT1.
• The Slow Registers allow backward compatibility with earlier family
devices using the existing codes.
Slow GPIO Registers
There are 4 Slow GPIO registers :
1. IOxDIR (GPIO Port Direction control register) : This is a 32-bit wide register. This
register individually controls the direction of each port pin. Setting a bit to ‘1’
configures the corresponding pin as an output pin. Setting a bit to ‘0’ configures the
corresponding pin as an input pin.

2. IOxPIN (GPIO Port Pin value register): This is a 32-bit wide register. The current state
of the GPIO configured port pins can always be read from this register, regardless of
pin direction. This register is used to read/write the value on Port (PORT0/PORT1).
But care should be taken while writing. Masking should be used to ensure write to
the desired pin.
Writing to the IOPIN register stores the value in the port output register, bypassing the
need to use both the IOSET and IOCLR registers to obtain the entire written value. This
feature should be used carefully in an application since it affects the entire port.
Examples :
a) Writing 1 to P0.4 using IO0PIN
IO0PIN = IO0PIN | (1<<4)
b) Writing 0 to P0.4 using IO0PIN
IO0PIN = IO0PIN & (~(1<<4) )
c) Writing F to P0.7-P0.4
IO0PIN = IO0PIN | (0x000000F0)
3. IOxSET (GPIO Port Output Set register) : This is a 32-bit wide register. This
register is used to make pins of Port (PORT0/PORT1) HIGH. Writing one to specific
bit makes that pin HIGH. Writing zero has no effect.

4. IOxCLR (GPIO Port Output Clear register) : This is a 32-bit wide register. This
register is used to make pins of Port LOW. Writing one to specific bit makes that pin
LOW. Writing zeroes has no effect.

Method 1: IO0DIR = (1<<3)


• This is a direct assignment method where the binary value (1) is set directly on the
pin. All the other pins are set to 0. This method should be avoided as the value is
directly being assigned in the register and while P0.3 is assigned as ‘1’, all the other
pins are forced to be assigned ‘0’.
• An alternative to this method is ORing the register and then assigning the value.
This can be done in two ways.

Method 2: IO0DIR | = 0x00000008


• In this method, the hexadecimal value of the register is assigned after ORing the
register with itself. In this way, the other pins other than the desired pin (P0.3 in
this case) are not affected. This method is useful if we want to assign many pins
without affecting the other pins.
Method 3: IO0DIR | = (1<<3)
• This is similar to the above method except that only a single pin is affected.
• Other registers can also be set using the same methods.

Now, we’ll see an example of setting pin 15 of PORT0 i.e. P0.15 as output and drive the pin High.
For this we need to use two registers: IODIR and IOSET.
• IO0DIR | = (1<<15); // Configuring P0.15 as output.
• IO0SET | = (1<<15); // Make the O/P pin P0.15 as High

Examples : a) Configure pin P0.0 to P0.3 as input pins and P0.4 to P0.7 as output pins.
IO0DIR = 0x000000F0;
b) Configure pin P0.4 as an output. Then set that pin HIGH.
IO0DIR = 0x00000010; OR IO0DIR = (1<<4);
IO0SET = (1<<4);
c) Configure pin P0.4 as an output. Then set that pin LOW.
IO0DIR = 0x00000010; OR IO0DIR = (1<<4);
IO0CLR = (1<<4);
write a simple program for turning LED ON or OFF depending on
the status of the pin.
Here, LED is interfaced to P0.0.
A switch is interfaced to P0.1 to change the status of the pin
#include <lpc214x.h>
#include <stdint.h>

int main(void)
{
PINSEL0 = 0x00000000; /* Configuring P0.0 to P0.15 as GPIO */
/* No need for this as PINSEL0 reset value is 0x 00000000 */
IO0DIR = 0x00000001; /* Make P0.0 bit as output bit, P0.1 bit as an in put
pin */
while(1)
{
if ( IO0PIN & (1<<1) ) /* If switch is open, pin is HIGH */
{
IO0CLR = 0x00000001; /* Turn on LED */
}
else /* If switch is closed, pin is LOW */
{
IO0SET = 0x00000001; /* Turn off LED */
}
}
}
Example 2: blink the LEDs repeatedly that are connected to PORT1 pins of the MCU

#include <lpc214x.h>
int delay;
int main (void)
{
PINSEL2 = 0x00000000;
IO1DIR = 0xFFFFFFFF; // All the pins of PORT1 are configured as Output
while (1)
{
IO1SET = 0xFFFFFFFF; // Set Logic 1 to all the PORT1 pins i.e. turn on LEDs
for (delay = 0; delay<500000; delay++)
IO1CLR = 0xFFFFFFFF; // Set Logic 0 to all the PORT1 pins i.e. turn off LEDs
for (delay = 0; delay<500000; delay++)
}
return 0;
}
Note: First, the PORT1 pins are configured as outputs using IO1DIR register. Then in an infinite
loop, the pins (or LEDs connected to them) are turned ON using IO1SET register and turned
OFF using IO1CLR register. A delay is introduced between the turning ON and OFF of the LEDs
using a “for” loop, so that the blinking of LEDs is visible
Example 3: blink the LEDs in serial order

#include "lpc214x.h"
void Delay(unsigned int dms);
unsigned int delay_ms,ledval,n; // Define all your variables here

void Delay(unsigned int dms)


{
delay_ms = dms;
while(delay_ms > 0)
{
delay_ms--;
}
}
void Init_GPIO(void)
{
PINSEL0 = 0x00000000;
PINSEL1 = 0x00000000;
PINSEL2 = 0x00000000;

IO0DIR = 0XFFFFFFFF;
IO1DIR = 0XFFFFFFFF;
}
main()
{ Init_GPIO();
while(1)
{ for(n = 0;n<8 ;n++)
{switch(n)
{case 0: ledval = 0x01010101;
break;
case 1: ledval = 0x02020202;
break;
case 2: ledval = 0x04040404;
break;
case 3: ledval = 0x08080808;
break;
case 4: ledval = 0x10101010;
break;
case 5: ledval = 0x20202020;
break;
case 6: ledval = 0x40404040;
break;
case 7: ledval = 0x80808080;
break;
}
IO0CLR = 0XFFFFFFFF; // LED OFF OF PORT1 ; g_pGPIO0->IOCLR
IO1CLR = 0XFFFFFFFF; // LED OFF OF PORT1
Delay(10000);
IO0SET = ledval; //TURN ON LED OF PORT0
IO1SET = ledval; //TURN ON LED OF PORT1
Delay(10000);
} // end of for loop
} // end of while loop

} // end of main
#include "lpc214x.h"
#include "stdint.h"
unsigned int delay_ms,led_val;
unsigned char index;
unsigned int
mvright[]={0x80808080,0x40404040,0x20202020,0x10101010,0x08080808,0x04040
404,0x02020202,0x01010101,0x00};
void InitLPC(void)
{
PINSEL0 = 0x00L;
IODIR = 0XFFFFFFFF;
}
void Delay(unsigned int dms)
{
delay_ms = dms;
while(delay_ms> 0)
delay_ms--;
}
main()
{
index=0;
InitLPC();
while(1)
{
index&= 0x7;
led_val = mvright[index++];
IOSET =led_val;
Delay(20000);
IOCLR=0xFFFFFFFF;
}
}
Interface a single 7 segment display to count from 0 – 9.

#include "lpc214x.h"
#include "stdint.h"

void delay(unsigned int c)

{
unsigned int a;
for(a=1;a<=60000;a++);
}

int main()
{
PINSEL0 = 0x00000000;
IO0DIR|=0xffffffff;
while(1)
{
int i,j,k,l;
unsigned char a[]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f};

for(j=0;j<10;j++)
{ IO0SET= IO0SET|a[j];

delay(10000);

IO0CLR=a[j];
} // end of for
} // end of while
} // end of main
7 segment display
Interace four 7 segment diaply to count from 0 – 9 without multiplexing.
#include "lpc213x.h"
#include "stdint.h"
void delay(unsigned int c)

{
unsigned int a;
for(a=1;a<=60000;a++);
}
int main()
{
PINSEL0 = 0x00000000;
PINSEL1 = 0x00000000;
PINSEL2 = 0x00000000;
IO0DIR|=0xffffffff;
IO1DIR|=0xffffffff;

while(1)
{
int i,j,k,l;
unsigned char a[]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f};
for(j=0;j<10;j++)
{ IO0SET= IO0SET|a[j]; //4

for(i=0;i<10;i++)
{ //3
IO0SET= IO0SET|(a[i]<<8);
for(k=0;k<=9;k++)
{ //2
IO0SET= IO0SET|(a[k]<<16);
for(l=0;l<=9;l++)
{ //1
IO1SET= IO1SET|(a[l]<<16);
delay(1000);
IO1CLR = IO1CLR|(a[l]<<16);
} //1
IO0CLR= IO0CLR|(a[k]<<16);
} //2
IO0CLR= IO0CLR|(a[i]<<8);
} //3
IO0CLR=a[j];
} //4
} // END OF WHILE
} // END OF MAIN
Interace four 7 segment diaply to count from 0 – 9 with multiplexing.
#include "lpc213x.h"
#include "stdint.h"

#define IO1 0x10000


#define IO2 0x20000
#define IO3 0x40000
#define IO4 0x80000
#define IOX 0xF0000
#define IOXcl 0xFFFFF

//Multiplexed 7segment Display


int count=0x0000;
unsigned int d0,d1,d2,d3;
unsigned char seg[] =
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
void init_gpio()
{
PINSEL0 = 0x00000000;
PINSEL2 = 0x00000000;

IO0DIR = 0XFFFFFFFF;
IO1DIR = 0XFFFFFFFF;
}

void delay()
{
int c = 50000;
while(c) //while count is more than zero loop
{
c--;
}
}
void show_disp()
{
//Digit 0
d0 = count & 0x000F;
IO0CLR = IOXcl;
IO0SET = seg[d0]; //Will display data 4 on 7seg
IO1SET = IOX; //ALL display are OFF
IO1CLR = IO1; //Display1 is made on
delay();
IO1SET = IOX; //ALL display are OFF

//Digit 1
d1 = count & 0x00F0;
d1 >>= 4;
IO0CLR = IOXcl;
IO0SET = seg[d1]; //Will display data 3 on 7seg

IO1SET = IOX; //ALL display are OFF


IO1CLR = IO2; //Display1 is made on
delay();

IO1SET = IOX; //ALL display are OFF


//Digit 2
d2 = count & 0x0F00;
d2 >>= 8;
IO0CLR = IOXcl;
IO0SET= seg[d2]; //Willdisplay data 2 on 7seg
IO1SET = IOX; //ALL display are OFF
IO1CLR = IO3; //Display1 is made on
delay();
IO1SET= IOX; //ALL display are OFF

//Digit 3
d3 = count & 0x0F000;
d3 >>= 12;
IO0CLR = IOXcl;
IO0SET= seg[d3]; //Willdisplay data 1 on 7seg
IO1SET = IOX; //ALL display are OFF
IO1CLR = IO4; //Display1 is made on
delay();
IO1SET = IOX; //ALL display are OFF
}
int main( void )
{

init_gpio();
while(1)
{
show_disp();
count++;
count &= 0xFFFF;
}
}
LCD
Vcc, Vss and VEE
Vcc and Vss provide +5V and ground to our LCD, respectively,
VEE is used for controlling LCD contrast i.e. dimming the brightness or
increasing the brightness of LCD.

RS (Register Select)
There are two very important registers inside the LCD.
The RS pin is used for the selection of these registers.
If RS=0, the instruction command code register is selected, which
allows the user to send commands for the LCD such as clear display,
cursor at home, and so on.
If RS=1, the data register is selected. It allows the user to send data
that is to be displayed on the LCD.
R/W (Read/Write)
R/W inputs allows the user to write information to the LCD or
read information from it.
R/W is set 0 while reading and R/W is set 1 when writing.

E (Enable)
The enable pin is used by the LCD to latch information presented
to its data pins.
When data is supplied to the data pins, a high-to-low pulse must
be applied to this pin in order for the LCD to latch in the data
present at the data pins.
This pulse must be a minimum of 450ns wide.

D0-D7
The 8-bit datapins, D0-D7 are used to send information to the
LCD or read the contents of the LCD’s internal Registers.
Program to display message on LCD

#include "lpc213x.h"
#include "stdint.h"
unsigned int cmd8[] = {0x38,0x0E,0x02,0x01,0x00};
unsigned int msg[] = {'H','e','l','l','o',0x20,'R','I','T',0x20,0x00};
unsigned int lcdval,index,delay_ms;

// define prototypes

void InitLPC(void);
void Delay(unsigned int);

void InitLPC(void)
{

// use the Wizards (see Wizards menu) to configure the on-chip peripherals
PINSEL0 = 0x0000;
IO0DIR = 0XFFFFFFFF;
}
void Delay(unsigned int dms)
{
// the timer has to work for this loop to function
delay_ms = dms;
while(delay_ms > 0)
{
delay_ms--;
}
}

void InitLCD()
{
index=0;
lcdval=cmd8[index];
while(lcdval !=0x0)
{
IO0SET = lcdval;
//Toggle E pin
lcdval |= 0x400;
IO0SET = lcdval;
Delay(500);
IO0CLR=0xFFFF;
index++;
lcdval=cmd8[index];
} }
void ShowMsg()
{
index=0;
lcdval=msg[index];
while(lcdval !=0x0)
{
IO0SET = lcdval;
//Toggle E pin
lcdval |= 0x500;
IO0SET = lcdval;
Delay(500);
IO0CLR=0x400;
index++;
lcdval=msg[index];
}
IO0CLR = 0XF00;
}
void main(void)
{
InitLPC();
// use the Wizards (see Wizards menu) to configure the on-chip peripherals
index=0;
while(1)
{
InitLCD();
ShowMsg();
Delay(5000);

}
}
4x4 keypad interfacing with lpc2148

Rows of the keypad R3-R0 are connected to pins P0.4-P0.7 respectively.


Columns of the keypad C3-C0 are connected to pins P0.0-P0.3
respectively.
Diagram Of Matrix Keypad

Interface 4x4 matrix keypad


with LPC2148.
Flow Chart Of Detecting Pressed
The pressed key will be
displayed on LCD.
// Initial C Source File
#include "lpc214x.h"
#include "stdint.h"

//MKBD tested ok for both ports


// Define all your variables here - donot use variable name as seg[]
unsigned int i,delay_ms,segval;
unsigned char index;
unsigned char lcdval,row,keyscan,keyret,keynum=0;
// define prototypes
void InitLPC(void);
void Delay(unsigned int);

void InitLPC(void)
{

// use the Wizards (see Wizards menu) to configure the on-chip peripherals
//Note H1 is used for MKBD and H2 for 7 seg display for ease of programming
PINSEL0 = 0x00L;
IO0DIR = 0XFFFFFFF0;
}
void Delay(unsigned int dms)
{
// the timer has to work for this loop to function
delay_ms = dms;
while(delay_ms > 0)
{
delay_ms--;
}
}
// This is the keypress data you need to show Hex to 7Segment
unsigned char seg7[] =
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,0x77,0x7c,0x39,0x5e,0x79,0
x71,0x00,0x00,0x00};

// This is the keyboard scan codes to output


unsigned char scan[] = {0xEF,0xDF,0xBF,0x7F,0x00} ;

// This is the response when user presses a key for each row
unsigned char keycode[] =
{0xEE,0xED,0xEB,0xE7,0xDE,0xDD,0xDB,0xD7,0xBE,0xBD,0xBB,0xB7,0x7E,0x7D,0x
7B,0x77,0x00};
void GetKey()
{ row=0;
while(1)
{ IO0CLR = 0xFF;
row &= 0x3;
keyscan=scan[row];
IO0SET = keyscan;
Delay(2);
keyret = IO0PIN;
if (keyscan != keyret) //SCAN 4 bits = E,D,B,7
break; // RET is F= 1111 if nokey press else RET
should be E,D,B,7
row++; //IF send E and recive F no key press
}
for(i=0;i<0x10;i++)
{ if(keycode[i]==keyret)
keynum=i;
}
IO0CLR = 0xFF00; // Connect 7 Segment on H2 with select pin grounded
segval = seg7[keynum];
segval <<= 8;
IO0SET = segval;
}

void main(void)
{
InitLPC();
index=0;
while(1)
{
GetKey();
}
}
DAC
void I2C_INIT(void)
{ PINSEL0 = PINSEL0 | 0x00000050; /* Configure P0.2 and P0.3 as SCL0 and SDA0 respectively */
I2C0CONSET = 0x40; /* Enable I2C */
I2C0SCLL = 0x32; /* I2C data rate 300Khz and 50% duty cycle */
I2C0SCLH = 0x32; /* I2C data rate 300Khz and 50% duty cycle */ }

void I2C_START(void) { I2C0CONSET = 0x20; /* Set Start bit for Start condition */
while ( (I2C0CONSET & 0x08) == 0 ); /* Wait till SI = 1 */
I2C0CONCLR = 0x28; /* Clear Start bit and SI bit */ }
UART in LPC2148
Both the UART modules are identical, except the UART1 block has an
additional full modem interface. This includes all the pins for RS232
compatibility like flow control pins (CTS, RTS) etc.

In order to control the data access and assembly, the UART blocks have two
registers each.

For the transmitter operation, the TX has two special registers called
Transmit Holding Register (THR) and Transmit Shift Register (TSR). In order
to transmit the data, it is first sent to THR and then moved to TSR.

For the receiver operation, the RX has two special registers called Receiver
Buffer Register (RBR) and Receive Shift Register (RSR). When the data is
received, it is first stored in the RSR and then moved to RBR.
UxTHR (UART 0/1 Transmit Holding Register)
The UxTHR is the top byte of the UART0/1 TX FIFO. The top byte
is the newest character in the TX FIFO. The UxTHR is always
Write Only.

UxRBR (UART 0/1 Receiver Buffer Register)


The UxRBR is the top byte of the UART0/1 Rx FIFO. The top byte
of the Rx FIFO contains the oldest character received. The UxRBR
is always Read Only.

UxLCR (UART 0/1 Line Control Register)


The Line Control Register is used to set the format of the data
which is transmitted or received.
UxDLL & UxDLM (UART 0/1 Divisor Latch registers)
These are standard UART0/1 baud rate generator divider
registers. Each of this register holds 8-bit values. Together
these registers form a 16-bit divisor value which will be used
for baud rate generation. UxDLM holds the upper 8-bits and
UxDLL holds the lower 8-bits and the formation is
“[UxDLM:UxDLL]“.

You might also like