Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

I can write into the lcd.

Status
Not open for further replies.

iVenki

Member level 3
Joined
Apr 2, 2011
Messages
60
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,771
I can't write into the lcd 16 x 2

This is the code
// Program to display a single alphabet ‘A’ on LCD
/*
LCD data transfer through 8 bit mode
Writing a single letter A on LCD

LCD DATA port----PORT A
ctrl port------PORT B
rs-------PB0
rw-------PB1
en-------PB2
*/

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

#define LCD_DATA PORTA // LCD data port
#define ctrl PORTB
#define en PB2 // enable signal
#define rw PB1 // read/write signal
#define rs PB0 // register select signal

void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);

int main()
{
DDRA=0xff; // making LCD_DATA port as output port
DDRB=0x07; // making signal as out put
init_LCD(); // initialization of LCD
_delay_ms(50); // delay of 50 milli seconds
LCD_write('A'); // call a function to write A on LCD
return 0;
}

void init_LCD(void)
{
LCD_cmd(0x38); // initialization of 16X2 LCD in 8bit mode
_delay_ms(1);

LCD_cmd(0x01); // clear LCD
_delay_ms(1);

LCD_cmd(0x0E); // cursor ON
_delay_ms(1);

LCD_cmd(0x80); // ---8 go to first line and --0 is for 0th position
delay_ms(1);
return;
}

void LCD_cmd(unsigned char cmd)
{
LCD_DATA=cmd;
ctrl =(0<<rs)|(0<<rw)|(1<<en); // RS and RW as LOW and EN as HIGH
_delay_ms(1);
ctrl =(0<<rs)|(0<<rw)|(0<<en); // RS, RW , LOW and EN as LOW
_delay_ms(50);
return;
}

void LCD_write(unsigned char data)
{
LCD_DATA= data;
ctrl = (1<<rs)|(0<<rw)|(1<<en); // RW as LOW and RS, EN as HIGH
_delay_ms(1);
ctrl = (1<<rs)|(0<<rw)|(0<<en); // EN and RW as LOW and RS HIGH
_delay_ms(50); // delay to get things executed
return ;
}

Here's the circuit diagram.
**broken link removed**

I want to check if my lcd can write the data or not. How should I do that?

---------- Post added at 16:49 ---------- Previous post was at 16:48 ----------

The problem is I don't get any output in the lcd screen. It's just blank
 

No, I don't see any cursor.

---------- Post added at 20:21 ---------- Previous post was at 20:18 ----------

I see the blacklight though.
 

Try this code... Though it might show some warnings, ignore them...
If u find any doubts in this code, reply me... :)

//********************************************************************************************//
//********************************************************************************************//

// PROGRAM : LCD Display
// Description : This program is used to display characters on an LCD display
// LANGUAGE : C
// MICROCONTROLLER : ATMega 16
// AUTHOR : ROHIT GUNNALA
// COMPILER : WINAVR-20100110

//******************************************************************************************//
//******************************************************************************************//

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

extern char y;
write_command(void);
clear_display(void);
display(char[]);
write_data(void);
new_line(void);

void main()
{
DDRA=0xFF; // PortA as output
DDRD=0xFF; // PortD as output
//INITIALIZATION OF LCD
PORTA=0x38; // 8-bit 2 line 5x7 dots
write_command();
PORTA=0x0F; // Display ON cursor blinking
write_command();
clear_display();
display("HELLO...!!");
new_line();
display("I AM ROHIT....");
}

write_command()
{
PORTD&=~(1<<PD0); // Setting RS=0; command register selected
PORTD&=~(1<<PD1); // Setting RW=0; writing mode
PORTD|=(1<<PD2); // Giving a high to low pulse to enable pin
_delay_ms(1);
PORTD&=~(1<<PD2);
_delay_ms(1);
}

clear_display()
{
PORTA=0x01; // From LCD basic commands
write_command();
}

display(char y[])
{
int i, j=strlen(y);
for(i=0;i<j;i++)
{
PORTA=y;
write_data();
_delay_ms(1);
}
}

