LCD module and AVR

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

Hi,

I have a LCD module which uses the ks0066u driver.

I have a tutorial for LCD modules that is for the Hitachi HD44780.

I'm trying to drive the LCD module with a AVR but the first commands i'm trying are not doing a thing.

My question is that if the commands for the HD44780 driver are the same for the ks0066u driver.

Thx,

Best regards,

Nuno

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

Yes, ks0066u is compatible with HD44780. I just heard in my LCD topic today. https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=44813

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

I have taken an overview of ks0066u & seems that they are the same. Your first inclination should be that it works and believe that it will work.

Be a bit elaborative on your post. This is a wonderful forum. You will get the answer

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

Oops a bit late

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

Maybe you should read my topic, see my previous reply.

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

Quote:

Yes, ks0066u is compatible with HD44780.

Careful! Although 44780 clones probably are identical in most aspects differences might occur. Look especially for differences in timing constraints and (IIRC) slight differences in the init sequence.

My two favourite 44780 documents can be found here:
https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=116409#116409(PDFs in ZIP files)

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

Hi,

If you are talking about "how to intelligent lcds" then is what i have.

I doing precisly the first things that they sugest to do in the experimental rig, even before using a micro processor.

But i'm trying to do this with a micro.

#include 
#include 
#define F_CPU 10000000
#include 

int main( void ) {
	
	DDRC = 0xFF;
	DDRD = 0xFF;

	PORTC = 0x00;
	PORTD = 0x38;

	PORTC = 4;
	return 0;
}

I'm trying to have a flashing cursor with underline

I have the LCD data lines connected to the PORTD bits and the other 3 connected to the first 3 bits of PORTC.

But nothing happens in the LCD.

The only thing i got its the same i got when i power it up... The second full of total black dots.

I have a 2x16 LCD.

Do you guys think this is because of the timings that i'm not using?

Cheers,

Nuno

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

The good thing is that the LCD seems to be OK. The bad thing is that what do you have is exactly what appears when initialization is not correct. Also need to adjust the contrast.

