Character LCD initialization frustration

Building your first 6502-based project? We'll help you get started here.
Post Reply
Gurft
Posts: 17
Joined: 06 May 2005
Location: Limerick, PA

Character LCD initialization frustration

Post by Gurft »

Going crazy trying to get this 4 x 20 Character display working. All I get are a screen full of blocks (well initially I get a single line, then it flips to a full screen) I tested on a 2x16 also and get the same results, so I think my issue is in my initialization code. Code is deeply taken from what Garth has in his primer, and I stole the delay_ms function from somewhere.... I feel like it's a timing issue but can't seem to suss it out. Logic Analyzer shows that the bits are being sent properly, and the RS and EN lines are getting toggled appropriately... Any suggestions or help is appreciated...

The LCD is connected for 4-bit mode to VIA1 Port A 0 through 5

V1A0 - D4
V1A1 - D5
V1A2 - D6
V1A3 - D7
V1A4 - RS
V1A5 - EN

Code: Select all

.setcpu "6502"

    VIA1_ORB = $B100
    VIA1_ORA = $B101
    VIA1_DDRB = $B102
    VIA1_DDRA = $B103

    .segment "VECTORS"

    .word   nmi
    .word   reset
    .word   irq

    .zeropage

tmp1:   .byte  $00

    .code

reset:  jmp main

nmi:    rti

irq:    rti

main:     jsr reset_lcd
          ldx #$0
loop:     lda hello,x
          beq hold
          jsr send_lcd_data
          inx
          jmp loop
 
hold:     jmp hold

send_lcd_nibble:
         ; XD XD EN RS D7 D6 D5 D4
         ; write the nibble
         sta VIA1_ORA
         ora #%00100000    ; Turn on enable pin
         sta VIA1_ORA
         AND #%11011111    ; Turn off enable pin
         sta VIA1_ORA
         RTS

send_lcd_instr:
         pha
         lsr A
         lsr A
         lsr A
         lsr A
         jsr send_lcd_nibble
         PLA
         AND #%00001111
         JMP send_lcd_nibble

send_lcd_data:
        pha
        LSR A
        LSR A
        LSR A
        LSR A
        ora #%00010000
        JSR send_lcd_nibble
        PLA
        AND #%00001111
        ORA #%00010000
        jmp send_lcd_nibble

reset_lcd:
        lda #$FF
        sta VIA1_DDRA
        lda #$00
        sta VIA1_ORA
        lda #50
        jsr _delay_ms

        lda #$03       ;0011 - Do Setup
        sta VIA1_ORA
        ldx #$23       ;100011  - Same value, but with enable
        stx VIA1_ORA   ; Do the Enable
        sta VIA1_ORA   ; Send again without enable
        lda #50
        jsr _delay_ms

        ldx #$23    
        stx VIA1_ORA   ; with enable
        lda #$03      
        sta VIA1_ORA   ; wihtout enable
        lda #50
        jsr _delay_ms

        ldx #$23    
        stx VIA1_ORA   ; with enable
        lda #$03      
        sta VIA1_ORA   ; wihtout enable
        lda #50
        jsr _delay_ms

        lda #$02 
        sta VIA1_ORA   ; 4 - bit address (0010), 
        ldx #$22       ; 
        stx VIA1_ORA   ; 4 - bit address (with enable)
        sta VIA1_ORA   ; 4 - bit address (no enable)

        lda #$2B
        jsr send_lcd_instr    ; two line display, 5x10 font

        lda #$0C         
        jsr send_lcd_instr    ; Display on, no cursur, no blink

        lda #$01
        jsr send_lcd_instr    ; Clear the screen

        lda #$06
        sta send_lcd_instr    ; 

        lda #$02
        sta send_lcd_instr    ; 

        rts


; stole this from somewhere, it's hardcoded for 1MHz
_delay_ms:          sta tmp1      ; 3
                    txa           ; 2
                    pha           ; 3
                    tya           ; 2
                    pha           ; 3
                    ldx tmp1      ; 3

                    ldy #190      ; 2
@loop1:             dey           ; 190 * 2
                    bne @loop1    ; 190 * 3 - 1

@loop2:             dex           ; 2
                    beq @return   ; (x - 1) * 2 + 3

                    nop           ; 2
                    ldy #198      ; 2
@loop3:             dey           ; 198 * 2
                    bne @loop3    ; 198 * 3 - 1

                    jmp @loop2    ; 3

@return:            pla           ; 4
                    tay           ; 2
                    pla           ; 4
                    tax           ; 2
                    lda tmp1      ; 3
                    rts           ; 6 (+ 6 for JSR)


hello:      .byte       "Hello, World!",$00

User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Character LCD initialization frustration

Post by GARTHWILSON »

The first thing I see immediately is that you don't have the required 15ms minimum delay after power-up to let the LCD get through its own reset and set-up steps before it can take instructions. I might look at the code more in depth later.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Gurft
Posts: 17
Joined: 06 May 2005
Location: Limerick, PA

Re: Character LCD initialization frustration

Post by Gurft »

I do have a 50ms delay right after I set the DDR and set the output register to zeros before I start twiddling bits to initialize the LCD. I’m going to spend some time with the data sheets and see if maybe my delays are too long. I’m just doing 50ms for all of them...
Gurft
Posts: 17
Joined: 06 May 2005
Location: Limerick, PA

Re: Character LCD initialization frustration

Post by Gurft »

So I went back this morning with a clear head and did some more digging for datasheet information outside the standard Hitachi sheet and the minimal one for the LCD display that I had.

I stumbled on this version: http://web.alfredstate.edu/faculty/weim ... index.html The author REALLY does a great job with his own flowchart of how the 4-bit initialization should work. I then went back and reviewed all of my timings. I needed more time up front for the LCD to initialize (I changed it from 50ms to 100ms) and REDUCED many of the timings from 50ms to 1ms or 5ms depending on the minimum requirement and adding some buffer.

Once I made those changes, everything is now working! So moral of the story, double check your datasheets, and sometimes when something says "at least" there may be a "too much" that you need to worry about.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Character LCD initialization frustration

Post by GARTHWILSON »

Right you are. I was trying to go too fast again. Too much time shouldn't ever be a problem though. In one project, I used delay routines that were much longer than required just because they were there for something else that needed them. These LCDs are a model of stability in the market, in that the same design and interface method have been there for decades. They always work on first try for me.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Post Reply