Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

LCD display

Status
Not open for further replies.

t.man

New Member
i'm trying to send characters to the dispaly but failed, i'm not even sure that the display do initialize.

i'm using KS0066U dased lcd(i.e PC1602F from POWERTIP company). it is a 16 pin display.

my hardware configurations:

LCD------------MCU(ATmega8)

Vss-------------------------->POWER SUPPLY(GND)
Vdd-------------------------->POWER SUPPLY(+5v)
Vo(Contrast Adjust)---------->(120 ohm to GND)

DB7-------------PD7
DB6-------------PD6
DB5-------------PD5
DB4-------------PD4

(DB3-DB0) tied to ground

(PIN 15 & 16 ) not connected

software

main.h
Code:
#ifndef MAIN_H 

#define MAIN_H 

#include <stdio.h> 
#include <avr/io.h> 
#include <util/delay.h> 



#define LCD_DATA_PORT PORTD 
#define LCD_DATA_DDR DDRD 

//define lcd control port 
#define LCD_CTRL_PORT PORTB 
#define LCD_CTRL_DDR DDRB 
#define LCD_rs 0 
#define LCD_rw 1 
#define LCD_en 2 




// LCD instructions 
#define LCD_start() LCD_command(0x20)   /* Send 0x2(0) */ 
#define LCD_function_set() LCD_command(0x28) /* LCD function set */ 
#define LCD_display_off() LCD_command(0x08) /* LCD display off*/ 
#define LCD_display_on() LCD_command(0x0F) /* LCD display on*/ 
#define LCD_display_clear() LCD_command(0x01)/* Clear display LCD */ 
#define LCD_mode_set() LCD_command(0x06) /* LCD mode set */ 



//functions declarations 
void LCD_enable(); 
void LCD_command(unsigned char command); 
void LCD_putc(unsigned char ascii); 
void LCD_puts(unsigned char *lcd_string); 
void LCD_init(); 
#endif


main.c
Code:
#include "main.h" 




unsigned char text[] = "AVR Project"; 

  

  

int main() 
{ 
    
    
   LCD_init(); 

    
   LCD_puts(text); 
    
    
}    


void LCD_enable() 
{ 
    LCD_CTRL_PORT |= (1<<LCD_en); 
    _delay_ms(1); 
    LCD_CTRL_PORT &= ~(1<<LCD_en); 
} 

void LCD_command(unsigned char command) 
{ 
    LCD_CTRL_PORT &= ~(1<<LCD_rs); 
    LCD_DATA_PORT = (command & 0xF0)|(LCD_DATA_PORT & 0x0F); 
    LCD_enable(); 
    LCD_DATA_PORT = (command << 4 & 0xF0)|(LCD_DATA_PORT & 0x0F); 
    LCD_enable(); 
    _delay_ms(1); 
} 

void LCD_putc(unsigned char ascii) 
{ 
    LCD_CTRL_PORT |= (1<<LCD_rs); 
    LCD_DATA_PORT = (ascii & 0xF0)|(LCD_DATA_PORT & 0x0F); 
    LCD_enable(); 
    LCD_DATA_PORT = (ascii << 4 & 0xF0)|(LCD_DATA_PORT & 0x0F); 
    LCD_enable(); 
    _delay_ms(1); 
} 

void LCD_puts(unsigned char *lcd_string) 
{ 
   while (*lcd_string) 
   { 
      LCD_putc(*lcd_string++); 
   } 
} 

void LCD_init() 
{ 

   //initialize LCD control lines 
   LCD_CTRL_PORT &= ~(1<<LCD_rs);   // RS low 
   LCD_CTRL_PORT &= ~(1<<LCD_rw);   // R/W low 
   LCD_CTRL_PORT &= ~(1<<LCD_en);   // E low 

   // initialize LCD control lines to output 
   LCD_CTRL_DDR |= (1<<LCD_rs); 
   LCD_CTRL_DDR |= (1<<LCD_rw); 
   LCD_CTRL_DDR |= (1<<LCD_en); 

   // initialize LCD data port to input 
      LCD_DATA_DDR |= 0xF0;// Data on high four bits of port 


   _delay_ms(30); 
   LCD_start(); 
   LCD_function_set(); 
    _delay_us(40); 
   LCD_display_off(); 
   _delay_us(40); 
   LCD_display_clear(); 
   _delay_ms(2); 
   LCD_mode_set(); 
   LCD_display_on(); 

}

i need help!
 
Last edited:
Try tying the lcd's RW pin to ground.... Kinda essential to get it working correctly!!
 
In your list of connections RS and Enable aren't listed. They need to be connected to PORTB bits 0 and 2 respectively.

Mike.
 
In your list of connections RS and Enable aren't listed. They need to be connected to PORTB bits 0 and 2 respectively.

Mike.

sorry not to mention them

RS is connected to PB0
R/W connected to PB1 and
E is connectd to PB2
 
I just had a look at your code and it is not doing the initialisation correctly.
There is a sequence of actions to get the LCD initialised.