write_data()
{
PORTD|=(1<<PD0); // Setting RS=1; data register selected
PORTD&=~(1<<PD1); // Setting RW=0; writing mode
PORTD|=(1<<PD2); // Giving a high to low pulse to enable pin
_delay_ms(1);
PORTD&=~(1<<PD2);
_delay_ms(1);
}

new_line()
{
PORTA=0xC0; // From LCD basic commands
write_command();
}
 

New development. I had no potentiometer so I didn't connect anything to 3 at all. Aftwards I connected 3 to ground and saw some thing of this pattern in the lcd screen.
:: :: :: :: :: :: ::
:: :: :: :: :: :: ::

Does this have any connection to the solution?

Thanks in advance.

---------- Post added at 21:38 ---------- Previous post was at 21:35 ----------

I haven't changed the program yet
 

Do you know the model number or controller chipset of the LCD you are attempting to use?

Also all LCDs have a powerup cycle which can take up to 15 to 20 ms before they are ready to accept input.

Try putting a 20 ms delay before starting your LCD initialization routine. Depending on your LCD controller chipset there are additional delays required the initialization procedure and each issued command unless you monitor the busy flag.

BigDog
 
Connect a pot, with the wiper connected to pin 3 of the LCD, and the other 2 connected to +5v and ground. Adjust the pot to see when the LCD displays something. As said before, add a 20ms delay before LCD initialization. Which controller does it use? I think it's HD44780.

---------- Post added at 01:55 ---------- Previous post was at 01:46 ----------

The code simulates properly, so I think it's fine. So, connect the pot as I said and I think your problem should be solved.
 

Okay. I don't have a potentiometer right now. I will try after buying it. I want to check whether my atmega has given the correct output or not. What should be the final voltages in the pins 1,2,3 and PortA after giving the supply? Is it possible to check whether lcd 16 x 2 is working or not ?
 

Pin 3 is simply the contrast control. A typical value for the pot is 10KΩ, so use two 4.7KΩ resistors to form a voltage divider with pin 3 the connection between the two. The application of 2.5v to pin 3 should enable you to see what is being displayed on the LCD. If you wish you can experiment with other combination of resistors to maximize the display quality, keeping the total resistance around 10KΩ.

After put the resistors in place, add the 20ms delay to your code I mentioned earlier and see if this corrects the problem.

And please indicate what model of LCD you are using or its controller chipset.

BigDog
 

I don't know what you mean by model as I am new to lcd 16 x 2 but this was written in my lcd 16 x 2.

JHD 162A
 

Here is the datasheet for your model JHD162A which uses the KS0066 Controller Chipset:

**broken link removed**

Keep a copy of the datasheet handy for future reference.

Have you installed the resistors?

BigDog
 
Here is the datasheet for your model JHD162A which uses the KS0066 Controller Chipset:

**broken link removed**

Keep a copy of the datasheet handy for future reference.

Have you installed the resistors?

BigDog

Im also a victim of this contras PIN of 16x2 LCD I keep editing my code and hardware connections if something wrong.. luckily i figured it out after 1.5 hours.. hehe lol

I dont want to read your code :) Im not good in debugging but instead you can use this code if you want.. this is woking.. :)

4bit mode programming:

PHP:
#include<htc.h>
#include"lcd.h"



void delayus(unsigned char delay){
    while(delay--);
}

void delayms(unsigned char delay){
    while(delay--)
        delayus(149);
}

void lcd_reset()
{
    LCD = 0xFF;
    delayms(40);
    LCD = 0x03+LCD_EN;
    LCD = 0x03;
    delayms(40);
    LCD = 0x03+LCD_EN;
    LCD = 0x03;
    delayms(5);
    LCD = 0x03+LCD_EN;
    LCD = 0x03;
    delayms(5);
    LCD = 0x02+LCD_EN;
    LCD = 0x02;
    delayms(5);
}


