LCD interfacing with Microcontrollers tutorial - 4-bit Mode
4-bit Initialization
Initialization of LCD is completed only after the reset sequence and basic initialization commands. We have already discussed about the reset sequence of the lcd in the previous section. So lets look at the programming now...Assembly Program
;In this whole 4-bit tutorial LCD is connected to ;my controller in following way... ;D4 - P3.0 ;D5 - P3.1 ;D6 - P3.2 ;D7 - P3.3 ;EN - P3.7 ;RS - P3.5 lcd_port equ P3 ;LCD connected to Port3 en equ P3.7 ;Enable connected to P3.7 rs equ P3.5 ;Register select to P3.5 lcd_reset: ;LCD reset sequence mov lcd_port, #0FFH mov delay,#20 ;20mS delay acall delayms mov lcd_port, #83H ;Data = 30H, EN = 1, First Init mov lcd_port, #03H ;Data = 30H, EN = 0 mov delay,#15 ;Delay 15mS acall delayms mov lcd_port, #83H ;Second Init, Data = 30H, EN = 1 mov lcd_port, #03H ;Data = 30H, EN = 0 mov delay,#5 ;Delay 5mS acall delayms mov lcd_port, #83H ;Third Init mov lcd_port, #03H mov delay,#5 ;Delay 5mS acall delayms mov lcd_port, #82H ;Select Data width (20H for 4bit) mov lcd_port, #02H ;Data = 20H, EN = 0 mov delay,#5 ;Delay 5mS acall delayms ret lcd_init: acall lcd_reset ;Call LCD Reset sequence mov a,#28H ;4-bit, 2 line, 5x7 dots acall lcd_cmd ;Call LCD command mov a,#0CH ;Display ON cursor OFF acall lcd_cmd ;Call LCD command mov a,#06H ;Set entry mode (Auto increment) acall lcd_cmd ;Call LCD command mov a,#80H ;Bring cursor to line 1 acall lcd_cmd ;Call LCD command ret
C Program
//The pins used are same as explained earlier
#define lcd_port P3
//LCD Registers addresses
#define LCD_EN 0x80
#define LCD_RS 0x20
void lcd_reset()
{
lcd_port = 0xFF;
delayms(20);
lcd_port = 0x03+LCD_EN;
lcd_port = 0x03;
delayms(10);
lcd_port = 0x03+LCD_EN;
lcd_port = 0x03;
delayms(1);
lcd_port = 0x03+LCD_EN;
lcd_port = 0x03;
delayms(1);
lcd_port = 0x02+LCD_EN;
lcd_port = 0x02;
delayms(1);
}
void lcd_init ()
{
lcd_reset(); // Call LCD reset
lcd_cmd(0x28); // 4-bit mode - 2 line - 5x7 font.
lcd_cmd(0x0C); // Display no cursor - no blink.
lcd_cmd(0x06); // Automatic Increment - No Display shift.
lcd_cmd(0x80); // Address DDRAM with 0 offset 80h.
}
Sending Dommand/Data to LCD in 4-bit mode
Assembly Program
lcd_cmd: ;LCD command Routine mov temp,a ;Save a copy of command to temp swap a ;Swap to use higher nibble anl a,#0FH ;Mask the first four bits add a,#80H ;Enable = 1, RS = 0 mov lcd_port,a ;Move it to lcd port anl a,#0FH ;Enable = 0, RS = 0 mov lcd_port,a ;Move to lcd port mov a,temp ;Reload the command from temp anl a,#0FH ;Mask first four bits add a,#80H ;Enable = 1 mov lcd_port,a ;Move to port anl a,#0FH ;Enable = 0 mov lcd_port,a ;Move to lcd port mov delay,#1 ;delay 1 ms acall delayms ret lcd_dat: ;LCD data Routine mov temp,a ;Keep copy of data in temp swap a ;We need higher nibble anl a,#0FH ;Mask first four bits add a,#0A0H ;Enable = 1, RS = 1 mov lcd_port,a ;Move to lcd port nop clr en ;Enable = 0 mov a,temp ;Reload the data from temp anl a,#0FH ;we need lower nibble now add a,#0A0H ;Enable = 1, RS = 1 mov lcd_port,a ;Move to lcd port nop clr en ;Enable = 0 mov delay,#1 ;Delay 1mS acall delayms ret
C Program
void lcd_cmd (char cmd)
{
lcd_port = ((cmd >
>
4) & 0x0F)|LCD_EN;
lcd_port = ((cmd >
>
4) & 0x0F);
lcd_port = (cmd & 0x0F)|LCD_EN;
lcd_port = (cmd & 0x0F);
delayus(200);
delayus(200);
}
void lcd_data (unsigned char dat)
{
lcd_port = (((dat >
>
4) & 0x0F)|LCD_EN|LCD_RS);
lcd_port = (((dat >
>
4) & 0x0F)|LCD_RS);
lcd_port = ((dat & 0x0F)|LCD_EN|LCD_RS);
lcd_port = ((dat & 0x0F)|LCD_RS);
delayus(200);
delayus(200);
}