Try changing your init routine to,
Code:
void LCD_init() 
{ 

   //initialize LCD control lines 
   LCD_CTRL_PORT &= ~(1<<LCD_rs);   // RS low 
   LCD_CTRL_PORT &= ~(1<<LCD_rw);   // R/W low 
   LCD_CTRL_PORT &= ~(1<<LCD_en);   // E low 

   // initialize LCD control lines to output 
   LCD_CTRL_DDR |= (1<<LCD_rs); 
   LCD_CTRL_DDR |= (1<<LCD_rw); 
   LCD_CTRL_DDR |= (1<<LCD_en); 

   // initialize LCD data port to input 
    LCD_DATA_DDR |= 0xF0;// Data on high four bits of port 

    _delay_ms(15);		//start of required sequnce
    LCD_command(0x30);
    _delay_ms(5); 
    LCD_command(0x30);
    _delay_ms(1); 
    LCD_command(0x30);		//end of sequence

   LCD_start(); 
   LCD_function_set(); 
    _delay_us(40); 
   LCD_display_off(); 
   _delay_us(40); 
   LCD_display_clear(); 
   _delay_ms(2); 
   LCD_mode_set(); 
   LCD_display_on(); 
}

Mike.
 
Last edited:
hi Mike,

Another effect I have seen when the PWRTE has been disabled and the LCD initialising subr is at the start of the program.
Some slower LCD's are still settling from the power up when the init subr is trying to set it up.
The result being the LCD is not initialised

I would suggest the CONFIG PWRT, when using the HD44780 should be enabled and the init subr not placed at the start of the program.

Regards
 
Last edited:
Hi eric,

The OP is using an AVR and so I don't know if it even has a Power up timer. However, the initial 15mS delay is supposed to take care of that problem. If the OP has a particularly slow power supply then increasing it might be advantageous.

Mike.
 
Hi eric,

The OP is using an AVR and so I don't know if it even has a Power up timer. However, the initial 15mS delay is supposed to take care of that problem. If the OP has a particularly slow power supply then increasing it might be advantageous.

Mike.

can power suply have effect on the problem? and how do u increase it?
i'm using a 12VDC plug-pack supplying a LM78L05 regulator.

...Again can unconnected LED backlight power suply pins on LCD contribute to my problem...if yes how can i connect them.

what happens now(when unused data lines are tied to ground) is that i can see only one line(background dots) with no text!...when unused data lines are not connected the 2 lines with no text....i've tried all possible means but with no success!
 
can power suply have effect on the problem? and how do u increase it?
i'm using a 12VDC plug-pack supplying a LM78L05 regulator.

...Again can unconnected LED backlight power suply pins on LCD contribute to my problem...if yes how can i connect them.

what happens now(when unused data lines are tied to ground) is that i can see only one line(background dots) with no text!...when unused data lines are not connected the 2 lines with no text....i've tried all possible means but with no success!
hi,
A 12Vdc connected to 7805 is normal practice, what decoupling do you have on the 7805.?
Are there any other devices drawing current from the 7805.?

Do you see any black pixel blocks on the LCD.?
 
Last edited:
what decoupling do you have on the 7805.?
i have 100uF electrolyte at the input and 10uF electrolyte at the output.

Are there any other devices drawing current from the 7805.?

at the moment only the AVR microcontroler(ofcourse and a potentiomenter connected to the internal ADC of the AVR) and LCD are drawing current from 78L05

Do you see any black pixel blocks on the LCD.?

Yes, there are black pixel blocks on the LCD but no text.
 
Last edited:
Yes, there are black pixel blocks on the LCD but no text.
hi
Are the pixel blocks totally black.?

You should have a 10K variable resistor between +5v and 0V with the slider of the pot going to the LCD contrast pin, the pot should be adjusted just to show faint pixel blocks.
 
Last edited:
If the OP's LCD_command() function is writing full 8 bits as two nybbles, could that be a problem during 4-bit initialization sequence?

I use a special command just for sending a single 4-bit nybble during the 4-bit initialization procedure;

Mike

Code:
void InitLCD()              //
{
  delay_ms(15000);          // 4-bit initialization procedure
  PutLCD(nyb,3);            // wr 1 nybble (8 bit mode, includes 160 us delay)
  delay_us(4100);           //
  PutLCD(nyb,3);            // wr 1 nybble (8 bit mode, includes 160 us delay)
  PutLCD(nyb,3);            // wr 1 nybble (8 bit mode, includes 160 us delay)
  PutLCD(nyb,2);            // wr 1 nybble, switch to 4 bit mode
                            // now write 2 nybbles every time
  PutLCD(cmd,0x28);         // 4 bit mode, 2 lines, 5x7 font
  PutLCD(cmd,0x08);         // display off, cursor off, blink off
  PutLCD(cmd,0x01);         // clear display (includes 1.55 msec delay)
  PutLCD(cmd,0x06);         // cursor inc, shift off
  PutLCD(cmd,0x0C);         // display on, leave cursor off
}
 
If the OP's LCD_command() function is writing full 8 bits as two nybbles, could that be a problem during 4-bit initialization sequence?

