Close

Interfacing a Character LCD

A project log for z80ctrl

AVR-based bootloader and IO card for RC2014 retrocomputer

J.B. LangstonJ.B. Langston 12/31/2018 at 16:270 Comments

I've added a few examples for interfacing a character LCD with the z80ctrl IO expander board.  The specific LCD I am using was purchased from Amazon.  However, almost every character LCD you can find will use a standard interface based on the HD44780 chip, and my examples should work with any of them.

Since the LCD has a parallel interface to begin with, one could argue that it's a bit convoluted having the Z80 talk to the AVR over the parallel bus, which converts it to a serial signal to send to the IO expander, which converts it back into a parallel signal to send to the LCD.  To that, I say: Shut up, one! It's my project and I'll do what I want!

The pinout for a character LCD is also fairly standardized.  This is from the LCD I bought:

Hooking up the LCD to the IO expander board is straightforward:

Once it's hooked up, I wrote a simple MBASIC program that prints "hello, world" on the LCD:

10 GOSUB 1000
50 C=&H33:GOSUB 3000: REM RESET SEQUENCE, PART 1
60 C=&H32:GOSUB 3000: REM RESET SEQUENCE, PART 2
70 C=&H28:GOSUB 3000: REM 4-BIT MODE, 2 LINES, 5x8 CHARS
80 C=&HD:GOSUB 3000: REM DISPLAY ON, BLINKING BLOCK CURSOR
90 C=&H1:GOSUB 3000: REM CLEAR DISPLAY
100 INPUT "STRING TO PRINT"; S$
110 GOSUB 5000
120 END

1000 REM INITIALIZE GPIO PORT
1010 OUT 0, 1: REM GPIO CHIP 1
1020 OUT 1, 0: REM DATA DIRECTION REGISTER A
1030 OUT 2, 0: REM ALL OUTPUT
1040 OUT 1, &H12: REM GPIO REGISTER A
1050 RETURN

2000 REM SEND BYTE IN C TO LCD
2010 OUT 2, &H40 OR M OR (C\16) : REM TOP NYBBLE WITH ENABLE HIGH
2020 OUT 2, M OR (C\16) : REM TOP NYBBLE WITH ENABLE LOW
2030 OUT 2, &H40 OR M OR (C AND &HF): REM BOTTOM NYBBLE WITH ENABLE HIGH
2040 OUT 2, M OR (C AND &HF): REM BOTTOM NYBBLE WITH ENABLE LOW
2050 RETURN

3000 REM SEND COMMAND IN C TO LCD
3010 M=0
3020 GOSUB 2000
3030 RETURN

4000 REM SEND CHAR IN C TO LCD
4010 M=&H10
4020 GOSUB 2000
4030 RETURN

5000 REM SEND STRING IN S$ TO LCD
5010 FOR I = 1 TO LEN(S$)
5020 C=ASC(MID$(S$,I,1))
5030 GOSUB 4000
5040 NEXT
5050 RETURN

The BASIC program has several subroutines that illustrate how to interface the LCD:

I have also written an assembly program to retrieve the date and time from the RTC and display it on the LCD. Since it's quite long, I won't reproduce it here, but be sure to check it out if you'd like an example of using the IO expander from Z80 assembly.  The code is heavily commented so it should be easy enough to follow.

Discussions