Patrefans
beneater from patreon
beneater patreon

4-bit LCD interface

🕑 Added 2021-05-05 16:46:56 +0000 UTC
4-bit LCD interface

Comments

Got it to work by adding Set 8-bit mode 3 times before setting the 4-bit mode. My problem was after reset, the LCD got set to 4-bit more but only 1 line mode, using the Enter key made the curser go off screen instead to the 2nd line it went to position 40 but on line 1. lcd_init: lda #%00000011 ; 1st Set 8-bit mode sta PORTB ora #E sta PORTB and #%00001111 sta PORTB lda #%00000011 ; 2nd Set 8-bit mode sta PORTB ora #E sta PORTB and #%00001111 sta PORTB lda #%00000011 ; 3rd Set 8-bit mode sta PORTB ora #E sta PORTB and #%00001111 sta PORTB lda #%00000010 ; Set 4-bit mode sta PORTB ora #E sta PORTB and #%00001111 sta PORTB rts

Ian Flanigan

For people of the future, if you don't want to hit reset twice every time, the HD44780U datasheet has a procedure called "Initializing by Instruction" in Figure 24 (p. 46) that forces a reset in 4-bit mode. Essentially, it sends the high nibble to request 8-bit mode 3 times using only timing between calls, then requests 4-bit mode as usual. The reason that it requests 8-bit mode 3 times is that if it were in 4-bit mode, the first two would be taken as both halves of a request. The third one ensures that it's really in the right state. I implemented this and it works like a charm.

Tim Walkowski

Ok - found an answer: you can't switch. Wikipedia is your friend. The ROM is determined by which version of the HD44780U is used by the LCD. From the article: "Two versions of the ROM have been developed: HD44780UA00, the standard (Japanese) version, which includes katakana characters and some Greek letters and mathematical symbols HD44780UA02, a European version, which includes the complete set of Greek, Cyrillic and Western European characters (with diacritics) The 7-bit ASCII subset for the Japanese version is non-standard: it supplies a Yen symbol where the backslash character is normally found, and left and right arrow symbols in place of tilde and the rubout character."

Tim Walkowski

As an aside to this conversation, does anyone know how to select the ROM code A02 instead of ROM code A00 in the HD4470? ROM A02 will display the "\" and "~" characters correctly while the ROM A00 shows other symbols. (pages 17, 18 of the HD44780U datasheet) The rest of the ROM characters map as expected...

Tim Walkowski

I send 3 instructions for 8-bit mode before sending a single instruction for 4-bit mode in my initialization code and the lcd behaves as expected. However, the display is blank until I press reset after power-up.

Luke McNinch

No problem, I'm glad it worked for you!

Worked like a charm! Thanks again

xedover

nevermind... I see it now. Its in software only... no change to the hardware. In the "reset" routine with the lcd_init

xedover

I'm confused. I'm not seeing it... what exactly was it that people noticed and how? I watched all the videos again, and still didn't see it. What am I missing?

Thanks so much for your help. I can't wait to try it out!

Luke McNinch

It's not needed. The 74HC595 shift register has that functionality built-in using the output enable pin. Sorry, I was calling it "chip select". Ben ties them low so they're always in output mode, but pulling them high with one of the PORTA pins puts them in 3-state mode so you can use those lines for the LCD.

Do you use something like a 74LS245 to isolate the shift register outputs when they're not being used?

Oh yes, it's there on the HD44780 datasheet, just not on the datasheet for the LCD module I was looking at. The suggested timings are more generous than the ones you would derive from my explanation of why it does what it does too. Thanks.

Phil Dennis

The LCD controller data sheet describes the procedure for software reset and establishing 4 bit mode on page 46. There’s a sequence of commands and also minimum delays specified between some of the commands.

Luke McNinch

I just remembered, you do have to be careful to disable interrupts in your LCD subroutines so you don't mess with PORTB in the middle of LCD communication.

Luke McNinch

It works basically like another data bus. When the LCD isn't enabled, you can do anything with the data bits. The shift register outputs can be disabled. Ben hard-wired the chip select but I connected it to a pin on PORTA which I toggle in the keyboard interrupt handler, then read PORTB. I'm going from memory but I think that's basically it.

@Luke McNinch - how did you share PORTB between the shift registers and the LCD?

Ben Eater

Oooh cool. I'll have to give this a try. Makes complete sense though.

Luke McNinch

Thanks for the tips! I ended up following the advice of another patron and shared PORTB between the shift register and the LCD (8-bit) and used a 4th pin on PORTA for Chip Select on the shift registers. It worked great!

There is a process for avoiding the flakiness at startup: the trick is to send 0011???? (on DB7-DB0 where the ?s are not connected) to force it into 8-bit mode first. That command is a no-op if sent multiple times: if it starts up in 8-bit mode then you don't need the command but it doesn't hurt to send it again. If it starts up in 4-bit mode awaiting the first nibble then you can send that command twice to enter 8-bit mode. If it starts up in 4-bit mode awaiting the second nibble then you can send that command three times, once to complete the pending command and twice more to enter 8-bit mode. In any case if you send 0011???? three times you're now in 8-bit mode, so that sending 0010???? puts you into 4-bit mode and then another 0010???? followed by NF00???? sends the actual Function Set command you wanted.

Warren Garabrandt

I said "programmable resister because I forgot it was actually called a R2R DAC (I think anyway).

Warren Garabrandt

What if the power for the lcd were going through a mosfet that the CPU could control? Then the cpu could turn on and off the lcd when it needed to reset it, and you could have a screen sleep mode that wakes up from a key press. Maybe shift + a function key can turn the display on and off. I used a 16 bit programmable resister that took spi input to set a resistance value between 0 and 65535 when I was working on a project a while back. Could it be used to set the contrast of the display with a shift + function key for higher and another for lower, like a laptop? These could be a fun thing to do and show how to interface the cpu with outside things.


More Creators