I use a special command just for sending a single 4-bit nybble during the 4-bit initialization procedure;

Mike

Code:
void InitLCD()              //
{
  delay_ms(15000);          // 4-bit initialization procedure
  PutLCD(nyb,3);            // wr 1 nybble (8 bit mode, includes 160 us delay)
  delay_us(4100);           //
  PutLCD(nyb,3);            // wr 1 nybble (8 bit mode, includes 160 us delay)
  PutLCD(nyb,3);            // wr 1 nybble (8 bit mode, includes 160 us delay)
  PutLCD(nyb,2);            // wr 1 nybble, switch to 4 bit mode
                            // now write 2 nybbles every time
  PutLCD(cmd,0x28);         // 4 bit mode, 2 lines, 5x7 font
  PutLCD(cmd,0x08);         // display off, cursor off, blink off
  PutLCD(cmd,0x01);         // clear display (includes 1.55 msec delay)
  PutLCD(cmd,0x06);         // cursor inc, shift off
  PutLCD(cmd,0x0C);         // display on, leave cursor off
}

maybe this could work! how do u define your PutLCD() function
 
If writing 8 bits is the problem then a write nibble function should solve it,

Code:
[COLOR="Blue"]void LCD_nibble(unsigned char nibble){
    LCD_CTRL_PORT &= ~(1<<LCD_rs); 
    LCD_DATA_PORT = (nibble & 0xF0)|(LCD_DATA_PORT & 0x0F); 
    LCD_enable(); 
}[/COLOR]

void LCD_init() 
{ 

   //initialize LCD control lines 
   LCD_CTRL_PORT &= ~(1<<LCD_rs);   // RS low 
   LCD_CTRL_PORT &= ~(1<<LCD_rw);   // R/W low 
   LCD_CTRL_PORT &= ~(1<<LCD_en);   // E low 

   // initialize LCD control lines to output 
   LCD_CTRL_DDR |= (1<<LCD_rs); 
   LCD_CTRL_DDR |= (1<<LCD_rw); 
   LCD_CTRL_DDR |= (1<<LCD_en); 

   // initialize LCD data port to input 
    LCD_DATA_DDR |= 0xF0;// Data on high four bits of port 

[COLOR="blue"]    _delay_ms(15);		//start of required sequnce
    LCD_nibble(0x30);
    _delay_ms(5); 
    LCD_nibble(0x30);
    _delay_ms(1); 
    LCD_nibble(0x30);	
    _delay_ms(1); 
    LCD_nibble(0x20);		//switch to 4 bit mode[/COLOR]

   LCD_start(); 
   LCD_function_set(); 
    _delay_us(40); 
   LCD_display_off(); 
   _delay_us(40); 
   LCD_display_clear(); 
   _delay_ms(2); 
   LCD_mode_set(); 
   LCD_display_on(); 
}

The blue bits are the changes from your original code.

Mike.
 
This is my first attempt from a month ago. It's pretty messy and I'm still adding types to the function but here's how I did it (below).

I didn't include the lcd_nyb() function because it's hard-coded for the 2-pin Myke Predko 74LS174 LCD interface rather than the standard 6 or 7 pin 4-bit interface that you're using but it should give you an idea of how I send the single nybbles that I believe are required during the 4-bit LCD initialization procedure.

Mike

Code:
#define cmd 0                   // LCD RS = 0
#define dat 1                   // LCD RS = 1
#define nyb 2                   // LCD RS = 0

void PutLCD(unsigned char ptype, unsigned char pbyte)
{
  unsigned char temp;
  if(ptype.1)                   // if 'dat' type
    RS = 1;                     //
  else                          // a 'nyb' or 'cmd' type
    RS = 0;                     //
  temp = pbyte / 16;            //
  if(ptype != nyb)              // if not 'nyb' type
    lcd_nyb(temp);              // send the hi nybble
  temp = pbyte & 15;            //
  lcd_nyb(temp);                // send the lo nybble
  delay_us(150);                //
  if(ptype == cmd)              // if 'cmd' type and
    if(pbyte < 3)               // if 'clear' or 'home' command
      delay_us(1400);           // delay additional 1.4 msecs
}

void PutLCD(rom char *pdata)    // "overload", PutLCD("K8LH Clock")
{
  char n = 0;                   //
  char temp;                    //
  while(temp = pdata[n++])      //
    PutLCD(dat,temp);           //
}
 
t.man,

Please try Pommie's procedure. It looks like the perfect solution.

Also look into your contrast hardware. A chap over on Forum.Microchip uses fixed resistors but I seem to recall he uses two resistors as a voltage divider. Your single resistor to ground may be a problem.

Mike
 
they r not totally black.


Actually i've connected 120 ohm resistor from contrast pin to ground, could that be a problem?

hi,
I would recommend you follow Pommie and Mike's guidance on the program.

When you said black, my concern was that the pixel blocks were totally black, in that case you would not see any characters that were being displayed..:)

When you get it working, fit a small 10K pot to give optimum contrast.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top