HD44780A00 20x4 LCD - 40th chars?

I recently purchased a 20x4 backlit LCD from a surplus shop. It seems to be in good working order, however, I am having difficulty getting the last character in the 3rd and 4th lines to display properly.

The controller is a legit HD44780A00, and there are four HD44100H ICs on it as well. Unfortunately I don't know the manufacturer of the module, but it has "V0020240 Rev. B" silkscreened on the back.

I'm using the 8-bit interfacing method, connecting the display to the dedicated LCD port on my brand-new Rev.5 8051 devkit from pjrc.com. I took the website-provided 2x15 display code and modified it to output a single character to a specific LCD address, allowing me to randomly step through memory to try and determine the memory map for the device.

Rows 1 and 2 work as expected:

Row 1: 01h - 14h (20 chars) Row 2: 41h - 54h (20 chars)

Rows 3 and 4 are problematic:

Row 3: 15h - 27h (19 chars) - 28h does not work Row 4: 55h - 67h (19 chars) - 68h does not work.

Oddly, 40h or 28h puts a character at the end of the 4th row, and I need to use 6Ah to get something at the end of the 3rd row.

Could this be an oddball hardware problem, or am I missing something?

Here's the code, if that may help:

.equ locat, 0xF300 ;Location for this program .equ lcd_command_wr, 0xFE00 .equ lcd_status_rd, 0xFE01 .equ lcd_data_wr, 0xFE02 .equ lcd_data_rd, 0xFE03 .equ esc, 0x003E ;paulmon2's check for esc key

.org locat .db 0xA5,0xE5,0xE0,0xA5 ;signiture bytes .db 35,255,0,0 ;id (35=prog) .db 0,0,0,0 ;prompt code vector .db 0,0,0,0 ;reserved .db 0,0,0,0 ;reserved .db 0,0,0,0 ;reserved .db 0,0,0,0 ;user defined .db 255,255,255,255 ;length and checksum (255=unused) .db "4x20 LCD Test",0 ;max 31 characters, plus the zero .org locat+64 ;executable code begins here

startup:

.equ cout, 0x0030 ; cout: print byte in accumulator to serial port .equ cin, 0x0032 ; cin: get a character from the serial port (blocking) .equ phex, 0x0034 ; phex: print accumulator value as 2-digit hex .equ phex16, 0x0036 ; phex16: print DPTR value as

4-digit hex .equ pstr, 0x0038 ; pstr: print string pointed to by DPTR .equ newline, 0x0048 ; newline: send cr+lf to serial port .equ ghex, 0x003A ; ghex: read ascii, store in acc. as hex

.equ lcd_clear_cmd, 0x01 ;clears display .equ lcd_home_cmd, 0x02 ;put cursor at home position .equ lcd_on_cmd, 0x0C ;turn on display (cursor off) .equ lcd_left_move_cmd, 0x10 .equ lcd_right_move_cmd, 0x14 .equ lcd_left_shift_cmd, 0x18 .equ lcd_right_shift_cmd, 0x1C .equ lcd_config_cmd, 0x38 ;configure, 8 bit interface, 2 lines, 5x7 digits

main_loop:

lcd_init: lcall lcd_busy mov dptr, #lcd_command_wr mov a, #lcd_config_cmd movx @dptr, a

lcall lcd_busy mov dptr, #lcd_command_wr mov a, #lcd_clear_cmd movx @dptr, a

lcall lcd_busy mov dptr, #lcd_command_wr mov a, #lcd_on_cmd movx @dptr, a

lcall lcd_busy mov dptr, #lcd_command_wr mov a, #lcd_left_shift_cmd movx @dptr, a

lcall lcd_busy mov dptr, #lcd_command_wr mov a, #0x81 movx @dptr, a

begin: mov dptr, #mesg_start lcall pstr

getaddr: lcall ghex lcall newline jc quit

setaddr: orl a, #0x80 ; msb set for set DD RAM address mov dptr, #lcd_command_wr ; set LCD write port movx @dptr, a ; and output character to LCD sendstr: mov dptr, #mesg1 acall lcd_pstr

quit: ljmp 0

; mesg_start: data sent to serial port at program initialization

mesg_start: .db "Enter screen address to try: ",0

; mesg1 : data sent to LCD during main loop

mesg1: .db "+",0

lcd_pstr: clr a movc a, @a+dptr inc dptr jz lcd_pstr_end push dpl push dph acall lcd_cout pop dph pop dpl sjmp lcd_pstr lcd_pstr_end: ret

lcd_cout: push acc acall lcd_busy mov dptr, #lcd_data_wr pop acc movx @dptr, a ret

lcd_busy: mov dptr, #lcd_status_rd movx a, @dptr jb acc.7, lcd_busy ret

Reply to
Gauntlet
Loading thread data ...

Figured it out myself - the LCD initialization routine has specified a screen-shift command. Took that out - works great.

Reply to
Gauntlet

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.