void lcd_init ()
{
     TRISC = 0x20;

    //CMCON |= 111; //make RA3:RA0 as digital and disable comparator
    
    lcd_reset();
    lcd_cmd(LCD_SETFUNCTION);                    // 4-bit mode - 1 line - 5x7 font. 
    lcd_cmd(LCD_SETVISIBLE+0x04);                // Display no cursor - no blink.
    lcd_cmd(LCD_SETMODE+0x02);                   // Automatic Increment - No Display shift.
    lcd_cmd(LCD_SETDDADDR);                      // Address DDRAM with 0 offset 80h.
 }

 void lcd_cmd (char cmd)
{ 
    LCD = ((cmd >> 4) & 0x0F)|LCD_EN;
    LCD = ((cmd >> 4) & 0x0F);

    LCD = (cmd & 0x0F)|LCD_EN;
    LCD = (cmd & 0x0F);

    delayus(250);
    delayus(250);
}

void lcd_data (unsigned char dat)
{ 
    LCD = (((dat >> 4) & 0x0F)|LCD_EN|LCD_RS);
    LCD = (((dat >> 4) & 0x0F)|LCD_RS);
    
    LCD = ((dat & 0x0F)|LCD_EN|LCD_RS);
    LCD = ((dat & 0x0F)|LCD_RS);

    delayus(250);
    delayus(250);
}

void lcd_str (unsigned char *str)
{
    while(*str)
    lcd_data(*str++);
    
        
    
}
 

I didn't try with a potentiometer. I connected a 10 k resistor to the point 3 and grounded it's(10k) other end. I still got the same output.
Here's the picture of it.

No one answered me this question.
How to check if my lcd 16 x 2 is working or not?
 

There's no point in connecting it to ground. If you don't have a pot with you now, do what has been suggested. Create a few voltage dividers with different voltage outputs within the range of 0 to 5v and connect pin 3 to that output. Start off with 2.5v by connecting two 10k resistors in series and creating the voltage divider.
The best way to test your LCD would be to do what you are doing - send some text from a microcontroller to be displayed.

Hope this helps.
Tahmid.
 

How to check if my lcd 16 x 2 is working or not?

I think you can test it by actual connecting it to a circuit with a working program.. :)

---------- Post added at 14:24 ---------- Previous post was at 14:05 ----------

the code I've posted is working. try it if you want
 

From the photo, I guess your problem is improper initialization. If the hardware connections are okay and if you powered the LCD, it will show like this as in your photo. Nothing is wrong with the LCD. After a proper initialization only it will enter the working mode.

I think this is the best link for LCD:
Initialization Issues
 

I didn't try with a potentiometer. I connected a 10 k resistor to the point 3 and grounded it's(10k) other end. I still got the same output.

That' fine. The JHD162A datasheet actually suggests this approach.

No one answered me this question.
How to check if my lcd 16 x 2 is working or not?

It's WORKING, I can tell from the photo.


From the photo, I guess your problem is improper initialization. If the hardware connections are okay and if you powered the LCD, it will show like this as in your photo. Nothing is wrong with the LCD. After a proper initialization only it will enter the working mode.

I think this is the best link for LCD:
Initialization Issues

As both Vinodstanur and I have indicated, the problem appears to be your LCD initialization sequence. Without the proper delays the LCD will not initialize and function.

Add the proper delays and command sequences to your code, then post the updated code so that it can be examined.

The link Vinodstanur provided has an excellent flowchart show the proper delays and command sequence.

Actually the diagram is originally from the .



After you post your updated code and results we'll take the next step.

BigDog
 

Now it's blank. This is my modified code.

//Program to Display string on LCD using AVR Microcontroller (ATmega16)
/*
LCD DATA port----PORT B
signal port------PORT D
rs-------PD0
rw-------PD1
en-------PD2
*/

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

#define LCD_DATA PORTB //LCD data port

#define ctrl PORTD
#define en PD2 // enable signal
#define rw PD1 // read/write signal
#define rs PD0 // register select signal

void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);

