0% found this document useful (0 votes)
124 views53 pages

C5 - Parallel Input Output Ports Interfacing2

This document provides information on interfacing an LCD display to a PIC microcontroller. It describes the pins of the LCD, including the data pins, enable pin, read/write pin, and register select pin. It explains how to send commands and data to the LCD by manipulating these pins. It also discusses initializing and controlling the LCD, including initializing it for a 2-line display, turning the display and cursor on, clearing the display, and positioning the cursor. Code examples are provided to demonstrate sending commands and data to the LCD with and without checking the busy flag. The document also describes storing character data and commands in ROM and displaying them on the LCD.

Uploaded by

Mifzal Izzani
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)
124 views53 pages

C5 - Parallel Input Output Ports Interfacing2

This document provides information on interfacing an LCD display to a PIC microcontroller. It describes the pins of the LCD, including the data pins, enable pin, read/write pin, and register select pin. It explains how to send commands and data to the LCD by manipulating these pins. It also discusses initializing and controlling the LCD, including initializing it for a 2-line display, turning the display and cursor on, clearing the display, and positioning the cursor. Code examples are provided to demonstrate sending commands and data to the LCD with and without checking the busy flag. The document also describes storing character data and commands in ROM and displaying them on the LCD.

Uploaded by

Mifzal Izzani
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/ 53

C5 - Parallel Input/Output Ports

Interfacing

Objectives
•Describe I/O ports interfacing to LEDs, Switches, 7-
Segment Display, LCD and keyboard interfacing.
•Write the PIC18 programming in C.
•Apply the I/O system interfacing.
TRIS Register
• Used for setting up the Ports as input or output
(PORTA to PORTE)

• If TRISx = 0 ; PORTx = output


• If TRISx = 1 ; PORTx = input
e.g.
TRISBbits.TRISB7=0; //PB7 as output;
TRISBbits.TRISB0=1; //PB1 as input;
TRISC = 0xFF //PC as intput;
TRISD = 0x00 //PD as output;
I/O Ports
Seven Segment
Objectives
• Describe the functions of the pins of a typical LCD
• Interface a LCD to the PIC18
• Describe the key press
• Interface a Keypad to the PIC18

• Why LCD?
• The ability to display numbers, charaters and graphics
• Incorporation of a refreshing controller into the LCD,
thereby relieving the CPU of the task of refreshing the
LCD
• Ease for programming for characters and graphics
The LCD
LCD
Pin
Pin Descriptions
Symbol I/O
- HD44780 Description
model
1 VSS -- Ground
2 VCC -- +5V Power Supply
3 VEE -- Power Supply to Control Contrast
4 RS I RS=0 to Select Command Register
RS =1 to Select Data Register
5 R/W I R/W=0 for Write
R/W=1 for Read
6 E I/O Enable
7 DB0 I/O The 8-bit Data Bus
8 DB1 I/O The 8-bit Data Bus
9 DB2 I/O The 8-bit Data Bus
10 DB3 I/O The 8-bit Data Bus
11 DB4 I/O The 8-bit Data Bus
12 DB5 I/O The 8-bit Data Bus
13 DB6 I/O The 8-bit Data Bus
14 DB7 I/O The 8-bit Data Bus
• LCD screen consist of two lines of16 characters each
• Every character consists of 5x8 or 5x11 dot matrix
• Its’ three memory blocks:
– DDRAM - Display Data RAM
– CGRAM - Character Generator RAM
– CGROM - Character Generator ROM

Model with backlights


CGROM memory
contains default
character map
Cursor Address for Some LCDs

80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F

C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF

16X2 LCD
LCD Control
• R/W (Read/Write)
– R/W = 0: Write information to the LCD
– R/W = 1: Read information from the LCD

