EmbeddedRelated.com
Forums

What is wrong with this LCD code?

Started by Unknown September 17, 2006
Everett M. Greene wrote:
> "Mike Silva" <snarflemike@yahoo.com> writes:
> > Why do we still have to put up > > with display interfaces that are '70s-slow anyway? > > There wouldn't be any functional improvement if it were. > LCDs have a rather slow response and the humans reading > the display are only slightly faster. You could make > the interface easier to program, but you'd probably > have to have a delay somewhere to slow the screen update > rate.
Yes, it's that 40us per character interface that I'd like to see fixed. Too much time to wait around between characters, too little time to do much of anything else. Just in this thread we have seen the lengths that people have gone to to accommodate the display interface -- 500us interrupts and serial loop-backs with the baud rate setting the timing. These are clever solutions, but they are workarounds for a really clumsy interface.
Mike Silva wrote:
> Yes, it's that 40us per character interface that I'd like to see fixed. > Too much time to wait around between characters, too little time to do > much of anything else. Just in this thread we have seen the lengths > that people have gone to to accommodate the display interface -- 500us > interrupts and serial loop-backs with the baud rate setting the timing. > These are clever solutions, but they are workarounds for a really > clumsy interface.
I'm not so sure about that, outputing 1 character on a timer interrupt from a shadow buffer would seem to be the sensible way even if it was much faster.
cbarn24050@aol.com wrote:
> Mike Silva wrote: > > Yes, it's that 40us per character interface that I'd like to see fixed. > > Too much time to wait around between characters, too little time to do > > much of anything else. Just in this thread we have seen the lengths > > that people have gone to to accommodate the display interface -- 500us > > interrupts and serial loop-backs with the baud rate setting the timing. > > These are clever solutions, but they are workarounds for a really > > clumsy interface. > > I'm not so sure about that, outputing 1 character on a timer interrupt > from a shadow buffer would seem to be the sensible way even if it was > much faster.
The problem then is that you have to deal with e.g. 40 interrupts to update a display. How much more sensible to go into a tight loop and dump those 40 characters all at once. But at 40us per character (up to 60us at temperature extremes), not every program can or wants to throw away 1600us updating the display (multiple times a second, if it's displaying real-time data). That could be many tens of thousands of CPU cycles, just to write 40 characters. Hence the tricks like timer interrupts and serial loop-backs. It's not the end of the world, but dang!
Mike Silva wrote:
> > The problem then is that you have to deal with e.g. 40 interrupts to > update a display. How much more sensible to go into a tight loop and > dump those 40 characters all at once. But at 40us per character (up to > 60us at temperature extremes), not every program can or wants to throw > away 1600us updating the display (multiple times a second, if it's > displaying real-time data). That could be many tens of thousands of > CPU cycles, just to write 40 characters. Hence the tricks like timer > interrupts and serial loop-backs. It's not the end of the world, but > dang!
On the contrary, you dont have to deal with or wait for anything. Your main program writes to the buffer and forgets all about it, gets on with its own thing. The timer interrupt updates the display "in the background" so to speak.
cbarn24050@aol.com wrote:
> Mike Silva wrote: > > > > The problem then is that you have to deal with e.g. 40 interrupts to > > update a display. How much more sensible to go into a tight loop and > > dump those 40 characters all at once. But at 40us per character (up to > > 60us at temperature extremes), not every program can or wants to throw > > away 1600us updating the display (multiple times a second, if it's > > displaying real-time data). That could be many tens of thousands of > > CPU cycles, just to write 40 characters. Hence the tricks like timer > > interrupts and serial loop-backs. It's not the end of the world, but > > dang! > > On the contrary, you dont have to deal with or wait for anything. Your > main program writes to the buffer and forgets all about it, gets on > with its own thing. The timer interrupt updates the display "in the > background" so to speak.
I understand, but then you have to have a suitable interrupt. And you have to write more code that tells the interrupt routine when to start a new update, and more code that keeps track of the next character to output. As I keep saying, it's not the end of the world, but it's more hassle than it needs to be. It certainly is not an optimum solution. Look at it this way. If you had your choice of a display that could accept a character every 400ns or a character every 40us, which would you choose?
Mike Silva wrote:
> I understand, but then you have to have a suitable interrupt.
True, but every processor has a timer (I think). And you
> have to write more code that tells the interrupt routine when to start > a new update,
It updates continuosly, and more code that keeps track of the next character to
> output.
Ok you need a static pointer As I keep saying, it's not the end of the world, but it's more
> hassle than it needs to be. It certainly is not an optimum solution.
There isn't a better one I know of, especially if you want to edit your display.
> > Look at it this way. If you had your choice of a display that could > accept a character every 400ns or a character every 40us, which would > you choose?
Well if there was no price difference the faster one.
Sending each command to LCD need to delay for a while depending on your
hardware, 2 ms usual.

My also succeed 4-bit interfacing 16x2 character LCD with 8051 (P89V51)
using SDCC as compiler. By applying this software timing function
(XTAL=18.432 MHz)

void LCD_delay(unsigned char ms)
{
	unsigned char n;
	unsigned int i;
	for (n=0; n<ms; n++)
	{
		for (i=0; i<LCD_DELAY; i++); /* For 1 ms */
	}

}


-----------------------------
Wira Kasem
http://mcu-programming.blogspot.com

"mcu.programmer@gmail.com" <mcu.programmer@gmail.com> writes:
> Sending each command to LCD need to delay for a while depending on your > hardware, 2 ms usual. > > My also succeed 4-bit interfacing 16x2 character LCD with 8051 (P89V51) > using SDCC as compiler. By applying this software timing function > (XTAL=18.432 MHz) > > void LCD_delay(unsigned char ms) > { > unsigned char n; > unsigned int i; > for (n=0; n<ms; n++) > { > for (i=0; i<LCD_DELAY; i++); /* For 1 ms */ > } > > }
After the LCD is initialized, why not use the busy status?
Everett M. Greene wrote:
> "mcu.programmer@gmail.com" <mcu.programmer@gmail.com> writes: > > Sending each command to LCD need to delay for a while depending on your > > hardware, 2 ms usual. > > > > My also succeed 4-bit interfacing 16x2 character LCD with 8051 (P89V51) > > using SDCC as compiler. By applying this software timing function > > (XTAL=18.432 MHz) > > > > void LCD_delay(unsigned char ms) > > { > > unsigned char n; > > unsigned int i; > > for (n=0; n<ms; n++) > > { > > for (i=0; i<LCD_DELAY; i++); /* For 1 ms */ > > } > > > > } > > After the LCD is initialized, why not use the busy status?
Because that would take away its staus as bieng the worst possible way.
Mad,

I recently implemented a similar project. First thing I would say is
get a data sheet on the device and look at your delays, you have what
looks like a delay of 1uS when the device needs delays in the order of
several mS! Anyway below is some of my init code for philips LPC which
might help you. Good luck.

	IODIR |= PIN_IO_LCD_DATA;							// Set all data pins as outputs
	IODIR |= PIN_OUT_LCD_CTRL;							// Set all control pins as outputs
	IOCLR = PIN_OUT_LCD_CTRL;							// Bring all control lines low
	lcd_write (0x38);                    				// Select 8-bit interface
	delay (100000);
	lcd_write (0x38);
	delay (10000);
	lcd_write (0x38);

	lcd_write (0x38);                    				// 2 lines, 5x8 character
matrix
	lcd_wr_cmd (0x0e);                   				// Display
ctrl:Disp/Curs/Blnk=ON
	lcd_wr_cmd (0x06);                   				// Entry mode: Move right, no
shift
	LCD_load ((U8 *)&UserFont, sizeof (UserFont));
	LCD_cls();


Mad I.D. wrote:
> I have 16x4 HD44780 base LCD module. > 2 days ago I wrote the code and it worked but I wasn't pleased with it so i > deleted it and started writing new one. > And for the lase 2 days it won't work :((( I lost 5-6 hours already on > this. > I can't even get LCD to initialize and turn cursor and blinking ON. > > Can you people find something wrong in this init code? > MCU is LPC22129 with ARM7 running at 60MHz > > void LCDInit(void) > { > IODIR0=0x7F00; > IOCLR0=0x7F00; > IOSET0=0x0200; > LCDtoggle(); > IOCLR0=0x7F00; > IOSET0=0x0800; > LCDtoggle(); > > IOCLR0=0x7F00; > LCDtoggle(); > IOSET0=0x0F00; > LCDtoggle(); > } > > void LCDtoggle(void) > { > IOSET0=ENABLE; > delayus(1); //wait for 1 microsec > IOCLR0=ENABLE; > }