LCD module and AVR

Last post
91 posts / 0 new

Pages

  • 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: http://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): 

"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]

  • 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!

"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]

  • 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...

"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]

  • 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: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=280670&highlight=#280670.

"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]

  • 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...

"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]

  • 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.

"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]

  • 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:

"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]

  • 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.

"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]

  • 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.

  • 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).

"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]

  • 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

Pages