More bad news: I had played a lot with other kind of LCD (mainly graphical), but not too much with alphanumeric ones. But what I could say is that the later ones, altough more usually standard and attached to the HD44780 'standard' lack in a big point: the timming is usually critical and the intialization, although always the same parameters, quite complex (about the same than graphic LCD's, but with the timming issue) and dependant on the timming, that often is different.

Better take a look to others code, and check with different timmings/delays.

Guillem.

Guillem.
"Common sense is the least common of the senses" Anonymous.

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

There are lots of example codes out there that you can have a look at!
If you want to write it all from scratch that's fine, but the timings ARE critical, you cannot write too slow to the display though, so you can always use trial and error. (You can use a dip-switch to write to it by hand actually)

Another thing, unless you are actually going to read data from the display (i've never used it), you can tie the R/W pin of the LCD to ground and save a I/O pin on the micro.

There is also the possibility to use 4-bit mode, that way you can save another 4 pins on the micro, i think most people use their HD44780's in 4 bit mode! That way you can do it all with just one port! But for starters the 8-bit mode is by far the easiest way to communicate with the LCD. :)

Brian

- Brian

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

Hi,

Where can i get the codevision lcd functions?

Cheers,

Nuno

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

With the Codevision compiler/toolchain maybe? Google puts http://www.codevision.be/ up as the very first hit when I search for Codevision. From there I downloaded the evaluation version.

From what I see the LCD functions are delivered as binaries only - no source code. The code snippet above looks like AVR-GCC, and if that is the compiler you are using then no CV binary will help you.

My suggestion is to read up on a proper init sequence, and for that you need a data sheet for the KS0066U. When I Google for that the very first hit points to a PDF which seems to be the thing On p 26-27 the proper init sequences are described.

Assuming that the init sequences for a 44780 and a KS066U are similar I'd say that the code in the post above is not a proper init sequence. Many display controllers will init without a proper init sequence, but for that to happend certain requirements exist for the electrical characteristics of the power-up sequence. Again, you should turn to the proper data sheet to determine how to acheieve this, if at all possible.

And finally: You should learn how to make use of the search functionality here. Init of LCDs has been discussed many many times. This is just one example (that might give you some clues/hints): https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=209301#209301. A thorough search should reveal more threads similar to that one.

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

Hi,

I have the proper datasheet but it only confuses me more.

In the initialization it tell to:

1 - Display clear instruction: write 0x20 to all DDRAM.

DDRAM is the data bits?

2 - Set function instruction:
DL = High
N = Low
F = Low

What is DL, N and F?

I was expecting to hear about RS,R/W,E

and the remaing steps i have the same problem in understand what this letter mean.

In the tutorial i told me about, that is the one i got in the hand experimental prototype it says to put data lines with the value "0x0F" and make RS switch 0 to receive command.
And then to put E high. Well, i'm supposed to see a flashing cursor...

I gave a lot of time because when we do this by hand its completly different:

#include 
#include 
#define F_CPU 10000000
#include 

int main( void ) {
	
	DDRC = 0xFF;
	DDRD = 0xFF;

	PORTC = 0x00;
	PORTD = 0x0F;

	_delay_ms(500);

	PORTC = 0x04;

	while(1);

	return 0;
}

You are right! I'll do some search around.

Thx,

Nuno

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

The following code is for the HD44780 based LCD. It is using 8 bit mode and R/W is forced low all of the time as, it depends on fixed delays and not the READY status flag of the display.

The initialization is a bit off-standard from the HD44780 datasheet but, I've never had an LCD not work properly because of this in more then 12 years. The timing of the RS & E to the presentation of the DATA are as per the HD44780 datasheet. The delays will have to be increased if a crystal greater the 8.000 MHz is used on the target microcontroller. Though, if a lower frequency crystal is used, all delays can remain the same.

For the record, this particulay rendition of LCD code is a result of some preliminary work that I was involved with when Johan was working on his LCD display tutorial. This code is different enough that, it should not impenge on the code that Johan has been developing.

For you that think this code is un-orthodox, it might be, but, it has been working flawlessly and I stand by it as it applies to the ImageCraft ICCAVR v7.xx C compiler.

No guarantees of proper operation are offered for the other standard C complier flavors that are out there.

// My_LCD.c

// Compiler: ImageCraft ICCAVR v7.xx
// Crystal: 8.000 MHz
// Data: PORTA
// Control: PORTB
// RS = PORTB, bit 0, 0x01
// RW = PORTB, bit 1, 0x02
// E = PORTB, bit 2, 0x04

#include 

// Define LCD Register Select as PORTB, 0x01;
#define LCD_RS 0
// Define LCD Read/Write as PORTB, 0x02;  
#define LCD_RW 1
// Define LCD Enable as PORTB, 0x04;  
#define LCD_E 2   

// TURN ON POWER TO THE DISPLAY, NO CURSOR
#define	PWR_CMD	0x0C
// SET FOUR LINE, 8 DATA BIT MODE		
#define	DL_CMD	0x38
// CLEAR DISPLAY COMMAND		
#define CLR_DSP 0x01

#define LINE1 0x80
#define LINE2 0xC0
#define LINE3 0x94
#define LINE4 0xD4

#define NULL 0x00

const char BANNER_1[] = {"Having Fun"};
const char BANNER_2[] = {"With LCD's"};
const char BANNER_3[] = {"By"};
const char BANNER_4[] = {"Carl W. Livingston"};

void LCD_Delay (unsigned long int d);
void LCD_IO_INIT (void);
void LCD_INIT (void);
void LCD_PutCmd (char);
void LCD_PutChar (char); 
void LCD_PutString (const char *);

void main (void)
{
 	LCD_IO_INIT ();
	LCD_INIT ();
	
	while(1)
	{
	    // Add other LCD related program operations here...
	}			
}

void LCD_Delay (unsigned long int d)
{
    unsigned long int n;
    for (n = 0; n < d; n++);
} 

void LCD_IO_INIT (void)
{
    DDRA = 0xFF; // PORTA is the LCD DATA LINES
    PORTA = 0x00;
    DDRB |= 0x07; // PORTB is the LCD CONTROL LINES
    PORTB |= 0x05; // LCD_E = HIGH, LCD_RW = LOW, LCD_RS = HIGH
    LCD_Delay (500); // Wait for the up LCD to power up			
}

void LCD_INIT (void)
{
    LCD_PutCmd (PWR_CMD); // Power up the display
    LCD_PutCmd (DL_CMD);  // Set to 4 lines, 8 bit, no cursor
    LCD_PutCmd (CLR_DSP); // Clear the display
    LCD_Delay (500); // Wait for the LCD to boot up	
	
	LCD_PutCmd (LINE1+5);
	LCD_PutString (BANNER_1);
	LCD_PutCmd (LINE2+5);
	LCD_PutString (BANNER_2);
	LCD_PutCmd (LINE3+9);
	LCD_PutString (BANNER_3);
	LCD_PutCmd (LINE4+1);
	LCD_PutString (BANNER_4);	
}
  
void LCD_PutCmd (char c) 
{
  PORTB &= ~(1<<LCD_RS);
  LCD_Delay (5); // Wait for the proper setup time to respond to the RS control line  
  LCD_PutChar(c);
  LCD_Delay (5); // Wait for the proper setup time to respond to the command being applied 
  PORTB |= (1<<LCD_RS);
}

void LCD_PutChar (char c) 
{
    PORTB |= (1<<LCD_E);
    LCD_Delay (5); // Wait for the proper setup time to respond to the E pulse	
    PORTA = c;
    LCD_Delay (5); // Wait for the proper setup time to respond to the character being applied
    PORTB &= ~(1<<LCD_E);
}
 
void LCD_PutString (const char *p) 
{
    char n = NULL; // Pointer position counter.
    while (p[n] != NULL) // Keep sending data until the NULL character is found.
  	    LCD_PutChar(p[n++]);
}

Edit:

What would be really nice is, if those who use WinAVR, GCC, IAR (or whatever other C compiler is out there) could test this code and maybe a version of the code could be devised that works for every flavor compiler out there.

That would give a "Base-Line" starting point of code that works for the "Newbe" and he/she could take it on their own from there.

I think that was the objective of Johan's tutorial but, I think he has been swamped with work and other matters right now.

Anyway... It was just a thought.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

Hi,

I have tested your code! Unfortunatly the result is the same i was having... this is... nothing!

I have a 2x16 lcd module and when i turn it up the only thing that happens its the first line blank and the second with black squares for all of it.

I'm using WinAVR with atmega 48 running at 1 Mhz (its internal frequency divided by 8).

Nuno

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

The gcc delay_ms routine poops out above 240ms. They should call it delay_0to240_ms. You are trying to get it to delay 500 ms and it obviously isnt doing what you want.

Imagecraft compiler user

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

bobgardner wrote:
The gcc delay_ms routine poops out above 240ms. They should call it delay_0to240_ms. You are trying to get it to delay 500 ms and it obviously isnt doing what you want.

Hey Bob, If you have an HD44780 based LCD display, can you possibly see if the code I posted at least initializes on err, your development system? Especially since you have the ImageCraft ICCAVR v7.xx compiler.

I've had no problems from this code and I don't know why it wouldn't work. It seems to me to be quite generic. It doesn't use any built in functions and, the delay function ought to go out to about 4 billion counts.

In addition, by moving the data buss and control pins, Iv'e had this code running on the AT90s2313, Tiny2313, Mega8, Mega88, Mega16, Mega32, Mega64 and Mega128.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

Hello Sinusoidal. You say your mega48 is running at 1mhz, but the winavr example you posted shows 10mhz. That one little extra zero puts the timing off by a factor of 10. Your init problem seems to be timing related. Perhaps I have found your problem? Happy New Year!

Imagecraft compiler user

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

bobgardner wrote:
Hello Sinusoidal. You say your mega48 is running at 1mhz, but the winavr example you posted shows 10mhz. That one little extra zero puts the timing off by a factor of 10. Your init problem seems to be timing related. Perhaps I have found your problem? Happy New Year!

In fact you were right, my frequency was wrong. I have corrected it but unfortunatly i couldnt see any positive results... :cry:

I had to change the ports name in the code posted by microcarl. My control bits port is PORTC and my data bits port is PORTD.

I also changed the frequency to 8 mhz, without the divider.

The actual code is:

#include 
#include 
#define F_CPU 8000000
#include  

// Define LCD Register Select as PORTC, 0x01;
#define LCD_RS 0
// Define LCD Read/Write as PORTC, 0x02; 
#define LCD_RW 1
// Define LCD Enable as PORTC, 0x04; 
#define LCD_E 2   

// TURN ON POWER TO THE DISPLAY, NO CURSOR
#define   PWR_CMD   0x0C
// SET FOUR LINE, 8 DATA BIT MODE      
#define   DL_CMD   0x38
// CLEAR DISPLAY COMMAND      
#define CLR_DSP 0x01

#define LINE1 0x80
#define LINE2 0xC0
#define LINE3 0x94
#define LINE4 0xD4

#define NULL 0x00

const char BANNER_1[] = {"Having Fun"};
const char BANNER_2[] = {"With LCD's"};
const char BANNER_3[] = {"By"};
const char BANNER_4[] = {"Carl W. Livingston"};

void LCD_Delay (unsigned long int d);
void LCD_IO_INIT (void);
void LCD_INIT (void);
void LCD_PutCmd (char);
void LCD_PutChar (char);
void LCD_PutString (const char *);

void main (void)
{
    LCD_IO_INIT ();
   LCD_INIT ();
   
   while(1)
   {
       // Add other LCD related program operations here...
   }         
}

void LCD_Delay (unsigned long int d)
{
    unsigned long int n;
    for (n = 0; n < d; n++);
}

void LCD_IO_INIT (void)
{
    DDRD = 0xFF; // PORTD is the LCD DATA LINES
    PORTD = 0x00;
    DDRC |= 0x07; // PORTD is the LCD CONTROL LINES
    PORTC |= 0x05; // LCD_E = HIGH, LCD_RW = LOW, LCD_RS = HIGH
    LCD_Delay (500); // Wait for the up LCD to power up         
}

void LCD_INIT (void)
{
    LCD_PutCmd (PWR_CMD); // Power up the display
    LCD_PutCmd (DL_CMD);  // Set to 4 lines, 8 bit, no cursor
    LCD_PutCmd (CLR_DSP); // Clear the display
    LCD_Delay (500); // Wait for the LCD to boot up   
   
   LCD_PutCmd (LINE1+5);
   LCD_PutString (BANNER_1);
   LCD_PutCmd (LINE2+5);
   LCD_PutString (BANNER_2);
   LCD_PutCmd (LINE3+9);
   LCD_PutString (BANNER_3);
   LCD_PutCmd (LINE4+1);
   LCD_PutString (BANNER_4);   
}
 
void LCD_PutCmd (char c)
{
  PORTC &= ~(1<<LCD_RS);
  LCD_Delay (5); // Wait for the display to respone to the E pulse 
  LCD_PutChar(c);
  LCD_Delay (5); // Wait for the display to respone to the E pulse 
  PORTC |= (1<<LCD_RS);
}

void LCD_PutChar (char c)
{
    PORTC |= (1<<LCD_E);
    LCD_Delay (5); // Wait for the display to respone to the E pulse   
    PORTD = c;
    LCD_Delay (5); // Wait for the display to respone to the E pulse
    PORTC &= ~(1<<LCD_E);
}
 
void LCD_PutString (const char *p)
{
    char n = NULL; // Pointer position counter.
    while (p[n] != NULL) // Keep sending data until the NULL character is found.
         LCD_PutChar(p[n++]);
}

Nuno

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

sinosoidal wrote:
In fact you were right, my frequency was wrong. I have corrected it but unfortunatly i couldnt see any positive results... :cry:

I had to change the ports name in the code posted by microcarl. My control bits port is PORTC and my data bits port is PORTD.

I also changed the frequency to 8 mhz, without the divider.

Nuno

So the question is???

Does my code work????????

Also, you include the following:

#include  
#include  
#define F_CPU 8000000 
#include  

As you are using no intrrupts:

#include  

and, as the LCD_Delay() is an integral part of my code:

#include 

Are these includes actually needed?

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

I thought you said you had a 16 x 2 display. That code is for a 4 line display. Which do you have? One quick question... can you tell me how many wires run to port d? (you have a choice of 4 or 8)

Imagecraft compiler user

Last Edited: Tue. Dec 26, 2006 - 06:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:
I thought you said you had a 16 x 2 display. That code is for a 4 line display. Which do you have?

He probably won't see the 2nd and 4th lines as, they will be hidden untill the display is scrolled left or right.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

No, your code does nothing in my circuit and lcd module.

I have a 16x2 display.

I have all the 8 pins of PORTD connected to lcd module.

The other includes are not necessary but i know that they arent doing nothing. They were just taken from my other project.

Cheers,

Nuno

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

@Microcarl
What wiring you need for your code?

PORTb 1 - 3 to RS, RW and E?

PORTA 0 -> DB0
PORTA 1 -> DB1
..
PORTA 7 -> DB7

That is all(and the power supply offcourse)?

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

naffets wrote:
@Microcarl
What wiring you need for your code?

PORTb 1 - 3 to RS, RW and E?

PORTA 0 -> DB0
PORTA 1 -> DB1
..
PORTA 7 -> DB7

That is all(and the power supply offcourse)?

PIN 1 = GND = 5 V COMON
PIN 2 = Vcc = +5 VDC
PIN 3 = Vee = CONTRAST POT SLIDER

PIN 4 = PORTB:0 = RS
PIN 5 = PORTB:1 = R/W
PIN 6 = PORTB:2 = E

PIN 7 = PORTA:0 = DB0
.
.
.
PIN 14 = PORTA:7 = DB7

This is what is currently working on my proto-board.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

Hi again,

I've been out of this since i have a lot of work by now.

Although, today i was trying again to put it working.

I've looked to several codes around.

But they all give me nothing.

I decided to give a new closer look to your code carl.

I needed to change some stuff as i only have 2 lines and my avr mega 88 doesnt have a port A

So i replaced all the PORTA and DDRA occurences by PORTD and DDRD.

I also replaced all the occurences of PORTB and DDRB to PORTC and DDRC.

About my LCD, it is not driven by hitachi. It is controlled by ks0066.

I choose the following addresses for the 2 lines:

#define LINE1 0x00
#define LINE2 0x40

Based on the "how to use inteligent LCD modules tutorial". I assume it's the same.

I have his datasheet:

http://www.datasheets.org.uk/dat...

I'm trying to make the initialization using the information on page 26:

The first thing i dont understand its fosc condition: 270khz.

Do i need to have that frequency in my chip? (i assume not)

In your code carl, there is no delay between these initialization operations. Is this a problem?

I also had to change two commands you have:

// TURN ON POWER TO THE DISPLAY, NO CURSOR
#define PWR_CMD 0x3F // now corresponds to function set
// SET 2 LINE, 8 DATA BIT MODE
#define DL_CMD 0x0F // now correspondes to display on/off control

Well, i tried to gather all the information i remembered.

And thanks for all the support give until now.

Many thx and happy new year

Nuno

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

sinosoidal wrote:
Hi again,

I decided to give a new closer look to your code carl.

Nuno

Let me refer you to this latest post.

https://www.avrfreaks.net/index.p...

I don't have a Mega88 so I couldn't test the code for that controller. I did test the code on a Mega168 and it worked fine so, the code should work for the Mega88 as, the Mega88 is the little brother to the Mega168.

I've been working on this for the past two days and have added quite a bit to it.

Let me know how it works out...

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

Quote:

The first thing i dont understand its fosc condition: 270khz.
Do i need to have that frequency in my chip? (i assume not)

No, your assumption is correct. What the data sheet is talking about is the frequency of the oscillator for the LCD controller (HD44780, KS0066, whatever...). Assume its 270 KHz and move on.

Bob wrote:

You say your mega48 is running at 1mhz, but the winavr example you posted shows 10mhz. That one little extra zero puts the timing off by a factor of 10. Your init problem seems to be timing related. Perhaps I have found your problem?

No, Bob. If the compiler generates delays based on a stated frequency of 10 MHz but the chip is actually running at 1 MHz then the delays will be 10 times longer than expected, not the other way around.

This is in fact a good thing. My first advice to avoid breaking timing constraints for a LCD module is to slow down the clock to "a ridicolously low value". The above manouvre will accomplish the same thing (although it might not have been intended).

Happy new year, everyone!

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

sinosoidal wrote:

I choose the following addresses for the 2 lines:

#define LINE1 0x00
#define LINE2 0x40

Based on the "how to use inteligent LCD modules tutorial". I assume it's the same.

That's where you have gone wrong. According to the LCD datasheet, the MSB should be set for the LCD to accept the command as DDRAM address. This is done correctly by using #define LINE1 0x80 in Microcarl's code.

I have tried Microcarl's LCD code on Tiny2313 and it works just fine.

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

eblc1388 wrote:
sinosoidal wrote:

I choose the following addresses for the 2 lines:

#define LINE1 0x00
#define LINE2 0x40

Based on the "how to use inteligent LCD modules tutorial". I assume it's the same.

That's where you have gone wrong. According to the LCD datasheet, the MSB should be set for the LCD to accept the command as DDRAM address. This is done correctly by using #define LINE1 0x80 in Microcarl's code.

I have tried Microcarl's LCD code on Tiny2313 and it works just fine.

Thank you very much!

I was beginning to think I was missing something very important.

Thank you for the confirmation that my program works correctly in another environment!!!

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

Hi again folks,

I'm getting crazy with this LCD module.

It is harder to work with it than learn to work with a AVR.

:(

I'm posting all the code i'm using right now.

Basicly it's carls code with some modifications because my hardware is atmega 88 and doesnt have PORTA. I also changed PORTB to PORTC.

In my hardware i use R/W always down to 0.

I also messed with the following defines:

// TURN ON POWER TO THE DISPLAY, NO CURSOR
#define PWR_CMD 0x3F
// SET 2 LINE, 8 DATA BIT MODE
#define DL_CMD 0x0F
// CLEAR DISPLAY COMMAND
#define CLR_DSP 0x01

Which based on what i understand from my datasheet they were not right... Well.. at this point i know nothing.... Grrr!!

#define F_CPU 80000000

// Data: PORTD
// Control: PORTC
// RS = PORTC, bit 0, 0x01
// RW = PORTC, bit 1, 0x02
// E = PORTC, bit 2, 0x04

#include 
#include 

// Define LCD Register Select as PORTC, 0x01;
#define LCD_RS 0
// Define LCD Read/Write as PORTC, 0x02; 
#define LCD_RW 1
// Define LCD Enable as PORTC, 0x04; 
#define LCD_E 2   

// TURN ON POWER TO THE DISPLAY, NO CURSOR
#define   PWR_CMD   0x3F
// SET 2 LINE, 8 DATA BIT MODE      
#define   DL_CMD   0x0F
// CLEAR DISPLAY COMMAND      
#define CLR_DSP 0x01

#define LINE1 0x80
#define LINE2 0x80


#define NULL 0x00

const char BANNER_1[] = {"Having Fun"};
const char BANNER_2[] = {"With LCD's"};

void LCD_Delay (unsigned long int d);
void LCD_IO_INIT (void);
void LCD_INIT (void);
void LCD_PutCmd (char);
void LCD_PutChar (char);
void LCD_PutString (const char *);

void main (void) {
   LCD_IO_INIT ();
   LCD_INIT ();
   
   while(1)
   {
       // Add other LCD related program operations here...
   }         
}

void LCD_Delay (unsigned long int d)
{
    unsigned long int n;
    for (n = 0; n < d; n++);
}

void LCD_IO_INIT (void)
{
    DDRD = 0xFF; // PORTD is the LCD DATA LINES
    PORTD = 0x00;
    DDRC |= 0x07; // PORTC is the LCD CONTROL LINES
    PORTC |= 0x05; // LCD_E = HIGH, LCD_RW = LOW, LCD_RS = HIGH
    LCD_Delay (500); // Wait for the up LCD to power up         
}

void LCD_INIT (void)
{
    LCD_PutCmd (PWR_CMD); // Power up the display
    LCD_PutCmd (DL_CMD);  // Set to 2 lines, 8 bit, no cursor
    LCD_PutCmd (CLR_DSP); // Clear the display
    LCD_Delay (500); // Wait for the LCD to boot up   
   
   LCD_PutCmd (LINE1+5);
   LCD_PutString (BANNER_1);
   LCD_PutCmd (LINE2+5);
   LCD_PutString (BANNER_2);
}
 
void LCD_PutCmd (char c)
{
  PORTC &= ~(1<<LCD_RS);
  LCD_Delay (5); // Wait for the proper setup time to respond to the RS control line 
  LCD_PutChar(c);
  LCD_Delay (5); // Wait for the proper setup time to respond to the command being applied
  PORTC |= (1<<LCD_RS);
}

void LCD_PutChar (char c)
{
    PORTC |= (1<<LCD_E);
    LCD_Delay (5); // Wait for the proper setup time to respond to the E pulse   
    PORTD = c;
    LCD_Delay (5); // Wait for the proper setup time to respond to the character being applied
    PORTC &= ~(1<<LCD_E);
}
 
void LCD_PutString (const char *p)
{
    char n = NULL; // Pointer position counter.
    while (p[n] != NULL) // Keep sending data until the NULL character is found.
         LCD_PutChar(p[n++]);
}

I'm using again 8 Mhz.

This is a screenshot of the bread board just for you guys check that i'm making the right connections or even discover something that is wrong.

http://www.imaginando.net/goodies/shot.jpg

I hope this helps you guys finding me the problem i have! ....

Best regards,

Nuno

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

80 Mhz is a real fast AVR

Imagecraft compiler user

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

bobgardner wrote:
80 Mhz is a real fast AVR

Yes, you were right. That was completly wrong, but i still dont have good news! :cry:

Thx

Nuno

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

The first thing I'd like to rule out is that this is not a timing problem. So: At what clock speed is your mega88 actually running?

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

Your program has gcc style include paths. I thought you were using the imagecraft compiler? If you have both compilers installed, maybe your problem has something to do with trying to compile the gcc includes with imagecraft? There should be an #include up there for imagecraft, and no avr/io and no util/delay etc.

Imagecraft compiler user

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

bobgardner wrote:
Your program has gcc style include paths. I thought you were using the imagecraft compiler? If you have both compilers installed, maybe your problem has something to do with trying to compile the gcc includes with imagecraft? There should be an #include up there for imagecraft, and no avr/io and no util/delay etc.

No. I'm actually using WinAVR, only!

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

sinosoidal wrote:
Basicly it's carls code with some modifications because my hardware is atmega 88 and doesnt have PORTA. I also changed PORTB to PORTC.

In my hardware i use R/W always down to 0.

I also messed with the following defines:

// TURN ON POWER TO THE DISPLAY, NO CURSOR
#define   PWR_CMD   0x3F
// SET 2 LINE, 8 DATA BIT MODE      
#define   DL_CMD   0x0F
// CLEAR DISPLAY COMMAND      
#define CLR_DSP 0x01

Which based on what i understand from my datasheet they were not right... Well.. at this point i know nothing.... Grrr!!Nuno

Well, the code that I posted has been verified as to be working code by two independant sources.

Either:
1. You are doing something wrong in the translation from one compiler to another.

2. You have a wiring error.

3. You have a deffective display.

I guess, like Bob, I am confused about exactly which compiler you are using.

Also, I think you need to re-visit the PWR_CMD, DL_CMD & CLR_DSP assignments as, I have been using these assignments for years and have never had the problems you are having, getting a text based LCD to work.

Also, I think a lengthy read of the datasheet of the LCD and a good understanding of the timing required, and a good understanding of the initialization process, will shed some light on some possable issues.

Over a three or four day span, I have re-written my original code at least three times, using different timing, initialization and bit lengths. All of the different code versions worked with several LCDs by several manufacturers. I have about 50 to 60 hours testing the compatability between these different LCD manufacturers. The only display that has given any issues at all was the Hyundi, which seemed slightly more sensitive to critically tight timing settings. But it still worked and only mis-placed a character occasionally.

What I can say, is that this whole thing has caused me to look at getting seriuos about a project that I have been wanting to do for a long, long time.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

microcarl wrote:
sinosoidal wrote:
Basicly it's carls code with some modifications because my hardware is atmega 88 and doesnt have PORTA. I also changed PORTB to PORTC.

In my hardware i use R/W always down to 0.

I also messed with the following defines:

// TURN ON POWER TO THE DISPLAY, NO CURSOR
#define   PWR_CMD   0x3F
// SET 2 LINE, 8 DATA BIT MODE      
#define   DL_CMD   0x0F
// CLEAR DISPLAY COMMAND      
#define CLR_DSP 0x01

Which based on what i understand from my datasheet they were not right... Well.. at this point i know nothing.... Grrr!!Nuno

Well, the code that I posted has been verified as to be working code by two independant sources.

Either:
1. You are doing something wrong in the translation from one compiler to another.

2. You have a wiring error.

3. You have a deffective display.

I guess, like Bob, I am confused about exactly which compiler you are using.

Also, I think you need to re-visit the PWR_CMD, DL_CMD & CLR_DSP assignments as, I have been using these assignments for years and have never had the problems you are having, getting a text based LCD to work.

Also, I think a lengthy read of the datasheet of the LCD and a good understanding of the timing required, and a good understanding of the initialization process, will shed some light on some possable issues.

Over a three or four day span, I have re-written my original code at least three times, using different timing, initialization and bit lengths. All of the different code versions worked with several LCDs by several manufacturers. I have about 50 to 60 hours testing the compatability between these different LCD manufacturers. The only display that has given any issues at all was the Hyundi, which seemed slightly more sensitive to critically tight timing settings. But it still worked and only mis-placed a character occasionally.

What I can say, is that this whole thing has caused me to look at getting seriuos about a project that I have been wanting to do for a long, long time.

And i belive your code!

Something must be wrong...

I guess i will take everything how and do the wiring again. Just from the scratch.

I'll give some feedback later

Cheers,

Nuno

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

sinosoidal wrote:
Basicly it's carls code with some modifications because my hardware is atmega 88 and doesnt have PORTA. I also changed PORTB to PORTC.

In my hardware i use R/W always down to 0.

I also messed with the following defines:

// TURN ON POWER TO THE DISPLAY, NO CURSOR
#define   PWR_CMD   0x3F
// SET 2 LINE, 8 DATA BIT MODE      
#define   DL_CMD   0x0F
// CLEAR DISPLAY COMMAND      
#define CLR_DSP 0x01

Which based on what i understand from my datasheet they were not right... Well.. at this point i know nothing.... Grrr!!Nuno


DL_CMD should be set according to the number of lines on the display but, PWR_CMD is incorrect.

// TURN ON POWER TO THE DISPLAY, NO CURSOR 
#define   PWR_CMD   0x0C 
// SET 8 DATA BIT MODE        
#define   DL_CMD   0x30 
// CLEAR DISPLAY COMMAND        
#define CLR_DSP 0x01

sinosoidal wrote:

#define F_CPU 80000000


Shouldn't this be:

#define F_CPU 8000000

sinosoidal wrote:

#define LINE1 0x80
#define LINE2 0x80

Line 2 starting address is incorrect.

#define LINE1 0x80 
#define LINE2 0xC0 
void LCD_PutCmd (char c)
{
  PORTC &= ~(1<<LCD_RS);
  LCD_Delay (5); // Wait for the proper setup time to respond to the RS control line 
  LCD_PutChar(c);
  LCD_Delay (5); // Wait for the proper setup time to respond to the command being applied
  PORTC |= (1<<LCD_RS);
}

Try the following, as an experiment

void LCD_PutCmd (char c)
{
  PORTC &= ~(1<<LCD_RS);
  LCD_Delay (200); // Wait for the proper setup time to respond to the RS control line 
  LCD_PutChar(c);
  LCD_Delay (200); // Wait for the proper setup time to respond to the command being applied
  PORTC |= (1<<LCD_RS);
  LCD_Delay (200); 
}

Also try the following...

void LCD_PutChar (char c)
{
    PORTC |= (1<<LCD_E);
    LCD_Delay (5); // Wait for the proper setup time to respond to the E pulse   
    PORTD = c;
    LCD_Delay (5); // Wait for the proper setup time to respond to the character being applied
    PORTC &= ~(1<<LCD_E);
    LCD_Delay (5); // Wait for the proper setup time 
}

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

Nope... It didnt work!

I still have to unwire everything and make it again.

Explain me just one thing.

In my datasheet (ks0066 datasheet), in the initialization part (page 26) i have the following sequence:

1 - Power On
2 - Wait for more than 30 ms after rises to 4.5. (i'm using 5 volts directly on this pin, since 4.5 doesnt even light up the display)
3 - Function set (which define 1 ou 2 line mode and sets display on) is like this

000011NFXX where N can be 0 for 1 line mode and 1 for 2 line mode. And F=0 makes display off and 1 display one.

This is related with your PWR_CMD?

Thx,

Nuno

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

000011NFXX has 10 bit positions. You have 2 extra 00s in the front by accident?

Imagecraft compiler user

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

Yes, bob. He's probably reading right out of the data sheet where the first two columns are the RS and R/W signals. So the instruction proper is 0011NFXX.

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

Yes, i forgot to mention that!

Sorry!

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

I took off every connection and made all the wiring up again. Nothing different!

My module has the reference GDM1602A

The one page datahseet can be found here:

http://www.datasheetarchive.com/datasheet.php?article=1547161

Can you guys see here anything that helps?

:S

Thx for all the help you guys gave me until now.

This is getting sick for me! :(

Best regards,

Nuno

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

Its a timing thing. Does the mega88 have a clkdiv fuse to run it at 8mhz or 1mhz? You THINK it is running at 8, but seems like it should still work even if it is running at 1. Does the mega88 have JTAG? Is it on portc? Do you need to turn the jtag fuse off to get portc to work like an output port? Can you edit, compile, burn and run ANY other program using this avr and your compiler setup that shows ANY correct behavior on the cpu, like flash an led on and off once each second, and it really flashes once per second and not once per 8 seconds?

Imagecraft compiler user

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

bobgardner wrote:
Its a timing thing. Does the mega88 have a clkdiv fuse to run it at 8mhz or 1mhz? You THINK it is running at 8, but seems like it should still work even if it is running at 1.

Running at 1MHz is far more tollerable then running at 8MHz. You can have the display running with an 8MHz machine and drop down to 1MHz with any problems at all but, you can't have the display timing critically set to run with a 1MHz machine and jump up to 8MHz and expect the LCD display to operate correctly, without re-adjusting all of the appropriate timing.

bobgardner wrote:
Can you edit, compile, burn and run ANY other program using this avr...

Good point! Will it even program to simply flash an LED on & off?

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

Yes, i can compile and program right.

I tried the LED program and you guys are right. It's a timing thing.

I will need your help here.

I'm running the following program to do the led test:

#include 
#define F_CPU 1000000
#include 

void my_delay_ms(uint16_t delay_count) {
   uint16_t i;

   for (i=0; i

I'm using the divider to have a frequency clock of 1 Mhz and i was expecting the led to light 1 second and then stay 1 second turned off.

In portb 0 its blinking very fast. in the other B ports it doesnt blink.

If i take the divider the blinking of portb0 is even greater but it doesnt change, changing the delay... :S

I have tried this in both mega88 and mega168?

What is happening here?

Any clue?

Best regards,

Nuno

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

Hey guys,

I wont believe this....

The problem with the led test was that i was always progamming the chip with a hex file that was not related with that project, and with the lcd project as well....

I though that it was the problem since the begining.

Unfortunetly i wasnt. I have the same behaviour.

I even tried to clean the code again and past again Carl's code.

Well... I now have sure that i'm programming the right file.

I'm suspect to talk now! :S

Nuno

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

1. You will not get the result you expect with _delay_ms(1000) unless you run your AVR with a clock that is substantially lower than 1 MHz. You need to read up on the avr-libc documentation, and on _delay_ms(). There is a limitation on how long delays it can generate. I can't remember the limits of hand and I could look it up for you, but you might as well do it yourself.

2. When you say "take the divider" I assume you are referring to the CKDIV8 fuse. If you change the CKDIV8 fuse, but do not change the F_CPU defined constant then the blinking frequency will change, as _delay_ms() depends on this define.

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

Hey!

I finally have good news!

After all the problem was in flashing with the correct file!

Dahhhh

You could post a news with the title "The lamest freak!"

ehehehhe

With the rewiring i forgot to plug R/W to the ground.

The output i have in the lcd with carl's code is:

"vnso"

I believe this is related to the fact i have a 2x16 lcd module and the code is for a 4 line.

Need help to understand the display chaacter address codes

Thx a lot!

Best regards,

Nuno

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

I have been playing a little bit with the LCD and i have a thing to ask you, Carl:

   LCD_PutCmd (LINE1+5);
   LCD_PutString (BANNER_1);

Why do you have LINE1+5 in the PutCmd function?

The output i'm having right now is:

__________H_____
_nuF_gniva______

This is the BANNER "Having Fun".

I'm doing the initialization using my datasheet values:

#define PWR_CMD 0x3C
#define DL_CMD 0x0F

Thx,

Nuno

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

sinosoidal wrote:
I have been playing a little bit with the LCD and i have a thing to ask you, Carl:

   LCD_PutCmd (LINE1+5);
   LCD_PutString (BANNER_1);

Why do you have LINE1+5 in the PutCmd function?

The output i'm having right now is:

__________H_____
_nuF_gniva______

This is the BANNER "Having Fun".

I'm doing the initialization using my datasheet values:

#define PWR_CMD 0x3C
#define DL_CMD 0x0F

Thx,

Nuno

Because I use primarily a 4x20 display.

The very first character in LINE1 is defined as 0x80 - the left most display position on line 1. This will be the same for every common text based LCD module, no mater how many lines it has.

LINE2 is defined as 0xC0. This too is that same for every text based display I have ever used.

I have tested the exact same setup with a 2x16 character display and:
"Having"
"Fun"
is still displayed correctly on the smaller display but, shifted to the right by 5 character positions - without and code changes.

Just change the PutCmd() variable from:

LCD_PutCmd (LINE1+5);
LCD_PutString (BANNER_1);

to

LCD_PutCmd (LINE1);
LCD_PutString (BANNER_1);

sinosoidal wrote:
I'm doing the initialization using my datasheet values:

#define PWR_CMD 0x3C
#define DL_CMD 0x0F

I am currently at work and don't have a datasheet available so, I don't know what the different bit positions represent and can't presume how the display is being set up. What I do know is that, the PWR_CMD & DL_CMD that I posted are what I'm using.

Now, with the DL_CMD, if you are using a two line display and a blinking cursor and what ever the other options there are, that's not really an issue.

However, the PWR_CMD value could be an issue. I just don't have enough information to determine what your values actually mean at the moment. I'll look them up tonight, after I get home - about 0:30, Jan 07, 2007.

Edit:

One thing you can do is to print just one character, followed be a space characer, such as
"H " on only one line - over and over. See what happens.

Then print:
"Ha " over and over.

Provide some detailed feedback as to the exact text position from each test. This might lead to clues as to whether its a command timing issue ot a character printing issue.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

There is an 'entry mode' command that lets you select whether to shift the cursor or the display, and if you shift the display, whether it shifts left or right. If you want it to act like a crt, the cursor should shift, not the display, and it should increment (move to the right) unless you want it to print arabic, which goes to the left.

Imagecraft compiler user

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

I follow Carl's advice to write only one caracter at line 0x80 and it was sucessefully drawn.

But with this issue i can say that i really dont understand datasheets!!

In the small datasheet of my LCD module the start address is 0x00 for the first line and 0x40 for the second! :S

Can somebody explain me why? And... how can i trust a datasheet if she tells me something that is wrong?

Another thing i realized with the experiment is that i need to LCD_PutCmd(LINE+numberOfCharacteresToBeWritten) to have a string written.

My entry mode i defined it as increment mode and entire shift off (what is this one related with?).

Another problem is that i can write a string in the first line and in the second.

But if try to write booth it doesnt work:

#define LINE1 0x80
#define LINE2 0xC0

const char BANNER_1[] = {"Control: 100"};
const char BANNER_2[] = {"Value: 127"};

LCD_PutCmd (LINE1+strlen(BANNER_1));
LCD_PutString (BANNER_1);
LCD_PutCmd (LINE2+strlen(BANNER_2));
LCD_PutString (BANNER_2);

The result is each case separetly is correct. The result of both lines instructions is 00 in the first line....

Any tips?

Thx

Nuno

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

sinosoidal wrote:
I follow Carl's advice to write only one caracter at line 0x80 and it was sucessefully drawn.

But with this issue i can say that i really dont understand datasheets!!

In the small datasheet of my LCD module the start address is 0x00 for the first line and 0x40 for the second!

But by the datasheet that you provided, DB7 must be set to gain access to the address counter. There are 7 data bit address lines, DB6:DB0. The 8th data bit, DB7, is used to select between CGRAM and DDRAM. When CGRAM, DB7, is set to logic 0, the address counter of the custom characters is being selected. When DDRAM, DB7 is set to logic 1, DDRAM the DDRAM address counter is being use to select the internal character generator. CGRAM is used to select the memory store where "Custom Built" characters are stored. DDRAM is the character generator that the display uses to display its "Built-In" character set.

If DB6:DB0 (127 possible characters) are used as the CGRAM OR DDRAM address counter and the first character position on line 1 is 0x00 then the data to select that position using the default display characters must be 0x80 because, DB7 must be set to logic 1 to enable the default character generator set.

So, if line 1 starts at 0x00 then, line 1 position 0 becomes:

 0x00
+0x80
------
 0x80

That is why 0x80 is used for line1:position 0.

And, if line 1 starts at 0x40 then line 2 position 0 becomes:

 0x40
+0x80
------
 0xC0

That is why 0xC0 is used for line2:position 0.

By the datasheet you provided.

Attachment(s): 

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

sinosoidal wrote:
Another thing i realized with the experiment is that i need to LCD_PutCmd(LINE+numberOfCharacteresToBeWritten) to have a string written.

My entry mode i defined it as increment mode and entire shift off (what is this one related with?).

Another problem is that i can write a string in the first line and in the second.

But if try to write booth it doesnt work:

#define LINE1 0x80
#define LINE2 0xC0

const char BANNER_1[] = {"Control: 100"};
const char BANNER_2[] = {"Value: 127"};

LCD_PutCmd (LINE1+strlen(BANNER_1));
LCD_PutString (BANNER_1);
LCD_PutCmd (LINE2+strlen(BANNER_2));
LCD_PutString (BANNER_2);

Nuno

No! It is:

LCD_PutCmd (LINE1 + Offset);
LCD_PutString (BANNER_1);
LCD_PutCmd (LINE2 + Offset);
LCD_PutString (BANNER_2);

String length is determined by the fact that the character strings are inherently NULL terminated by the compiler when they are assigned to the array when it was defined - at least in ImageCraft ICCAVR they are.

The format for

LCD_PutCmd (LINE1 + 3);

is:

LCD_PutCmd (StartinPosition + Offset);

IT IS NOT

LCD_PutCmd (StartingPosition + CharacterCount);

If this is the case, you have either changed my LCD_PutCmd (); function or, your compiler doesn't handle string terminations to the C standard.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

Ok. Definitly. I don't know how to read datasheets!

Well. Its seems all clear now!

About that other issue about strlen. It isnt having that behaviour. Now that i got back to this it was not working.

The first thing i tried was to take off that +strlen and put a 0 offset.

Its working perfectly.

Maybe something like the entry set was not defined yet and after the long power out it was now initialized with that.

I just got to thank you all for the incredible patient!

Thx!!!

Best regards,

Nuno

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

Hi again,

I'm trying to adapt carl's code to use only port. In this case, only PORTD.

I have the pins 0,1,2 and 3 connected to DB4,DB5,DB6 and DB7.

The pins 4, 5 and 6 are connected to RS,RW and E.

The code i'm using is the following. I'm just trying to initialize for now. Maybe my problem is the bit operations. I'm still very confused about it.

The actual behaviour is the first line filled with black squares and the cursor blinking at the third square. If i program it again, the blinking cursor jumps one time to the right.

#define F_CPU 1000000
#include 
#include 

// Define LCD Register Select as PORTD, 0x10;
#define LCD_RS 4
// Define LCD Read/Write as PORTD, 0x20; 
#define LCD_RW 5
// Define LCD Enable as PORTD, 0x40; 
#define LCD_E 6 

// DISPLAY ON, 2 LINE MODE
#define   PWR_CMD1   0x20
#define   PWR_CMD2   0x20
#define   PWR_CMD3   0xC0

// DISPLAY ON, CURSOR ON, BLINK ON
#define   DL_CMD1   0x00
#define   DL_CMD2   0xF0

// CLEAR DISPLAY COMMAND      
#define CLR_DSP1 0x00
#define CLR_DSP2 0x10

// ENTRY MODE SET
#define ENT_MOD1 0x00
#define ENT_MOD2 0x60

#define LINE1 0x80
#define LINE2 0xC0

#define NULL 0x00

const char BANNER_1[] = {"Control: 100"};
const char BANNER_2[] = {"Value: 127"};

void LCD_Delay (unsigned long int d);
void LCD_IO_INIT (void);
void LCD_INIT (void);
void LCD_PutCmd (char);
void LCD_PutChar (char);
void LCD_PutString (const char *);

void main (void) {
	DDRB = 0xFF;
	PORTB = 0xFF;

	LCD_IO_INIT ();
	LCD_INIT ();

	/*
	LCD_PutCmd (LINE1);
	LCD_PutString (result);
	LCD_PutCmd (LINE2);
	LCD_PutString (BANNER_2);
	*/
}

void LCD_Delay (unsigned long int d) {
    unsigned long int n;
    for (n = 0; n < d; n++);
}

void LCD_IO_INIT (void) {
    DDRD = 0xFF; // PORTD is the LCD DATA AND CONTROL LINES
    PORTD = 0x00;
    PORTD |= (1<<LCD_RS);
	PORTD |= (1<<LCD_E);
	LCD_Delay (500); // Wait for the up LCD to power up         
}

void LCD_INIT (void) {
	LCD_PutCmd (PWR_CMD1);
	LCD_PutCmd (PWR_CMD2);
	LCD_PutCmd (PWR_CMD3);

	_delay_us(40);
	
	LCD_PutCmd (DL_CMD1);
	LCD_PutCmd (DL_CMD2);

	_delay_us(40);
	
	LCD_PutCmd (CLR_DSP1);
	LCD_PutCmd (CLR_DSP2);

	_delay_ms(2);

	LCD_PutCmd (ENT_MOD1);
	LCD_PutCmd (ENT_MOD2);

    LCD_Delay (500); // Wait for the LCD to boot up   
}
 
void LCD_PutCmd (char c) {
  PORTD &= ~(1<<LCD_RS);
  LCD_Delay (5); // Wait for the proper setup time to respond to the RS control line 
  LCD_PutChar(c);
  LCD_Delay (5); // Wait for the proper setup time to respond to the command being applied
  PORTD |= (1<<LCD_RS);
}

void LCD_PutChar (char c) {
    PORTD |= (1<<LCD_E);
    LCD_Delay (5); // Wait for the proper setup time to respond to the E pulse   
    PORTD = c;
    LCD_Delay (5); // Wait for the proper setup time to respond to the character being applied
    PORTD &= ~(1<<LCD_E);
}
 
void LCD_PutString (const char *p) {
    char n = NULL; // Pointer position counter.
    while (p[n] != NULL) // Keep sending data until the NULL character is found.
         LCD_PutChar(p[n++]);
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Back to 4 bit mode... we went thru this a couple days ago.... the putchar routine that used to put all 8 bits now is two subroutines.. put hi nib of c out on the hi bits, and another sub to put lo nib of c out on the hi bits... involves anding c with 0f and f0 and shifting.... I dont see that you've added that part to Carl's 8 bit program, so need to go look for a 4 bit example to port over....

Imagecraft compiler user

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

bobgardner wrote:
Back to 4 bit mode... we went thru this a couple days ago.... the putchar routine that used to put all 8 bits now is two subroutines.. put hi nib of c out on the hi bits, and another sub to put lo nib of c out on the hi bits... involves anding c with 0f and f0 and shifting.... I dont see that you've added that part to Carl's 8 bit program, so need to go look for a 4 bit example to port over....

Ohh.... ok... But the initialization is not being done correctly. Before write anything to the module i need a correct initialization.

Can you see anything wrong beside that?

Thx

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

One or several of the first instructions you send to the display is not correct.

When the display powers up it is in 8-bit mode.

So the display wants to se all instructions up to, and including, the one that sets it in 4-bit mode as 8-bit instructions. (Your code sends all instructions as 8-bit instructions, by sending them as two consecutive nibbles. That will not work).

How is this possible in 4-bit mode?, you ask. Well, as the low nibble of these instructions are "don't care" then what you need is to send only the high nible of these instructions - the low nibble of the LCD is unconnected (or maybe tied to ground) and will be read by the display as zeroes).

So you need to follow the sequence below (and I am following the official init sequence, as documented in Hitachis 44780 data sheet - it might be that Carls code does not follow that sequence to the letter):

1. Wait at least 15 ms
2. Send the high nibble of a Function Set instruction
3. Wait at least 4.1 ms
4. Send the high nibble of a Function Set instruction
5. Wait at least 0.1 ms (100 us)
6. Send the high nibble of a Function Set instruction
7. Send the high nibble of a Function Set instruction for 4-bit interface
It is at his point the 4-bit interface becomes interactive. From now on you send complete 8-bit instructions as twop consecutive nibbles, high nibble first.
8. Send a Function Set instruction, 4-bit interface, and N and F bits set to your liking.
9. Send a Display Off
10. Send a Display Clear instruction
11. Send a Entry Mode Set instruction
And then finally
12. Send a Display On instruction

The document that I am referencing is in this thread: https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=116409#116409, in the file 99rtd006d2.zip, which contains a PDF by the same name. The 4-bit init sequence is on p 46.

Also, as a "preview" I attach a small test program for 4-bit interface and the avr-gcc compiler. It was not my intention to let this out in public just yet as it is intended for a LCD tutorial I am working on, but it might help you move forward. You may use it on the condition that you supply me with any feedback on it that you have. Really! I mean it - you get it in return for being my giunea-pig. If you don't try it out at all I would like to know that too. I have tried it on a ATmega88 and it worked flawlessly for me. I think you will find that the comments in the code should clarify what you will need to change for it to fit your connection of the display. Only one thing that might be akward: You have to have the 4 data bits (DB4..DB7) on the 4 high pins of a port, but I don't think that this will be a problem. If you really need them on the low bits of a port then I can hlp you with this in the week-end. You will also find that all instruction names and signals are in close resemblace with their names in the data sheet I am referring to.

Also, please note that I in no way am saying that Carls code is not working. On the contrary, I am quite sure that it is. View my code merely as as an alternative test.

Hope this helps!

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]

Last Edited: Tue. Sep 25, 2007 - 09:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

It works perfectly. I gave a light look across all the code and i have some doubts that i would like to put you.

Not now because i need to sleep. But tomorow! If you are available to answer them, of course! :)

Thx,

Nuno

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

JohanEkdahl wrote:
...it might be that Carls code does not follow that sequence to the letter):

This might, in fact, be the case! Although, it will be very close.

I have since done a lot more work on my LCD project, though, it doesn't apply to a tutorial and, it also dosen't use 4 bit mode anymore but, rather; it is for a project that is required to write data to the LCD text based display at a serial communications rate of 115.2K BAUD.

I seriously doubt that a standard text based LCD display can reliably deal with processing and displaying data at 115.2K BAUD using 4 bit mode.

This project has been a real trip - especially getting it to work reliably on about 10 different manufacturers at 115.2K BAUD. But be advised, my current project was inspired by this thread and this thread caused me to get off of my lazy AS.. and, finally get through it. Thanks!

Oh! This is one project that I plan to deposit into the "Projects" forum.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

Nice! :)

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

Quote:

i have some doubts that i would like to put you. Not now because i need to sleep. But tomorow!

You are most welcome.

Quote:

If you are available to answer them, of course!

There is a high probablility that I will spend much of the weekend in front of my computer (as if I didn't do that all week...), and I will be focusing on LCD issues. Yes, it is about the Tutorial, and I wantyour feedback, which very well could be in form of questions or doubts. Bring it on!

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

Hi,
I also have some issues with LCD's. I use several (4 bit mode) with the cvavr library. In general all works well but sometimes the LCDs do not reset correctly.
I assume that one can repeat the init sequence anytime to get clean conditions but I have some doubts about it now. On several occasions the LCD seems to hang (must be revived by interrupting the Vcc) if the init is applied after doing some output.
BTW in 4 bit mode do you ground the D0..D3 pins on the LCD and use pull-ups for the others?

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

Fried wrote:
BTW in 4 bit mode do you ground the D0..D3 pins on the LCD and use pull-ups for the others?

That's what my Optrex datasheet says.

But you do not need "Pull-Up" resistors on the active DB7:DB4 nibble.

Attachment(s): 

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston

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

On Jan 12, 2007

sinosoidal wrote:

I gave a light look across all the code and i have some doubts that i would like to put you.
Not now because i need to sleep. But tomorow!

It's the day after "tomorrow". I'm just about to start another writing pass. It would be nice if you could post what your "doubts" where so I can take them into consideration. Please...

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

Hi all,

I am using very simple C code program with standard lcd.c and lcd.h libraries for managing 16x1 LCD with KS0066 driver. Trouble is that on LCD is visible only
first half of characters and second half is empty.
I assume that program is working properly (first 8 characters is always visible). In lcd.h is setting only for D44780 and KS0073 controllers. I think that trouble is maybe in internal KS0066 addressing???
Do you know this type of LCD trouble? Can you help me? Thank you. Tomas :(

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

WE had the same problem in another recent thread. There are 16x1 LCDs that actually function as two-line displays. The first eight characters are on line 1, and the last eight characters are on line two. Try to set your display to two lines and see if that helps. Please note that the addressing is not linear, but rather like this (hex): 00, 01, ... 07, 41, 42, ... 47.

The recent thread with similar topic is here: https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=280670&highlight=#280670.

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

Thank you JohanEkdahl, your code was very helpful. I really like the way you commented your functions. It was very easy to understand.

One question, why did you use the volatile qualifier before the while loop?

volatile int i = 0;
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl,

In your code you state

Quote:
/*
* This holds as long as you have the four data signals
* connected to the upper 4-bit nibble of the AVR port,
* and you run at a maximum frequency of 8 MHz.
*/

What changes if you are running at 16 MHz?

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

Quote:

What changes if you are running at 16 MHz?

Without looking at the code again, I think you'd have to look at two things:

1) The short timing constraints that is required while sending one byte/nibble. Eg the "data steady time" before E drops. For up to 4 MHz you cant break this constraint even in hand-optimized assembly (IIRC, I actually have the same program in assembler with timing comments but I'm at work now). You might have to insert short "time-wasters"/NOPs.

2) The longer delays are done with delay_ms/delau_us. When the clock is frequency is raised the maximum time that these routines can delay falls. See the avr-libc documentation for the nitty-gritty...

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:

why did you use the volatile qualifier before the while loop?

Oppps. Must have copied/pasted some code. The volatile qualifier is not needed.

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

Hello,newbie here,

When I build avr-gcc4bit.c in Studio4 14.489...
I get a ../LCDJohann.c:10:24: util/delay.h: No such file or directory.

I tried building it for an atmega 88 and 128, just to see if one of them had that library or not....util/delay.h something I have to install or should it be part of the library already?

thanks in advance!!!

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

You should really start a new topic instead of posting your question at the end of a 1 year old 4 page thread.

util/delay.h is part of WinAVR.

David.

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

hmm, i don't understand why the "build" process doesn't find the util/delay.h file .....i guess I need to look into what files are in MY WinAvr library, bad installation if missing?

I'll start a new thread if this gets's any more involved.

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

In case you missed it, the CodeVisionAVR C compiler comes with library function to support your LCD Char. display. I think they offer limited student or eval version and the full price is only a few hundred dollars so maybe you might consider buying that compiler then you could move on with your project.

Al Welch

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

THANK YOU. After hours of tearing my hair out after never using LCD's before, i finally got my 2x20 lcd working correctly and have a bit of a better understanding of how the commands are sent after examining your code, very helpful. :)

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

So, what did you end up with? Did you solve the avr-libc issue with util/delay.h? If so, what was it? Or did you take the CodeVision AVR approach?

Can I rub my ego with another running instance of my demo code? :wink:

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

Johan,your code looks very nice; even an illiterate like me can follow it without a problem. It was just the right thing I needed to get a grip on LCD control.

But... I'm sure the code is right but my display just pulls out a pixel version of a Jackson Pollock art piece and goes blank in a second.It didn't came with instructions so I probably have some of the wiring wrong.

Thanks for sharing it and I'll let you know if I can make the display work later.

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

Oh... I figured out the pins of the display!, but it displays a full line of block characters on the first line. Two blinks on start up and then the first line just stays full on.

Any idea what is that all about?

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

So I reckon this first line filled with black blocks means that there was an intialization error, right?

I put a delay before the initialization, in case the power wasn't kicking in fast enough. Still doesn't work.
I doubled the delays on the different functions in case they where too short. Nope
I changed the MCU frequency to 4MHz and still doesn't work.

I'm sure the wiring is right now, so I'm clueless about why it doesn't work.

Perhaps I should try with an external, crystal oscillator instead of the internal one?

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

Superfreak code of JohanEkdahl worked like a charm !!!
thank you *very* much ...

"same" code that worked ok in assembler was driving me fool with C and i was losing my religion dealing with the hundreds of libraries available here and there but i wasn't able to get a single pixel on :-(

Thank you again for sharing.

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

JohanEkdahl wrote:

1. Wait at least 15 ms
2. Send the high nibble of a Function Set instruction
3. Wait at least 4.1 ms
4. Send the high nibble of a Function Set instruction
5. Wait at least 0.1 ms (100 us)
6. Send the high nibble of a Function Set instruction
7. Send the high nibble of a Function Set instruction for 4-bit interface
It is at his point the 4-bit interface becomes interactive. From now on you send complete 8-bit instructions as twop consecutive nibbles, high nibble first.
8. Send a Function Set instruction, 4-bit interface, and N and F bits set to your liking.
9. Send a Display Off
10. Send a Display Clear instruction
11. Send a Entry Mode Set instruction
And then finally
12. Send a Display On instruction

This sequence was wrong.
Every command need at least the minimal wait time (37µs) after it, so waiting 100µs was fine.
So you must insert 100µs delay after step 6 and 7.

Nevertheless your code works, because your LcdSendNibble command contain 5ms delay, which was a big waste of CPU time. :(

Peter

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

Thank you, Peter.

Yes, I should have made it clear that apart from the (special) delays explicitly mentioned in that sequence the "standard" timing requirements from the data sheet always apply.

It is my belief that after step 6 above the display interface is in "normal operation mode" so the usual timing requirements from the data sheet apply. Could have made that clearer also.

Re the 5 ms: The purpose of my small program has never been to be a real application. (For that, one is better off using e.g. your LCD code.)

The purpose has all the time been to introduce a minimal test - e.g. to prove that the hardware wiring is correct, the contrast control is set correctly etc. For that purpose code like the one from Procyon, Fleury, or your LCD code, can actually be troublesome for an LCD noob. Being clueless they have more code than necessary to mess around with, ultimately onfusing them even more. Then they either give up or come here displaying a total mess - and we then have to start them over from square one. While the minimal test code was evolving I have some time tossed in that 5 ms delay to be well on the safe side - not pretty perhaps, but will not do any harm for the purposes the code has. If all you're doing is testing "Hello LCD!" on your 44780-based module then you're wasting a lot of CPU time any way.. :wink:

Never advocated using my minimal test code for a real app - I try to always recommend going with something already written and proved. E.g. your code.

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:
It is my belief that after step 6 above the display interface is in "normal operation mode" so the usual timing requirements from the data sheet apply. Could have made that clearer also.
It is my belief that the data sheet flowchart is ambiguous about the BF at this point. For that particular instruction the information to the right says: "BF cannot be checked before this instruction." For the next instruction the information to the right says: "BF can be checked after the following instructions". There is no information given about the use of the BF between those two instructions. As Danni says "Every command need at least the minimal wait time (37µs) after it, so waiting 100µs was fine." I too use 100us since that is what was specified for the previous instruction.

Don

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

My BFF and her BF had a short delay before checking the BF, but I had no BeeF with that.

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

Yes, Don. I agree with that. So, instead of relying on the BF at that point I assume that the timings for the execution of the instruction as given in the data sheet should be used. (Going on memory here - it's been a while since I dabbled with CLCDs on this level).

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:
I assume that the timings for the execution of the instruction as given in the data sheet should be used.
I didn't choose that approach because even though this 'looks like' a Function set instruction it really isn't one. There's really no sense skimping on a delay that is only going to be used once.

Don

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

I use a 50usec delay per byte. No delay between hi nib and lo nib.

Imagecraft compiler user

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

Quote:
I use a 50usec delay per byte. No delay between hi nib and lo nib.
That's fine for most (but not all) of the instructions after you have finished the first few steps in the initialization sequence.

In this case we are talking about the reset portion of the initialization sequence. Here all of the specified delays are significantly longer than 50 uSec and the mode is always 8-bit so there are no nibbles to consider.

Don