int main()
{
DDRB=0xff;
DDRD=0x07;
_delay_ms(20);
init_LCD(); // initialization of LCD
_delay_ms(50); // delay of 50 mili seconds
LCD_write_string("Welcome"); // function to print string on LCD
return 0;
}

void init_LCD(void)
{
LCD_cmd(0x38); // initialization of 16X2 LCD in 8bit mode
_delay_ms(1);

LCD_cmd(0x01); // clear LCD
_delay_ms(1);

LCD_cmd(0x0E); // cursor ON
_delay_ms(1);

LCD_cmd(0x80); // ---8 go to first line and --0 is for 0th position
_delay_ms(1);
return;
}

void LCD_cmd(unsigned char cmd)
{
LCD_DATA=cmd;
ctrl =(0<<rs)|(0<<rw)|(1<<en);
_delay_ms(1);
ctrl =(0<<rs)|(0<<rw)|(0<<en);
_delay_ms(50);
return;
}

void LCD_write(unsigned char data)
{
LCD_DATA= data;
ctrl = (1<<rs)|(0<<rw)|(1<<en);
_delay_ms(1);
ctrl = (1<<rs)|(0<<rw)|(0<<en);
_delay_ms(50);
return ;
}

void LCD_write_string(unsigned char *str) //store address value of the string in pointer *str
{
int i=0;
while(str!='\0') // loop will go on till the NULL character in the string
{
LCD_write(str); // sending data on LCD byte by byte
i++;
}
return;
}
 

when you say function is void why do you return??? as in LCD_Write function...

and in main function instead of return put while(1); as the last statement in main function.......

---------- Post added at 18:50 ---------- Previous post was at 18:47 ----------

where is your circuit diagram.. from one of the screen shots its looks ok as you can see black boxes..but i wanted to see if you used pull up for port pins.. please put your circuit here.........
 

Ok Ivaneki,
i never used atmega, my code works fine for p89v51 and at89s52 >> i need you to convert this for your atmega
its working with jhd162A,
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
#include<reg52.h>
#define ldata P1 //16x2 lcd data pins to port p1
sbit en = P2^2; //enable pin of jhd162A
sbit busy = P1^7; //D7 pin of jhd162A
sbit rs = P2^0; //rs pin of jhd162A
sbit rw = P2^1; //rw pin of jhd162A
void lcdcmd(unsigned char l);
void lcddata(unsigned char l);
void MSDelay(unsigned int t);
void lcdready();
void callmsg();
void callme();
void main()
{
while(1)
{
lcdcmd(0x38);
lcdcmd(0x0E);
lcdcmd(0x01);
lcdcmd(0x06);

callmsg();
MSDelay(275);

lcdcmd(0x01);
lcdcmd(0x06);

callme();
MSDelay(275);
MSDelay(275);
}
}
void callmsg()
{
unsigned char message[] = "J@i GuruDev :)";
unsigned char z,l;

for(z=0;z<14;z++)
{
l = message[z];
lcddata(l);
MSDelay(1000);
}
}
void callme()
{
unsigned char message[] = "Tushar $achdeva";
unsigned char z,l;

for(z=0;z<15;z++)
{
l = message[z];
lcddata(l);
MSDelay(1000);
}
}

void lcdcmd(unsigned char l)
{
lcdready();
ldata = l;
rs = 0;
rw = 0;
en = 1;
MSDelay(1);
en = 0;
return;
}
void lcddata(unsigned char l)
{
lcdready();
ldata = l;
rs = 1;
rw = 0;
en = 1;
MSDelay(1);
en = 0;
return;
}

void lcdready()
{
busy = 1;
rs = 0;
rw = 1;
while(busy==1)
{

en = 0;
MSDelay(1);
en = 1;

}

return;

}
void MSDelay(unsigned int t)
{

unsigned int i,j;
for(i=0;i<t;i++)
{
for(j=0;j<250;j++)
{}
}
}



And if you connect pin3 (contrast pin to ground it will work, you will see dark black blocks)..

Good Luck :)
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top