16*2 lcd initiation, why does not my code work?

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey all!
I am struggling with my 16*2 character display bought from www.elfa.se and I really cannot understand why my code does not work. Running a mega88 at 20mhz. Please help me if you can!

void init_lcd(){

/*following initialization-sequence follows the one presented for similar displays available in Elfa */

PORTD=0x00;

//4bit mode, sending 0x02 two times
DDRD=0Xff;
PORTD &= ~_BV(RW_BIT);//denna snutt ändrar till 4bitars interface
PORTD &= ~_BV(RS_BIT);//set rs och rw bits low
bwait(1); //VIL1 i timingfigur
PORTD |=_BV(E_BIT);//send enable-pulse
bwait(1);
PORTD |= 0x02; //först skrivs 4 msb bitarna sedan de lsb bitarna
bwait(10);//maintain enable-pulse, 10*0.5us
PORTD &= ~_BV(E_BIT);//turn off enable-pulse
bwait(1);//th1 i timingfigur
PORTD=0x00;
bwait(1);
DDRD=0Xf0;

bwait(150);//wait for sending next four bits

//second time sending 0x02
DDRD=0Xff;
PORTD &= ~_BV(RW_BIT);//
PORTD &= ~_BV(RS_BIT);//set rs och rw bits low
bwait(1); //VIL1 i timingfigur
PORTD |=_BV(E_BIT);//send enable-pulse
bwait(1);
PORTD |= 0x02; //först skrivs 4 msb bitarna sedan de lsb bitarna
bwait(10);//maintain enable-pulse
PORTD &= ~_BV(E_BIT);//turn off enable-pulse
bwait(1);
PORTD=0x00;
bwait(1);
DDRD=0Xf0;
bwait(150);

//two line mode, display on
DDRD=0Xff;
PORTD &= ~_BV(RW_BIT);//denna snutt ändrar till 4bitars interface
PORTD &= ~_BV(RS_BIT);//set rs och rw bits low
bwait(1); //VIL1 i timingfigur
PORTD |=_BV(E_BIT);//send enable-pulse
bwait(1);
PORTD |= 0x0c;
bwait(10);//maintain enable-pulse
PORTD &= ~_BV(E_BIT);//turn off enable-pulse
bwait(1);
PORTD=0x00;
bwait(1);
DDRD=0Xf0;
bwait(150);

iwrite(0x0f);//display on, cursor on, blink on

//iwrite(0x06);//increment mode, entire shift off

//iwrite(0x01); //clear display and move cursor to beginning of display (address 64)

bwait(3500);

}

void wait_instr(){
/* LCD life insurance... */
bwait(1);
DDRD=0Xf0; //set bit 4..7 as outputs and 0-3 as inputs on the cpu
PORTD |=_BV(RW_BIT);//set bit
PORTD &= ~_BV(RS_BIT);//clear bit
bwait(1);
loop_until_bit_is_clear(PORTD, BF_BIT);
bwait(1);
PORTD =0x00;
bwait(1);
DDRD=0x00;

}

void iwrite(uint8_t instr){

DDRD=0Xff;
PORTD &= ~_BV(RW_BIT);//clear bit
PORTD &= ~_BV(RS_BIT);
bwait(1);
PORTD |=_BV(E_BIT);//send enable-pulse
bwait(1);
PORTD |= ((instr>>4)&0x0f); //först skrivs 4 msb bitarna sedan de lsb bitarna
bwait(10);//maintain enable-pulse
PORTD &= ~_BV(E_BIT);//turn off enable-pulse

wait_instr();

PORTD &= ~_BV(RW_BIT);
PORTD &= ~_BV(RS_BIT);

DDRD=0Xff;
PORTD |=_BV(E_BIT);//send enable-pulse
bwait(1);
PORTD |= (instr&0x0f); //skrivs 4 lsb bitarna sedan de lsb bitarna
bwait(10);//maintain enable-pulse for 1ms
PORTD &= ~_BV(E_BIT);//turn off enable-pulse

wait_instr();

}