• E
– To latch information presented to its data pins
– When data is supplied to data pins, a HIGH-to-LOW
pulse must be applied to the E 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
• RS (Register Select)
– RS = 0: The instruction command code is selected,
allowing the user to send command such as clear
display, cursor at home
– RS = 1: The data register is selected , allowing the user
to send data to be displayed on the LCD.
• D0-D7
– Are used to send information to the LCD or read the
contents of the LCD’s internal register.
• LCD Command (Page 475)
– 01 – clr display sereen
– 02 - return home
– 38 - 2line and 5 x 7
EX
XTAL 2 MHz, for instruction 2 μs
#define LCD PORTB //define data port
#define RS PORTBbits.RB5
#define E PORTBbits.RB4
void SendLCDdata(char data, char rs)
{
LCD = data >>4; //send left nibble
RS = rs; //control RS
E = 0; //pulse E
E = 1;
Delay10TCYx (2); //delay 40 μs
LCD = data & 0x0F; //send right nibble
RS = rs; //control RS
E = 1; //pulse E
E = 0;
Delay10TCYx (2); //delay 40 μs
}
void intLCD(void)
{
char a;
Delay1TCYx (10); //delay 20 ms
for (a=0;a<3;a++)
{
SendLCDdata(0x20, 0); //send 0x20
Delay1TCYx (3); //wait 6 ms
}
SendLCDdata(0x28, 0);
SendLCDdata(0x01, 0);
Delay1TCYx (1);
SendLCDdata(0x0C, 0);
SendLCDdata(0x06, 0);
}
EX
#define LCD PORTB //define data port
#define RS PORTBbits.RB5
#define E PORTBbits.RB4
#define RW PORTBbits.RB6
#define LCD_TRIS TRISB
void SendLCDdataWbusy(char data, char rs)
{
RW =0; //select write mode
LCD = data >>4; //send left nibble
RS = rs; //control RS
E = 1; //pulse E
E = 0;
Delay10TCYx (2); //delay 40 μs
LCD = data & 0x0F; //send right nibble
RS = rs; //control RS
E = 1; //pulse E
E = 0;
Delay10TCYx (2); //delay 40 μs
RW=1; //select read mode
RS=1; //set R/W
LCD_TRIS = 0x0F; //set RB0-RB3 as input
RS=0; //read busy command
E=1; //read high nibble
E=0;
data=LCD; //read busy bit
while(data&8)==8;
{
E=1; //read low nibble
E=0;
E=1; //pulse E
E=0; //read high nibble
data=LCD; //read LCD
}
LCD_TRIS=0; //prgPORTB as output
)
Ex. Sending commands and data to LCD with time delay

How to send characters (command/data) to the LCD without


checking the busy flag. Send letters ‘M’, ‘D’ and ‘E’ to the
LCD using delay.

Hint.
Delay (5 – 10 ms) between issuing character to the LCD
LDELAY for power-up process
SDELAY for the LCD’s enable input
#include <P18f4580.h>
#define ldata PORTD //LCD Data Pin
#define rs PORTBbits.RB0
#define rw PORTBbits.RB1
#define en PORTBbits.RB2

void main()
{
TRISD = 0x00 //PD as output;
TRISB = 0x00 //PB as output;
en =0; //enable idle low
MSDelay(250); //long delay
lcdcmd(0x38) //init. 2 line 5x7matrix
MSDelay(250);
lcdcmd(0x0E) //Display on, cursor on
MSDelay(15);
lcdcmd(0x01) //clear LCD
MSDelay(15);
lcdcmd(0x06) //shift cursor right
MSDelay(15);
lcdcmd(0x86) //line 1,position 6
MSDelay(15);
lcddata(‘M’) //Display letter ‘M’
MSDelay(15);
lcddata(‘D’) //Display letter ‘M’
MSDelay(15);
lcddata(‘E’) //Display letter ‘M’
}
void lcdcmd(unsigned character value)
{
idata = value; //put the value on the pins
rs = 0;
rw = 0;
en = 1; //strobe the enable pin
MSDelay(1);
en =0;
}
void lcddata(unsigned character value)
{
idata = value; //put the value on the pins
rs = 1;
rw = 0;
en = 1; //strobe the enable pin
MSDelay(1);
en =0;
}
void MSDelay(unsigned int itime)
{
insigned int i, j;
for (i=0; i<itime; i++)
for (j=0;J<135; j++)
}
Ex. Sending command or data to LCD using busy flag
Send letters ‘M’, ‘D’ and ‘E’ to the LCD using busy flag

Use RS = 0 to read the busy flag bit to see if the LCD is


