This second LCD-tutorial is based on 'Introduction to LCD Programming', so you should to read that first.
In the first tutorial we have seen that character LCD's based on the HD44780 chip can be driven in 8bits mode, which requires in total 11 lines from you microcontroller. If we want (or need) to spare some lines for other purposes it is possible to drive the display in 4bits mode, which requires 7 lines. It is possible to use only 6 lines, in which case R/W is tied to GrouND. This configuration is seen many times in projects. Instead of reading the busy flag (which is somewhat trickier than it is in 8 bit modus) we have to use delay loops. These delayloops have to be recalculated when using other oscillator frequencies. In this tutorial we use the somewhat harder solution, making use of the busy flag and being independent of the oscillator frequency. The only drawback using 4 bits is that commands and data have to be sent in two nibbles (4bit parts) to the display, which take slightly more time. In many cases that won't be a problem.
To keep things simple, I will take the examples from the first tutorial, make the necessary changes and only explain the differences.
HARDWARE CONFIGURATION
The only difference with the 8bit version is DB0, DB1, DB2 and DB3 on the displaymodule side. These lines are not
connected to the processor. Leave those lines unconnected, DON'T SHORT THEM TO GROUND as seen in projects where R/W
is tied to ground.
So the initial equates are:
Again, if you want to know how to handle the control lines in your programs, please read the
first tutorial on LCD displays.
In 4-bit mode, we have to read and write databytes and commandbytes in two separate 'nibbles' (4bit parts). To make only
minor changes to the original example, we make two subroutines; one to read two nibbles from the LCD, and the other to
write two nibbles to the LCD. Furthermore, the toggling of the EN-line is also taken to these subroutines, because we
have to toggle for each nibble.
As we see in the WRITE_2_NIBBLES routine, there are some logic instructions (ORL, ANL) so I/O lines P1.0 to P1.3 are not
affected. These lines are thus free for input or output and not affected by this routine.
CHECKING THE BUSY STATUS OF THE LCD
DB4 EQU P1.4
DB5 EQU P1.5
DB6 EQU P1.6
DB7 EQU P1.7
EN EQU P3.7
RS EQU P3.6
RW EQU P3.5
DATA EQU P1
READ_2_NIBBLES:
ORL DATA,#0F0 ;Be sure to release datalines (set outputlatches
;to '1') so we can read the LCD
SETB EN
MOV A,DATA ;Read first part of the return value (high nibble)
CLR EN
ANL A,#0F0h ;Only high nibble is usable
PUSH ACC
SETB EN
MOV A,DATA ;Read second part of the return value (low nibble)
CLR EN
ANL A,#0F0h ;Only high nibble is usable
SWAP A ;Last received is actually low nibble, so put it in place
MOV R7,A
POP ACC
ORL A,R7 ;And combine it with low nibble
RET
WRITE_2_NIBBLES:
PUSH ACC ;Save A for low nibble
ORL DATA,#0F0h ;Bits 4..7 <- 1
ORL A,#0Fh ;Don't affect bits 0-3
ANL DATA,A ;High nibble to display
SETB EN
CLR EN
POP ACC ;Prepare to send
SWAP A ;...second nibble
ORL DATA,#0F0h ; Bits 4...7 <- 1
ORL A,#0Fh ; Don't affect bits 0...3
ANL DATA,A ;Low nibble to display
SETB EN
CLR EN
RET
WAIT_LCD:
CLR RS ;It's a command
SETB RW ;It's a read command
LCALL READ_2_NIBBLES ;Take two nibbles from LCD in A
JB ACC.7,WAIT_LCD ;If bit 7 high, LCD still busy
CLR RW ;Turn off RW for future commands
RET
Previous: 8-bit LCD Programming | Tutorial Contents | Next: Done! |