Utilizing
Alphanumeric LCD Displays
In this tutorial I am going to target
peoples who do not have much experience in embedded designs. Interfacing a LCD
display is not a tough work if you know C language and Data sheet reading
mechanism. In internet you can find the milliner of tutorials about LCD interfacing
but these all are very complicated because every tutorial writer uses another
library written by a person they ever never known. Therefore they don’t know
how to minimize the code effectively. Through this tutorial I wish to give very
simple algorithm to interface any type of alphanumeric displays. I am sure you
can write an own code for LCD interfacing after this tutorial.
Hardware Interfacing
Hint:
In according to above diagram, RW is connected
to ground .Because in my algorithm I wish to data transfer towards PIC to LCD
only.
If you use RC port higher 4-bits,
you should have discipline to connect it to LCD higher pin numbers. Otherwise,
if you user lower 4 bits, you should have discipline to connect it to LCD lower
pin numbers
For adjusting contrast of the
LED, you can use a 1K variable resister to VEE pin. When you are working with
LCD, it contrast should be low.( To increase the deadline on the LCD)
Identify LCD pin functions (20x4)
Data busses(D0-D7)
I have used 4-bit interfacing method.
That mean, though the LCD has eight data busses, we have used only four data
busses. By using these buses we can pass data, PIC to LCD or LCD to PIC. LCD
module has a standard method to give instructions. Therefore, first we have to
give command and secondly we can give data. However, data busses are the only
one communication way. Therefore there is another variable which can identify
data or command.
Register select (RS)
RS is the abbreviation name of Register
select. Its function is identify, which are data or command. If RS has zero (0)
bit value, data busses are going to communicate commands. If RS has one (1) bit
value, data busses are going to communicate data. In according to before
paragraph, these buses can pass data, PIC to LCD or LCD to PIC. So that, there
should be another variable to identify what is the exact direction data are
being travelling.
Read /write(RW)
R/w is the abbreviation name of Read
/write. Its function is identifying the data travelling direction. If R/w has
zero (0) bit value, data busses are going to communicate commands or data, PIC
to LCD. If R/w has one (1) bit value, data busses are going to communicate
commands or data, LCD to PIC.
Enable (E)
E is the abbreviation name of enable.
Its function is getting external data from data busses or giving internal data
to data busses. When it is in falling edge situation, that particular data
communication will occur. That mean, it occurs when E terminal voltage reduced
5V to 0V.
Instruction set
To work
LCD correctly we have to give some kind of instructions to LCD module by using
PIC. By using these instructions we can configure it to data display.
Since we
use 4bit interface mode, we use only four data busses. But all instruction set
command has eight bits. Therefore, 8 bit command should communicate correctly
with LCD by using 4 busses. You will see in function set instruction which
is last three most significant bits has a code such as 001. That code
identifies what the given instruction set command is. Therefore, first we should commutate last
four most significant bits then can be commutated first four bits.
Hint: - If you
use last 4-bit of a port as data busses, you have to swap 8-bit after the first
pulse calling. If you use first 4-bit of a port as data busses, you have to
swap 8-bit before the first pulse calling.
After the command given, RS should make as zero.
Then it will identify given thing as instructions. Then RW should make as zero
and it will identify data transferring direction as PIC to LCD. Next step is
8-bit code converting correctly to 4-bit code. After that, display will get
given data by PIC through the data busses when E is in falling edge
Function set
Function set instructions gives information
about size of font, number of lines and interfacing method.
0
|
0
|
1
|
DL
|
N
|
F
|
*
|
*
|
DL
|
DL=0 ; four bit interface
|
DL=1 eight bit interface
|
N
|
N=0
;0ne duty line
|
N=1; two duty line
|
F
|
F=0 ; 5x7 dots
|
F=1 ; 5x10 dots
|
In
our program since we used four bit interfacing method, DL should be zero, and, both
of N and F should be one since we used two lines with 5 by 10 sizes.
Code for
function set
0
|
0
|
1
|
0
|
1
|
1
|
0
|
0
|
Display on\off
Display
on\off instruction gives information about curser off\on, curser blink on\off
and display on \off.
0
|
0
|
0
|
0
|
1
|
D
|
C
|
B
|
D
|
D=0 ; Display off
|
D=1 Display ON
|
C
|
C=0
;curser off
|
C=1; curser ON
|
B
|
B=0 ; curser blink off
|
B=1 ; curser blink ON
|
Code for Display
on\off
0
|
0
|
0
|
0
|
1
|
1
|
1
|
1
|
Display clear
Code for Display
clear
0
|
0
|
0
|
0
|
0
|
0
|
0
|
1
|
Entry
mode set
Entry
mode set instruction gives
information about Sets cursor move direction, specifies to shift the display
.These operations are performed during data read/write.
0
|
0
|
0
|
0
|
0
|
0
|
I/D
|
S
|
I/D
|
I/D=0 ; Decrement cursor position
|
I/D=1
Increment cursor position
|
S
|
S=0
;No display shift
|
S=1; display shift
|
Code for Entry
mode set
0
|
0
|
0
|
0
|
0
|
0
|
1
|
0
|
Algorithm
#include<p18f2520.h>
#include <delays.h>
#include <delays.h>
/*PIC 18f2520 CONFIGURATION BIT SET IN MANUAL */
#define E LATBbits.LATB2 // PORTB BIT 2 DEFINE AS E
#define RS LATBbits.LATB1// PORTB BIT 1 DEFINE AS RS
void lcd_int (void);
void send_cmd2 (unsigned char cmd2);
void LCD_send(unsigned char ch);
void send_data (void);
void pulse (void);
unsigned char l1=0x08,l2=0xC0,l3=0x94,l4=0xD4; //4 ROWS STARTING ADDRESS
void send_char (unsigned char dat);
void SendString(unsigned char i,char *);
char text[]={"N.A SANUJI KALHAN"};// TEXTS NEED TO DISPLAY
char text1[]={"SRI LANKAN DUDE"}; // TEXTS NEED TO DISPLAY
/*-----------------------------------------------------------------------*/
void main()
{
ADCON1=0x0f; // ALL PORTS ARE DIGITAL
TRISC=0 ; // PORTC OUTPUT
TRISB=0 ; // PORTB OUTPUT
E=0 ;
lcd_int(); // CALL FOR LCD initiation
ADCON1=0x0f; // ALL PORTS ARE DIGITAL
TRISC=0 ; // PORTC OUTPUT
TRISB=0 ; // PORTB OUTPUT
E=0 ;
lcd_int(); // CALL FOR LCD initiation
SendString(l2+2,text); // SHIFT 2 COLUMNS OF ROW 2 AND DISPLAY TEXT
SendString(l3+3,text1);// SHIFT 3 COLUMNS OF ROW 3 AND DISPLAY TEXT1
while(1); // FOREVER HERE
SendString(l3+3,text1);// SHIFT 3 COLUMNS OF ROW 3 AND DISPLAY TEXT1
while(1); // FOREVER HERE
}
/*-----LCD initialization------ */
void lcd_int (void)
void lcd_int (void)
{
send_cmd2(0b0000000001); // CLEAR DISPLAY
Delay1KTCYx(310);
send_cmd2(0b0000000010);
Delay1KTCYx(310);
send_cmd2(0b0000000110);
Delay1KTCYx(1);
send_cmd2(0b0000001110);
Delay1KTCYx(1);
send_cmd2(0b0000101100);
Delay1KTCYx(1);
}
send_cmd2(0b0000000001); // CLEAR DISPLAY
Delay1KTCYx(310);
send_cmd2(0b0000000010);
Delay1KTCYx(310);
send_cmd2(0b0000000110);
Delay1KTCYx(1);
send_cmd2(0b0000001110);
Delay1KTCYx(1);
send_cmd2(0b0000101100);
Delay1KTCYx(1);
}
/*-----SENDING COMMANDS--------- */
void send_cmd2 (unsigned char cmd2)
{
RS=0;
LCD_send(cmd2);
}
void send_cmd2 (unsigned char cmd2)
{
RS=0;
LCD_send(cmd2);
}
/*---SENDING DATA------- */
void send_char (unsigned char dat )
{
RS=1;
LCD_send(dat);
}
void send_char (unsigned char dat )
{
RS=1;
LCD_send(dat);
}
/*---DATA OR COMMAND PACK TO 4-BIT MODE------- */
void LCD_send(unsigned char cmd)
{
unsigned char cmd2;
cmd2=cmd;
Nop();
TRISC=0;
LATC=LATC&0b00001111;
cmd=cmd&0b11110000;
LATC=LATC|cmd;
Nop();
pulse();
{
unsigned char cmd2;
cmd2=cmd;
Nop();
TRISC=0;
LATC=LATC&0b00001111;
cmd=cmd&0b11110000;
LATC=LATC|cmd;
Nop();
pulse();
LATC=LATC&0b00001111;
cmd2 =cmd2 <<4;
cmd2=cmd2&0b11110000;
LATC=LATC|cmd2;
Nop();
pulse();
cmd2 =cmd2 <<4;
cmd2=cmd2&0b11110000;
LATC=LATC|cmd2;
Nop();
pulse();
Nop();
Delay10TCYx(1000);
Nop();
Delay10TCYx(1000);
Nop();
}
/*--ENABLE TO DATA acquisition */
void pulse (void)
{
Delay10TCYx(100);
E=1;
Delay10TCYx(100);
E=0;
Delay10TCYx(100);
}
/*------SEND DATA AND ITS POINTER----------- */
void SendString(unsigned char i,char *ptr)
{ send_cmd2(i);
while(*ptr!=0)
{
send_char(*ptr);
ptr++;
}
}
void SendString(unsigned char i,char *ptr)
{ send_cmd2(i);
while(*ptr!=0)
{
send_char(*ptr);
ptr++;
}
}
After successful coding, text can be seen as following