void bwait(uint16_t cyc){ //at 20MHz bwait(1) -->> 0.5us
for(;cyc > 0;cyc--);
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

forgot to say:

/* LCD interface bit positions */
/*
databits 0..3 channel D on mcu, bits 4..7 on display
controlbits 4..6 channel D
backligth enabled by bit 7
*/

#define E_BIT 6 //channel D
#define RW_BIT 5
#define RS_BIT 4
#define BF_BIT 3

/Tomas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please post a schematic. How we are supposed to know if your code wiggles wrong pins without seeing the schematics?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tell more about what "does not work" means.

First, address the most common situation: the contrast circuit and setting. When you have an uninitialized, powered-on display, do you see a row of black boxes on the top row? And changing the contrast setting changes the contrast of that row of black boxes?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also the exact type of the display and maybe even a datasheet of your display would be nice. Are you sure it has HD44780 compatible interface? I've seen one display that does not support 4-bit interface, only 8-bit.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jepael wrote:
Please post a schematic. How we are supposed to know if your code wiggles wrong pins without seeing the schematics?

Does not my second post complete your question? All connections between display and avr are shown.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Tell more about what "does not work" means.

First, address the most common situation: the contrast circuit and setting. When you have an uninitialized, powered-on display, do you see a row of black boxes on the top row? And changing the contrast setting changes the contrast of that row of black boxes?

Lee

Hello Lee,
I have tried so many different waittimes combinations and run into lots of different behaviour of the display. I have seen what you mention "a row of black boxes on the top row" before but what is valid for the code I show here is just a blank display. No blinking cursor, and the whole display seem to be inactivated. The contrast setting is good since I had this display working before but with different code. Now when I rewrote the code for optimizing the code and changing type of avr, I just cannot get it working again.
/tomas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jepael wrote:
Also the exact type of the display and maybe even a datasheet of your display would be nice. Are you sure it has HD44780 compatible interface? I've seen one display that does not support 4-bit interface, only 8-bit.

This display supports 4 bit interface I am sure of that because I had it running before with this. The attached datasheet is similar to the display I have, the datasheet refers to a 16*1 display but it has teh setting that makes it valid for also 16*2characters. I beleive there is a standard for this communication interface for these displays.

/Tomas

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

maybe you need to use 0x30 in portd instead of 0x02? (from table 5-2-2)

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:
maybe you need to use 0x30 in portd instead of 0x02? (from table 5-2-2)

Hello Bob!
Long time no see!
The 4 lsb on the display are not connected to the mcu. Bit 3 is pulled up and bit 2 is pulled down, bit 0 and 1 is loose. PortD: Bit 0-3 is display bit 4-7 on display. Bit 4-6 on portD is connected to controlbits on the mcu. 0x30 would mean RW high, and RS high and no data value.

Or did I misunderstand your proposition?

/Tomas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Speedfoot wrote:

Does not my second post complete your question? All connections between display and avr are shown.

No and yes. It does not tell me how things are connected physically, so those constants might have errors. I am positive that no connection between AVR and LCD is wrong, the problem is in the code or LCD wiring. Schematic can tell those errors.

Good points from people, now I remember what happened to me once. When 4-bits mode of the LCD is used, unused data pins, or at least most important ones, must be pulled low externally. Not direct connection to GND if you are reading from the LCD, but maybe a 1k pull-down resistors or so. LCD has internal weak pull-up resistors, so it will not initialize correctly to 4-bit mode if unused pins are left floating.

Also contrast pin must be driven to say 0.5 volts. I usually use a 10 or 20 kohm trimmer to get that. Remember, no capacitance to the contrast pin (3 Vo).

- Jani

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jepael wrote:
Speedfoot wrote:

Does not my second post complete your question? All connections between display and avr are shown.

No and yes. It does not tell me how things are connected physically, so those constants might have errors. I am positive that no connection between AVR and LCD is wrong, the problem is in the code or LCD wiring. Schematic can tell those errors.

Good points from people, now I remember what happened to me once. When 4-bits mode of the LCD is used, unused data pins, or at least most important ones, must be pulled low externally. Not direct connection to GND if you are reading from the LCD, but maybe a 1k pull-down resistors or so. LCD has internal weak pull-up resistors, so it will not initialize correctly to 4-bit mode if unused pins are left floating.

Also contrast pin must be driven to say 0.5 volts. I usually use a 10 or 20 kohm trimmer to get that. Remember, no capacitance to the contrast pin (3 Vo).

- Jani

Thank you Jani,
The contrast pin is connected as you propose. I will test to pull-down the unused pins on the display as you propose.

/Tomas

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you have it hooked up in 4 bit mode, you still need to call iwrite during init and write the byte out hi nib lo nib, right? If you are writing the 2 bit, and its not hooked to anything, how does it get into the 44780??

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The intialization for 4-bit mode looks a bit funny. The lower bits don't matter, as the command to switch to 4-bit mode only needs the upper 4. However, you first want to send the command to switch to 8-bit mode as it's the only way to get the display back in sync if it had received half an instruction in 4-bit mode. So, the first set function commands are 3 thrice (switch to 8-bit mode even if we were out of sync in 4-bit mode), then 2 once (switch to 4-bit mode), then you're truly in 4-bit mode. After the first 3 you may need to wait a long while as the display could have loaded half a slow command.
Your code also seems to be sending the lower nibble while holding the enable pin high. At least from the documents I've read and how my display behaves that's wrong, you need to pulse enable for each nibble.
A working example (though now that I think of it, probably should send the initial 3 once more) can be found at http://donkey.dyndns.org/~yann/a...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
So, the first set function commands are 3 thrice (switch to 8-bit mode even if we were out of sync in 4-bit mode), then 2 once (switch to 4-bit mode), then you're truly in 4-bit mode.

According to the datasheet the OP provided, this is not quite a standard HD44780. The initialization is different.

From what the sheet says, what you are doing is correct. However it might be worth a try to use the more standard init procedure.

Quote:
Your code also seems to be sending the lower nibble while holding the enable pin high.

No, he is sending the enable bit high then low for each nibble.

What you are doing wrong is waiting for the busy bit after the high nibble. You should only wait for the busy flag after all 8 bits have been sent.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

The 4 lsb on the display are not connected to the mcu. Bit 3 is pulled up and bit 2 is pulled down, bit 0 and 1 is loose.

AFAIK the four low bits DB0..3 of the 44780 should be unconnected when running it in 4-bit mode.

Also, the init sequence for four bit mode should start with three times sending the upper nibble of an eight bit Function Set instruction, with certain timing constraints. You should then send another high nibble of an eight bit instruction, switching the display to four bit mode. The rest of the init sequence is made in four bit mode, sending full eight bit instructions as two nibbles with the high nibble first.

Search this site for a pdf document named 99rtd006d2 packed inside a zip file. I have posted it here several times, and IMHO this is the best document on the 44780 controller. The figure on 4-bit init attached below is from that document.

Attachment(s): 

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Also, the init sequence for four bit mode should start with three times sending the upper nibble of an eight bit Function Set instruction, with certain timing constraints.

Not all HD44780 clones are created equal. Some have a different init procedure. The OPs display appears to be one of them (assuming that the data sheet that he has is actually the correct one). Since he says that he has already gotten this display to work with other code (presumably using the same datasheet), then I suspect that this is not the problem. There is a definite error in the code (that of waiting for the busy flag after the first nibble). I would suggest that he correct that first.

Regards,
Steve A.

The Board helps those that help themselves.