Hello friends, in this tutorial we are going to interface LCD with 8051 microcontroller but in 4 bit mode. we already interfaced LCD with 8051 in 8 bit and also done scrolling of text in previous tutorials.
And if i need to send 28h then i send first 20h and then 80h.(upper nibble first and lower nibble second).
Let we have 28h in accumulator register and we are going to send it to LCD. So we need to break it. We can break it as 20h (higher nibble) and 80h (lower nibble).
If i perform AND operation of 28h with F0h then it become 20H (upper nibble) and if i swap nibbles of 28h (become 82h) and then do same ANDing then i got 80H (lower nibble).
We can write a routine to perform separation because it needed when we send command and data to LCD. lets call it Separator.i use two memory location to store to upper(U) nibble and lower nibble(L). it will make the program simple and better understandable.
Let make a routine which put data/command on Port and make EN Switching (high to low). this routine not going to tell LCD that it is a command or Data. it only put to LCD whatever you give it.
Here is Pin description of LCD and instruction
- LCD interfacing with 8051 in assembly in 8 bit mode
- Scroll text on a 16x2 LCD with 8051 microcontroller
- First we initialize LCD by sending different command
- To send command we make RS=0[low] and put command on DATA pins of LCD(DB0-BD7)
- Then make EN = 1[high] and after some delay EN = 0[low]. it make a high to low pulse on EN of LCD
- Do same thing to send data but this time RS = 1[high]
- this is called LCD interfacing in 8 bit mode
This is how i connect LCD and other variables
U equ 31H ;memory location to hold upper nibble L equ 32H ;memory location to hold lower nibble Port equ P1 ;data port to connect LCD RS equ P2.0 ;RS pin connection RW equ P2.1 ;RW pin connection EN equ P2.2 ;EN pin connection ;connection of Port ;Port.1-Port.3 (not used) ;Port.4 = DB4 ;Port.5 = DB5 ;Port.6 = DB6 ;Port.7 = DB7
How i send Data and Command
As you can see from connection of LCD and microcontroller that i can send data to LCD in the upper nibble of the port only because lower nibble is not connected. so if i need to send 02H (Two) then i have to send it as 20h. by doing this LCD read only upper nibble of port that is 2.And if i need to send 28h then i send first 20h and then 80h.(upper nibble first and lower nibble second).
How to Break 8 bit Data
4 bit LCD interfacing mode require that we first break 8 bit data in to 4 bit data and then send it to LCD.Let we have 28h in accumulator register and we are going to send it to LCD. So we need to break it. We can break it as 20h (higher nibble) and 80h (lower nibble).
If i perform AND operation of 28h with F0h then it become 20H (upper nibble) and if i swap nibbles of 28h (become 82h) and then do same ANDing then i got 80H (lower nibble).
We can write a routine to perform separation because it needed when we send command and data to LCD. lets call it Separator.i use two memory location to store to upper(U) nibble and lower nibble(L). it will make the program simple and better understandable.
++++++++++++++++++++++++++++++++++++++++++++++++++++ separator: MOV U,A ;save A at temp location U ANL U,#0F0H ;mask it with 0Fh (28h & F0h = 20h) SWAP A ;swap nibble (28h => 82H) ANL A,#0F0H ;mask it with 0fh (82h & f0h = 80h) MOV L,A ;save it at temp location L RET ;return +++++++++++++++++++++++++++++++++++++++++++++++++++++
Move Data/Command to LCD
i write many routine so the code become simpler because long code is easy to understand than shorter and compact one. but you can put all in single routine.Let make a routine which put data/command on Port and make EN Switching (high to low). this routine not going to tell LCD that it is a command or Data. it only put to LCD whatever you give it.
++++++++++++++++++++++++++++++++++++++++++++++++++++ move_to_Port: MOV port,A ;put content of A to port SETB EN ;make EN hight ACALL DELAY ;call a short delay routine CLR EN ;clear EN ACALL DELAY ;short delay RET ;return +++++++++++++++++++++++++++++++++++++++++++++++++++++
Send Command to LCD
Now i need to send command to LCD. if i set rs=0 and send data then LCD consider it as command. let call it lcd_cmd+++++++++++++++++++++++++++++++++++++++++++++++++++++ lcd_cmd: CLR RS ;clear rs, going to send command ACALL separator ;separate the command and save to U and L MOV A, U ;copy U to A ACALL move_to_port ;move content of a to port MOV A, L ;copy L to A ACALL move_to_port ;move content of a to port RET ;return +++++++++++++++++++++++++++++++++++++++++++++++++++++now you can send command easily to LCD. you only need put command in A and call lcd_cmd.
Send Data to LCD
Routine to send data to LCD remain same as to send command. the only thing change that this time RS will be High.+++++++++++++++++++++++++++++++++++++++++++++++++++++ lcd_data: SETB RS ;RS=1, going to send DATA ACALL separator ;separate the data and save to U & L MOV A, U ;copy U to A ACALL move_to_port ;send it to LCD MOV A, L ;copy L to A ACALL move_to_port ;send it to LCD RET ;return +++++++++++++++++++++++++++++++++++++++++++++++++++++
The Delay
Delay have a great role in LCD interfacing with 8051 microcontroller. Because processing speed of LCD and 8051 is not same. And LCD need some time to process the command, and 8051 have to wait. if the delay is not proper and you give command to LCD then LCD will not receive it because it is busy in doing some thing else. let make a short delay routine.+++++++++++++++++++++++++++++++++++++++++++++++++++++ delay: MOV R0, #10H L2: MOV R1,#0FH L1: DJNZ R1, L1 DJNZ R0, L2 RET +++++++++++++++++++++++++++++++++++++++++++++++++++++you can change the value of delay i take it randomly. check datasheet for precise delay.
Ready to launch the Rocket
OK we have all the routine and function. now we only need to initialize the LCD by sending some command and then we can send the data bytes.Here is Pin description of LCD and instruction
Initialization
Before sending any thing to LCD first i need to tell LCD that i am going to interface in 4 bit mode. to do this i first send 20h on the port and make switching of EN. all commands are-- Send 20h to set 4 bit mode
- Send 28h to set 4 bit Interface,2 Line LCD, and 5x7 Font set,
- Send 0ch to set Display ON, Cursor OFF and Blink ON
- Send 06h to set Cursor Position Auto Increment and Cursor Move to Right
- Send 01h to Clear the display and bring cursor to starting location
+++++++++++++++++++++++++++++++++++++++++++++++++++++ init: ACALL delay ;some delay to lcd after power on ACALL delay MOV port, #20h ;send 20h to lcd to set 4 bit mode CLR RS ;after that we can use lcd_cmd SETB EN ;make EN switching ACALL delay CLR EN MOV A, #28H ACALL lcd_cmd MOV A, #0CH ACALL lcd_cmd MOV A, #06H ACALL lcd_cmd MOV A, #01H ACALL lcd_cmd RET +++++++++++++++++++++++++++++++++++++++++++++++++++++
Here is full program to interface LCD with 8051 in 4 bit mode
$mod51 ;+++++++++++++++++++++++++++variables ;++++++++++++++++++++++++++++++++++++ U equ 31 ;memory location to hold upper nibble L equ 32 ;memory location to hold lower nibble Port equ P1 ;data port to connect LCD RS equ P2.0 ;RS pin connection RW equ P2.1 ;RW pin connection EN equ P2.2 ;EN pin connection ;connection of Port ;Port.1-Port.3 (not used) ;Port.4 = DB4 ;Port.5 = DB5 ;Port.6 = DB6 ;Port.7 = DB7 ;+++++++++++++++++++++++++++++++++++++ ORG 0000h CLR RW ACALL init MOV A, #'T' ;SEND "TENTUTS.COM 4BIT" ACALL lcd_data ;in first line of LCD MOV A, #'E' ACALL lcd_data MOV A, #'N' ACALL lcd_data MOV A, #'T' ACALL lcd_data MOV A, #'U' ACALL lcd_data MOV A, #'T' ACALL lcd_data MOV A, #'S' ACALL lcd_data MOV A, #'.' ACALL lcd_data MOV A, #'C' ACALL lcd_data MOV A, #'O' ACALL lcd_data MOV A, #'M' ACALL lcd_data MOV A, #' ' ACALL lcd_data MOV A, #'4' ACALL lcd_data MOV A, #'B' ACALL lcd_data MOV A, #'I' ACALL lcd_data MOV A, #'T' ACALL lcd_data MOV A, #0c0H ;switch to 2nd line of LCD ACALL lcd_cmd MOV A, #'M' ;SEND "MODE USING 2 PORT" ACALL lcd_data ;in SECOND line of LCD MOV A, #'O' ACALL lcd_data MOV A, #'D' ACALL lcd_data MOV A, #'E' ACALL lcd_data MOV A, #' ' ACALL lcd_data MOV A, #'U' ACALL lcd_data MOV A, #'S' ACALL lcd_data MOV A, #'I' ACALL lcd_data MOV A, #'N' ACALL lcd_data MOV A, #'G' ACALL lcd_data MOV A, #' ' ACALL lcd_data MOV A, #'2' ACALL lcd_data MOV A, #'P' ACALL lcd_data MOV A, #'O' ACALL lcd_data MOV A, #'R' ACALL lcd_data MOV A, #'T' ACALL lcd_data SJMP $ ;INFINITE LONG LOOP ;+++++++++++++++++++++++++++++Separator ;++++++++++++++++++++++++++++++++++++++ separator: MOV U,A ;save A at temp location U ANL U,#0F0H ;mask it with 0Fh (28h & F0h = 20h) SWAP A ;swap nibble (28h => 82H) ANL A,#0F0H ;mask it with 0fh (82h & f0h = 80h) MOV L,A ;save it at temp location L RET ;return ;++++++++++++++++++++++++++Move To Port ;++++++++++++++++++++++++++++++++++++++ move_to_Port: MOV port,A ;put content of A to port SETB EN ;make EN high ACALL DELAY ;call a short delay routine CLR EN ;clear EN ACALL DELAY ;short delay RET ;return ;++++++++++++++++++++++++++LCD command ;++++++++++++++++++++++++++++++++++++++ lcd_cmd: CLR RS ;clear rs, going to send command ACALL separator ;separate the command and save to U and L MOV A, U ;copy U to A ACALL move_to_port ;move content of a to port MOV A, L ;copy L to A ACALL move_to_port ;move content of a to port RET ;return ;++++++++++++++++++++++++++++++LCD data ;++++++++++++++++++++++++++++++++++++++ lcd_data: SETB RS ;RS=1, going to send DATA ACALL separator ;separate the data and save to U & L MOV A, U ;copy U to A ACALL move_to_port ;send it to LCD MOV A, L ;copy L to A ACALL move_to_port ;send it to LCD RET ;return ;+++++++++++++++++++++++++Initilization ;++++++++++++++++++++++++++++++++++++++ init: ACALL delay ;some delay to lcd after power on ACALL delay MOV port, #20h ;send 20h to lcd to set 4 bit mode CLR RS ;after that we can use lcd_cmd SETB EN ;make EN switching ACALL delay CLR EN MOV A, #28H ACALL lcd_cmd MOV A, #0CH ACALL lcd_cmd MOV A, #06H ACALL lcd_cmd MOV A, #01H ACALL lcd_cmd RET ;+++++++++++++++++++++++++++++++++Delay ;++++++++++++++++++++++++++++++++++++++ delay: MOV R0, #10H L2: MOV R1,#0FH L1: DJNZ R1, L1 DJNZ R0, L2 RET ;+++++++++++++++++++++++++++++++++++++++ endCircuit diagram of LCD interfacing with 8051 in 4 bit mode
ALERT: here i use 2 different port of 8051 P1 to connect LCD and P2 to signals. if you try this code with using all in single port may be it not work because then EN switch differently and make wrong command read.
Download keil project file, code and proteus simulation files
If you enjoy the post please share it. like and follow use on Facebook and Google. thanX
best explanation about 4bit lcd interfacing on the internet
ReplyDeleteThanks
can one use this code directly in multisim?
ReplyDelete@parasbhanot - glad to know you consider it best explanation... and your most welcome, if you want to write some tutorial (open to very one).
ReplyDelete@mase - As you can see i tested it in proteus. but it will also work in multisim. You can simulate in two different ways.
1. use mutisim simulator and multisim assembler.
2. assemble code with keil assembler and run in multisim simulator (I attach keil project, link HEX file generated by keil to multisim MCU).
I hop it work in both ways for you.
I'm getting garbage data on the display. its showing DToEUE2..... please help. I made the connections as shown. thankyou
ReplyDeletehey buddy i dont know ur name i dont know who u are ,but ur great bro..bless u buddy..
ReplyDeletebut ur code helped me alot to understand the complete code very very clearly.