otacon14112
Experienced Member
I have a blue background with white character 20x4 AMC2004A. From what I've read, it's based on the HD44780U chip. I've read tutorial after tutorial, and the datasheet for both the AMC2004A and the HD44780U.
I really hate to ask this here. It's basically admitting defeat. But I've spent dozens of hours rewiring, and recompiling code, and just can't get this darn thing to work (the way I want it to). I've tried 4-bit, and 8-bit mode.
I've gone back to the drawing board - no kidding - probably 100 times, changing this or that. I wish I could tell you EVERYTHING I've tried, but that's impossible, due to the sheer amount of times I've tried things.
My basic scenario:
I'm working on this 8088-based homebrew computer, and I've been using the 8255 as the output device. At first, I tried using the display in 4-bit mode, using the 4-7 data lines on the display hooked up to the same output lines on the 8255. I used the 8255's pins 0-2 for RS, R/W, and enable.
When that didn't work, I hooked all the data lines to their corresponding lines on the 8255's port C, and I used address lines 4, 5, and 6 for the 3 control signals, and that still didn't work. I suspected it might have been a slight timing issue, so I inverted all (4, 5, and 6) twice with a 74LS04, which made no difference.
I was hoping it was just a bad 8255, but I know it works because I tried both ports B and C, and both work fine with another program hooked up to some 7-segment LEDs.
I'll post some code here to show the last version of the 2 programs I wrote. The assembler I'm using is nasm.
I wasn't able to find any sites explaining how to do this in x86 assembly. All the results I got were for microcontrollers.
But anyway, here is my code:
I know it can display stuff, because when I kept pushing the reset button on my breadboard, it showed random stuff on the screen sometimes. I have rarely been as frustrated with something that I know should work as this. To make matters more complicated, I've seen several different ways to initialize this. I have tried to follow the initialization sequences depicted in the AMC2004A datasheet, as well as the HD44780U datasheet. I tried the troubleshooting suggestions Dennis Che recommended in his ebook "All About Liquid Crystal Displays – Character Models Vol 2".
I'm this close to giving up on the darn LCD. I don't think I should have to waste a microcontroller on something that a computer should be able to control. I'm starting to lean more toward making my own primitive VGA board at this point, modeled closely after the one shown here: http://www.lucidscience.com/pro-vga%20video%20generator-1.aspx
But I still want to beat this thing and make it work. Anybody have any wild ideas about what might be wrong? Oh, and I put a 10 K ohm pot for the contrast, and a 4.7 uF capacitor between the 5V line and the ground line of the LCD. Nothing made a difference. Thanks
I will upload a picture of the schematic later on when I wake up. It's getting late now.
I really hate to ask this here. It's basically admitting defeat. But I've spent dozens of hours rewiring, and recompiling code, and just can't get this darn thing to work (the way I want it to). I've tried 4-bit, and 8-bit mode.
I've gone back to the drawing board - no kidding - probably 100 times, changing this or that. I wish I could tell you EVERYTHING I've tried, but that's impossible, due to the sheer amount of times I've tried things.
My basic scenario:
I'm working on this 8088-based homebrew computer, and I've been using the 8255 as the output device. At first, I tried using the display in 4-bit mode, using the 4-7 data lines on the display hooked up to the same output lines on the 8255. I used the 8255's pins 0-2 for RS, R/W, and enable.
When that didn't work, I hooked all the data lines to their corresponding lines on the 8255's port C, and I used address lines 4, 5, and 6 for the 3 control signals, and that still didn't work. I suspected it might have been a slight timing issue, so I inverted all (4, 5, and 6) twice with a 74LS04, which made no difference.
I was hoping it was just a bad 8255, but I know it works because I tried both ports B and C, and both work fine with another program hooked up to some 7-segment LEDs.
I'll post some code here to show the last version of the 2 programs I wrote. The assembler I'm using is nasm.
I wasn't able to find any sites explaining how to do this in x86 assembly. All the results I got were for microcontrollers.
But anyway, here is my code:
Code:
; ************************************************
; * *
; * A PROGRAM TO EXPERIMENT WITH MY LCD DISPLAY *
; * *
; ************************************************
;*****************************************************************************
; *
; USING 8-BIT MODE *
; *
; Address lines used for control signals: *
; A6 A5 A4 *
; RS R/W EN Hex Operation *
; ** *** ** *** ********* *
; 0 0 1 1h IR write as an internal operation (display clear, etc.)*
; 0 1 1 3h Read busy flag (DB7) and address counter (DB0 to DB7) *
; 1 0 1 5h Write data to DDRAM or CGRAM (DR to DDRAM or CGRAM) *
; 1 1 1 7h Read data from DDRAM or CGRAM (DDRAM or CGRAM to DR) *
; *
; Initialization sequence *
; *
; 00111000b 38h *
; 00111000b 38h *
; 00001111b Fh *
; 00000001b 1h *
; 00000111b 7h *
; *
;*****************************************************************************
;0x0AFF = approx. 50 ms
; 2815 (decimal) 20 Hz
;0x006F = approx. 2 ms
; 111 (decimal) 500 Hz
;0x0037 = approx. 1 ms
; 55 (decimal) 1 KHz
start: mov al,90h ;This sets the 8255 to operate
;in Mode 0 (basic input output)
;with port 0 as an input and
out 03h,al ;ports 1 and 2 as outputs.
mov bx,0x0000
mov cx,0x0AFF ;Wait about 50 ms.
jmp begin ;Jump to the main loop.
waitasec: mov word [bx],cx ;Reset the countdown timer.
waitasec1: dec word [bx] ;Decrement it by 1 each time.
cmp word [bx],00h ;If the timer has counted down
;all the way, return to the
;'nextloop' label so that it
;can move on to the next hex
;value to display on the LEDs.
jnz waitasec1 ;If the counter hasn't counted
;down to 00h yet, keep going.
ret ;Here is where the zero flag
;is checked. If the timer has
;reached 00h, go to 'nexthex'.
init_lcd: call waitasec ;Start the timer.
mov al,0x38
out 12h,al
mov cx,0x006F ;Wait about 2 ms.
call waitasec ;Start the timer.
mov al,0x38
out 12h,al
mov cx,0x006F ;Wait about 2 ms.
call waitasec ;Start the timer.
mov al,0x38
out 12h,al
mov cx,0x006F ;Wait about 2 ms.
call waitasec ;Start the timer.
mov al,0x0F
out 12h,al
mov cx,0x006F ;Wait about 2 ms.
call waitasec ;Start the timer.
mov al,0x01
out 12h,al
mov cx,0x006F ;Wait about 2 ms.
call waitasec ;Start the timer.
mov al,0x07
out 12h,al
call waitasec ;Start the timer.
ret
begin: call init_lcd ;Initialize the LCD screen.
mov al,0x82
out 12h,al ;Set DDRAM address to 02h
mov cx,0x006F ;Wait about 2 ms.
call waitasec ;Make sure LCD event is done.
mov al,0x48
out 52h,al ;Output "H"
call waitasec ;Make sure LCD event is done.
mov al,0x69
out 52h,al ;Output "i"
call waitasec ;Make sure LCD event is done.
mov al,0x0C
out 12h,al ;Turn display on
call waitasec ;Make sure LCD event is done.
jmp $
times 2032- ($-$$) db 0
jmp start
times 12 db 0
Code:
; ************************************************
; * *
; * A PROGRAM TO EXPERIMENT WITH MY LCD DISPLAY *
; * *
; ************************************************
;*****************************************************************************
; *
; USING 4-BIT MODE *
; *
; R B W *
; D2 D1 D0 *
; RS R/W EN Hex Operation *
; ** *** ** *** ********* *
; 0 0 1 1h IR write as an internal operation (display clear, etc.)*
; 0 1 1 3h Read busy flag (DB7) and address counter (DB0 to DB7) *
; 1 0 1 5h Write data to DDRAM or CGRAM (DR to DDRAM or CGRAM) *
; 1 1 1 7h Read data from DDRAM or CGRAM (DDRAM or CGRAM to DR) *
; *
; Wait 40 ms *
; 0011 0001b 31h *
; *
; Wait 39 us *
; 0010 0001b 21h *
; 1000 0001b 81h *
; *
; Wait 39 us *
; 0010 0001b 21h *
; 1000 0001b 81h *
; *
; Wait 37 us *
; 0000 0001b 01h *
; 1111 0001b F1h *
; *
; Wait 37 us *
; 0000 0001b 01h *
; 0001 0001b 11h *
; *
; Wait 1.53 ms *
; 0000 0001b 01h *
; 0111 0001b 71h *
; *
;*****************************************************************************
;0x0AFF = approx. 50 ms
; 2815 (decimal) 20 Hz
;0x006F = approx. 2 ms
; 111 (decimal) 500 Hz
;0x0037 = approx. 1 ms
; 55 (decimal) 1 KHz
start: mov al,90h ;This sets the 8255 to operate
;in Mode 0 (basic input output)
;with port 0 as an input and
out 03h,al ;ports 1 and 2 as outputs.
mov bx,0x0000
mov cx,0x0AFF ;Wait about 50 ms.
jmp begin ;Jump to the main loop.
waitasec: mov word [bx],cx ;Reset the countdown timer.
waitasec1: dec word [bx] ;Decrement it by 1 each time.
cmp word [bx],00h ;If the timer has counted down
;all the way, return to the
;'nextloop' label so that it
;can move on to the next hex
;value to display on the LEDs.
jnz waitasec1 ;If the counter hasn't counted
;down to 00h yet, keep going.
ret ;Here is where the zero flag
;is checked. If the timer has
;reached 00h, go to 'nexthex'.
init_lcd: call waitasec ;Start the timer.
mov al,31h
out 02h,al
mov cx,0x006F ;Wait about 2 ms.
call waitasec ;Start the timer.
mov al,21h
out 02h,al
call waitasec ;Start the timer.
mov al,81h
out 02h,al
call waitasec ;Start the timer.
mov al,21h
out 02h,al
call waitasec ;Start the timer.
mov al,81h
out 02h,al
call waitasec ;Start the timer.
mov al,01Fh
out 02h,al
call waitasec ;Start the timer.
mov al,0xF1
out 02h,al
call waitasec ;Start the timer.
mov al,01Fh
out 02h,al
call waitasec ;Start the timer.
mov al,11h
out 02h,al
call waitasec ;Start the timer.
mov al,01Fh
out 02h,al
call waitasec ;Start the timer.
mov al,71h
out 02h,al
mov cx,0x0AFF ;Wait about 50 ms.
call waitasec ;Start the timer.
ret
begin: call init_lcd ;Initialize the LCD screen.
mov al,81h
out 02h,al ;Set DDRAM address to 00h
mov cx,0x0AFF ;Wait about 50 ms.
call waitasec ;Make sure LCD event is done.
mov cx,0x006F ;Wait about 50 ms.
mov al,45h
out 02h,al ;Output "H"
call waitasec ;Make sure LCD event is done.
mov al,85h
out 02h,al ;Output "H"
call waitasec ;Make sure LCD event is done.
mov al,65h
out 02h,al ;Output "i"
call waitasec ;Make sure LCD event is done.
mov al,95h
out 02h,al ;Output "i"
call waitasec ;Make sure LCD event is done.
jmp $
times 2032- ($-$$) db 0
jmp start
times 12 db 0
I know it can display stuff, because when I kept pushing the reset button on my breadboard, it showed random stuff on the screen sometimes. I have rarely been as frustrated with something that I know should work as this. To make matters more complicated, I've seen several different ways to initialize this. I have tried to follow the initialization sequences depicted in the AMC2004A datasheet, as well as the HD44780U datasheet. I tried the troubleshooting suggestions Dennis Che recommended in his ebook "All About Liquid Crystal Displays – Character Models Vol 2".
I'm this close to giving up on the darn LCD. I don't think I should have to waste a microcontroller on something that a computer should be able to control. I'm starting to lean more toward making my own primitive VGA board at this point, modeled closely after the one shown here: http://www.lucidscience.com/pro-vga%20video%20generator-1.aspx
But I still want to beat this thing and make it work. Anybody have any wild ideas about what might be wrong? Oh, and I put a 10 K ohm pot for the contrast, and a 4.7 uF capacitor between the 5V line and the ground line of the LCD. Nothing made a difference. Thanks
I will upload a picture of the schematic later on when I wake up. It's getting late now.