ready to receive information.
To read command register, R/W=1, RS=0 and E=L to H.
When busy flag (D7=1), LCD is busy and not accept new
info.
When D7=0, LCD is ready to accept new info either
command or data.
E (Page 479)
Write – negative edge trigger
Read – positive edge trigger
#include <P18f4580.h>
#define ldata PORTD //LCD Data Pin
#define rs PORTBbits.RB0
#define rw PORTBbits.RB1
#define en PORTBbits.RB2
#define busy PORTDbits.RD7 //busy=PD.7
void main()
{
TRISD = 0x00 //PD as output;
TRISB = 0x00 //PB as output;
en =0; //enable idle low
MSDelay(250); //long delay
lcdcmd(0x38) //init. 2 line 5x7matrix
MSDelay(250);
lcdcmd(0x0E) //Display on, cursor on
lcdready(); //check LCD busy flag
lcdcmd(0x01) //clear LCD
lcdready(); //check LCD busy flag
lcdcmd(0x06) //shift cursor right
lcdready(); //check LCD busy flag
lcdcmd(0x86) //line 1,position 6
lcdready(); //check LCD busy flag
lcddata(‘M’) //Display letter ‘M’
lcdready(); //check LCD busy flag
lcddata(‘D’) //Display letter ‘M’
lcdready(); //check LCD busy flag
lcddata(‘E’) //Display letter ‘M’
}
void lcdcmd(unsigned character value)
{
idata = value; //put the value on the pins
rs = 0;
rw = 0;
en = 1; //strobe the enable pin
MSDelay(1);
en =0;
}
void lcddata(unsigned character value)
{
idata = value; //put the value on the pins
rs = 1;
rw = 0;
en = 1; //strobe the enable pin
MSDelay(1);
en =0;
}
void lcdready()
{
TRISD = 0xFF; //PD as input
rs = 0;
rw = 1;
do //wait for busy flag
{
en=1; //strobe the enable pin
MSDelay(1);
en=0;
}while(busy==1);
TRISD=0;
}
void MSDelay(unsigned int itime)
{
insigned int i, j;
for (i=0; i<itime; i++)
for (j=0;J<135; j++)
}
EX Display data in ROM
#include <P18f4580.h>
#define ldata PORTD //LCD Data Pin
#define rs PORTBbits.RB0
#define rw PORTBbits.RB1
#define en PORTBbits.RB2

#pragma romdata mycom=0x300 //ROM addrs


Far rom const char mycom[ ] = (0x0e,0x01,0x06,0x84);

#pragma romdata mydata=0x320 //ROM addrs


Far rom const char mydata[ ] = “Hello”;
void main()
{
unsigned char z=0;
TRISD = 0x00 //PD as output;
TRISB = 0x00 //PB as output;
en =0; //enable idle low
MSDelay(250); //long delay
lcdcmd(0x38) //init. 2 line 5x7matrix
MSDelay(250);
//send out the command
for(;z<4;z++)
{
lcdcmd(mycom[z]);
MSDelay(15);
}
//send out the data
for(z=0;z<5;z++)
{
lcdcmd(mycom[z]);
MSDelay(15);
While(1) //infinite loop
}
void lcdcmd(unsigned character value)
{
idata=value //put the value on the pin
rs = 0;
rw = 0;
en = 1; //strobe the enable pin
MSDelay(1);
en =0;
}
void lcddata(unsigned character value)
{
idata=value //put the value on the pin
rs = 1;
rw = 0;
en = 1; //strobe the enable pin
MSDelay(1);
en =0;
}
void MSDelay(unsigned int itime)
{
insigned int i, j;
for (i=0; i<itime; i++)
for (j=0;J<135; j++)
}
Interfacing the Keyboard
• Organized in a matrix of rows and coloums
• The CPU accesses both rows and coloums thru’
port; therefore with 8-bit ports, an 8 X 8 matrix of
keys can be connected to a microcontroller
• Key pressed: Row and column make a contact
• Key press detection method:
– Interrupt method
– Scanning method
EX
Row RA0 to RA4
Col RB0 to RB2

Rom near char lookup key [ ] =


{
1,4,7,10
2,5,8,0
3,,6, 9,11
)
#define KEYPORT PORTA
#define DELAY 15
void Switch (char bit)
{
do //wait for release
{
while((KEYPORT&bit)!=bit);
Delay1KTCYx(DELAY);
}
while((KEYPORT&bit)!=bit);
do //wait for press
{
while((KEYPORT&bit)==bit);
Delay1KTCYx(DELAY);
}
while((KEYPORT&bit)==bit);
}
unsigned char key(void)
#define MASK 0x0F //set mask
#define row 4
char a;
char keyCode;
PORTB =keyCode=0; //clr PB and keyCode
Switch(MASK) //debounce and wait for any key
PORTB=0xFE //select a left most col
while((PORTA&MASK)==MASK); //while no key is found
{
PORTB=(PORTB<<1)|1; //gets next col
KeyCode +=ROWS //add row tokeycode
}
For (a=1;a!=0;a<<=1)
{
If(PORTA&a)==0)
break;
keyCode++
}
Return lookupkey(keyCode) //lookup
correct keycode
}
Interrupt Method of Key Press Detection
Column (RB4-RB7)

