LCD: Code, or LCD, or Both

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

So, I went to a electronics surplus store and I bought a super cheap, what I thought was a 1 by 16 character HD44780 based LCD with 14 pins plus two that have a + and - symbol by them, with no data sheet. I hooked up the latter pins, what I thought were the data pins, to PORTD on my ATMega8, and connected pin 0 to RS, pin 1 to RW, and pin 2 to EN on PORTB. I made some code for it and it didn't work, the LCD look as if it was not on, not even a flash. I was wondering if my code had problems, the LCD is not standard or HD44780 based, or the pin aren't hooked up right? This is my first LCD.

PINS:
+ Not Connected
- Not Connected
1 GND
2 VCC
3 VCC(Contrast)
4 PB0(RS)
5 PB1(RW)
6 PB2(EN)
7 PD0(D0)
8 PD1(D1)
9 PD2(D2)
10 PD3(D3)
11 PD4(D4)
12 PD5(D5)
13 PD6(D6)
14 PD7(D7)

(I'm assuming that the pin are in this order)

#include 
#include 

#define LCD_Control PORTB
#define LCD_data PORTD
#define LCD_BF PD7
#define LCD_rs PB0
#define LCD_rw PB1
#define LCD_en PB2

int WaitForLCD(void)
{
	LCD_data &= ~(1 << LCD_BF);
	while(LCD_BF == 1){}
	LCD_data |= (1 << LCD_BF);
	
	return 1;
}

int CommandLCD(char data)
{
	LCD_data = data;
	LCD_Control &= ~(1 << LCD_rs);
	LCD_Control &= ~(1 << LCD_rw);
	LCD_Control |= (1 << LCD_en);
	LCD_Control &= ~(1 << LCD_en);
	WaitForLCD();
	
	return 1;
}

int SendDataToLCD(char data)
{
	LCD_data = data;
	LCD_Control &= ~(1 << LCD_rs);
	LCD_Control |= (1 << LCD_rw);
	LCD_Control |= (1 << LCD_en);
	LCD_Control &= ~(1 << LCD_en);
	WaitForLCD();
	
	return 0;
}

char ReadFromLCD(void)
{
	DDRD = 0b00000000;
	char data;
	
	LCD_Control &= ~(1 << LCD_rw);
	LCD_Control |= (1 << LCD_rs);
	LCD_Control |= (1 << LCD_en);
	LCD_Control &= ~(1 << LCD_en);
	_delay_ms(20);
	data = LCD_data;
	
	DDRD = 0b11111111;
	return data;
}

int Init_LCD(void)// I don't know about this code, I got it from: http://www.8051projects.net/lcd-interfacing/initialization.php
{
	_delay_ms(20);
	
	LCD_data = 0x30;
	LCD_Control &= ~(1 << LCD_rs);
	LCD_Control &= ~(1 << LCD_rw);
	LCD_Control |= (1 << LCD_en);
	LCD_Control &= ~(1 << LCD_en);
	_delay_ms(20);
	
	LCD_data = 0x30;
	LCD_Control &= ~(1 << LCD_rs);
	LCD_Control &= ~(1 << LCD_rw);
	LCD_Control |= (1 << LCD_en);
	LCD_Control &= ~(1 << LCD_en);
	_delay_ms(20);
	
	LCD_data = 0x30;
	LCD_Control &= ~(1 << LCD_rs);
	LCD_Control &= ~(1 << LCD_rw);
	LCD_Control |= (1 << LCD_en);
	LCD_Control &= ~(1 << LCD_en);
	WaitForLCD();
	return 1;
}

int main (void)
{
	DDRD = 0b11111111;
	DDRB = 0b11111111;
	
	Init_LCD();
	CommandLCD(0x0F);// Display ON, Curser ON, Curser Blinking
	
	while(1){}
}

Life Is Like A Bucket Of Chicken.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
   _delay_ms(20);
   
   LCD_data = 0x30;
   LCD_Control &= ~(1 << LCD_rs);
   LCD_Control &= ~(1 << LCD_rw);
   LCD_Control |= (1 << LCD_en);
   LCD_Control &= ~(1 << LCD_en);
   _delay_ms(20);
   
   LCD_data = 0x30;
   LCD_Control &= ~(1 << LCD_rs);
   LCD_Control &= ~(1 << LCD_rw);
   LCD_Control |= (1 << LCD_en);
   LCD_Control &= ~(1 << LCD_en);
   _delay_ms(20);
   
   LCD_data = 0x30;
   LCD_Control &= ~(1 << LCD_rs);
   LCD_Control &= ~(1 << LCD_rw);
   LCD_Control |= (1 << LCD_en);
   LCD_Control &= ~(1 << LCD_en);
   WaitForLCD();
   return 1; 

This is not a complete initialization sequence (though it may be enough with the command to turn on the LCD to get something on the display).

int WaitForLCD(void)
{
   LCD_data &= ~(1 << LCD_BF);
   while(LCD_BF == 1){}
   LCD_data |= (1 << LCD_BF);
   
   return 1;
} 

This will not work. You want to set the entire data port to input (the LCD will probably not work correctly with them set as output while it is in read mode). More importantly, LCD_BF is a constant whose value is 7, so it will never be equal to 1. Also you are setting the R/W line high in the calling function (which is probably not a good idea), but more importantly, you never send it back low again.

But even with just applying power to the LCD you should get a row of dark boxes.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
DDRD = 0b00000000; 

I'm wandering if this is alowed.

In the past someone tolled me that with GCC you could not use the binary format. It always had to be hex or decimal.

I could be wrong here. ( I sure hope so) because then I can start using it again too.

Regards

Marcel

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

meslomp wrote:
I could be wrong here.
You are wrong. The 0b... number format has been specifically added to AVR-GCC. It is being considered as an enhancement to gcc in general.

Use it with confidence! (Although the bit manipulation techniques are better in that they are self-documenting.)

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

Hi stu,

Thanks for the clarification on this.

I mainly use it for mij after reset initialisation of the IO pins. In that routine I also have the comment on what line is doing what to clarify.

untill now I always had in comments the 0b..... numbers and then recalculated it to HEX numbers.

I can now skip this conversion and thus a possibility for error(although small)

regards

Marcel

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

Try tying contrast to ground (or better yet, tie a 10k or so pot from vcc to gnd with the wiper going to the LCD contrast pin).