Row (RB0-RB3)

4 X 4 Matrix Keyboard Connection to Ports


Keyboard Debounce

Noise

Stable
EX:
Read the keypad and sends the result to the serial port
Identify the row and column of the pressed key for the
following:
RB3-RB0 = 1110 (Row)
RB7-RB4 = 1011 (Column)

Try This:
RB3-RB0 = 1101 (Row)
RB7-RB4 = 1011
(Column)
#include <P18f4580.h>
void SerTX(unsigned char x);
void RBIF_ISR(void);
void MSDelay(unsigned int millisecs);
Unsigned char keypad[4] [4] = (‘0’,’1’,’2’,’3’,
‘4’,’5’,’6’,’7’
‘8’,’9’,’A’,’B’
‘C’,’D’,’E’,’F’);
#pragma code HiPrio_int=0x0008 //high-priority interrupt
void my_HiPrio_int (void)
{
_asm
GOTO chk_isr
_endasm
}
#pragma code

#pragma interrupt chk_isr //which ISR


void chk_isr(void)
{
if (INTCON2bits.RBIF==1) //RBIF caused interrupt;
RBIF_ISR( ); //yes goto RBIF_ISR
}
#pragma code
void main()
{
TRISD = 0x00 //PD as output;
INTCON2bits.RBPU=0 //enable PB pullup
TRISB = 0xF0; //PB as input and output;
PORTB = 0xF0; //PB clear PB low
while( PORTB = 0xF0); //wait until key not pressed
TXSTA = 0x20; //low baud rate 8-bit
SPBRG = 15 //9600 baud rate
TXSTAbits.TXEN = 1; //enable tx
RCSTAbits.SPEN = 1; //enable serial port
INTCONbits.RBIE=1; //enable PB int on change
INTCONbits.GIE=1; //enable all int globally
while(1)
}
void RBIF_ISR(void) //which key pressed
{
insigned char temp, COL=0,ROW=4;
MSDelay(15);
temp=PORTB //get column
temp ^=0xF0; //invert high nibble
if(!temp) return; //if false alarmreturn
while(temp<<=1) COL++ //find the column
PORTB=0xFE; //gound row 0
if(PORTB != 0xFE) //did high nibble change
ROW=0; //yes row 0
else{
PORTB=0xFD; //gound row 1
if(PORTB != 0xFE) //did high nibble change
ROW=1; //yes row 1
else
else{
PORTB=0xFB; //gound row 2
if(PORTB != 0xFB) //did high nibble change
ROW=2; //yes row 2
else{
PORTB=0xF7; //gound row 3
if(PORTB != 0xF7) //did high nibble change
ROW=3; //yes row 3
}
}
}
if(ROW<4) //find valid row
serTX(keypad[row][col]) //then send char
while(PORTB!=0xF0) PORTB=0xF0 //wait for release
INTCONbits.RBIF=0; //reset flag
)
void SeTX(unsigned char x) //send char
{
while(PIR1bits.TXIF!=1); //wait until ready
TXREG=x; //send char out serialport
}

void MSDelay(unsigned int millisecs)


{
insigned int i, j;
for (i=0; i<millisecs; i++)
for (j=0;J<135; j++)
}

You might also like