LPC and LCD problem

Hi futz,

yeah I have a 1k resistor, and when I run the code I can see some random caracters with a blinking cursor.

some caracters go off others change, and the cursor moves continuously .

yep I’m closer than I was this morning, thank you very much !!!

now I have to find why it displays random caracters rather than my favorite quote “LPC2468 LCD It Works !” :`(

zack

the display takes few seconds before clearing and starting firing random characters …

zanak:
yeah I have a 1k resistor, and when I run the code I can see some random caracters with a blinking cursor.

some caracters go off others change, and the cursor moves continuously.

Aha! Then you are VERY close. Find that last little detail and you're in business. Did you try single stepping through the init and the first letter or two? Just do a run-to the beginning of the init and then step-over each line. Takes too long to step-into everything, but if you have to then do that too. Just step-over the delays or you'll be there till next year and wear out that key on your keyboard. :grin:

zanak:
the display takes few seconds before clearing and starting firing random characters …

Well... there's the half second settling time delay. If you're running at 12MHz that will become (.5 times 5 =) 2.5 seconds. At 60MHz it's very quick.

EDIT: Just noticed you also have this before the init() routine:

for (j = 0; j < 200000; j++);

That’s not necessary. The init() routine has more than enough settle time delay.

There are also 1 second delays in the display loop, which will become 5 second delays at 12MHz.

This is why I use busy checking whenever possible. So much faster and easier!

futz:

zanak:
the display takes few seconds before clearing and starting firing random characters …

Well... there's the half second settling time delay. If you're running at 12MHz that will become (.5 times 5 =) 2.5 seconds. At 60MHz it's very quick.

EDIT: Just noticed you also have this before the init() routine:

for (j = 0; j < 200000; j++);

That’s not necessary. The init() routine has more than enough settle time delay.

There are also 1 second delays in the display loop, which will become 5 second delays at 12MHz.

This is why I use busy checking whenever possible. So much faster and easier!

I was thinking to use BF, since I have problems with delays … and I gonna use your code (again).

tomorow I’ll port it to my LPC2468 and tell you if it works. but I have some doubts about the FIOCLR problem.

thanks a lot my friend.

Zack

zanak:
but I have some doubts about the FIOCLR problem.

Here's what mine looks like. Works fine.
void lcd_nybble(unsigned char nyb,unsigned char rs)
{
    int i,dat;
    if(rs)
        FIO0SET |= RS;            //set RS pin
    else
        FIO0CLR |= RS;            //clear RS pin
    dat = nyb;                    //get the nybble in an int
    FIO0CLR = 0x001e0000;	      //clear D4-D7
    FIO0PIN |= dat<<17;           //OR the bits in there
    strobe_e();                   //latch data to LCD
}

One thing, is that you need to do is to stop using the |= operator with the FIO0SET and FIO0CLR registers. These registers are write only, so the or is not required (and not desired), and in many cases, it can actually cause problems.

This problem is regularly mentioned on the LPC2000 yahoo group, and has been shown to cause behaviour that is unexpected.

Mike

manton:
One thing, is that you need to do is to stop using the |= operator with the FIO0SET and FIO0CLR registers. These registers are write only, so the or is not required (and not desired), and in many cases, it can actually cause problems.

This problem is regularly mentioned on the LPC2000 yahoo group, and has been shown to cause behaviour that is unexpected.

Oh ya! Good point! I never thought of that. Now I gotta go fix all my code. :D Luckily it all works good, so I haven't yet been bit by the unexpected behaviour thing.

manton:
One thing, is that you need to do is to stop using the |= operator with the FIO0SET and FIO0CLR registers. These registers are write only, so the or is not required (and not desired), and in many cases, it can actually cause problems.

This problem is regularly mentioned on the LPC2000 yahoo group, and has been shown to cause behaviour that is unexpected.

Mike

yeah exact ! I changed all the OR operation, and now it works fine in simulation, but I still having the same problem, and even the random characters are no longer displayed !!

zanak:
I changed all the OR operation, and now it works fine in simulation, but I still having the same problem, and even the random characters are no longer displayed !!

Here is working delay code for 20x4 with the FIO0SET/FIO0CLR thing fixed:
#include "LPC214x.h"
#include "lcd4bit.h"
#include <stdio.h>

char row[]="                    ";

int main(void)
{
    SCS = 0x00000001;               //enable fast gpio
	clkinit();
	PINSEL0 = 0x00000000;
	FIO0DIR = 0x107e0000;
	FIO0CLR = 0x107e0000;
	lcd_init();
	while(1){
		lcd_line1();
		sprintf(row,"bleh",0);
		lcd_string("LPC2148 LCD");
		delay_ms(1000);
		lcd_line2();
		lcd_string("It works!");
		lcd_line3();
		lcd_string("Line 3 here.");
		lcd_line4();
		lcd_string("Here is line 4!");
		delay_ms(1000);
	}
}	

void lcd_string(char *senpoint)
{
	while(*senpoint != '\0')
	{
		lcd_char(*senpoint);
		senpoint++;
	}
}	

void lcd_line1(void)
{
	lcd_cmd(0x80);
}

void lcd_line2(void)
{
	lcd_cmd(0xc0);
}		

void lcd_line3(void)
{
    lcd_cmd(0x94);
}       

void lcd_line4(void)
{
    lcd_cmd(0xd4);
}       

void lcd_cmd(unsigned char letter)
{
	unsigned char temp;
	temp=letter;
	temp=temp>>4;
	lcd_nybble(temp,0);
	temp=letter;
	temp=temp&0x0f;
	lcd_nybble(temp,0);
}

void lcd_char(unsigned char letter)
{
	unsigned char temp;
	temp=letter;
	temp=temp>>4;
	lcd_nybble(temp,1);
	temp=letter;
	temp=temp&0x0f;
	lcd_nybble(temp,1);
}

void lcd_nybble(unsigned char nyb,unsigned char rs)
{
	int i,dat;
	if(rs)
		FIO0SET = RS;				//set RS pin
	else
		FIO0CLR = RS;				//clear RS pin
	dat = nyb;						//get the nybble in an int
	FIO0CLR = 0x001e0000;			//clear D4-D7
	FIO0PIN |= dat<<17;				//OR the bits in there
	strobe_e();						//latch data to LCD
}

void lcd_init(void)
{
	delay_ms(500);					//settle time delay
	lcd_nybble(0x03,0);				//reset LCD
	delay_ms(5);
	strobe_e();
	delay_us(160);
	strobe_e();
	delay_us(160);
	lcd_nybble(0x02,0);
	delay_us(160);
	lcd_cmd(0x28);					//set 4-bit mode and 2 lines
	delay_us(160);
	lcd_cmd(0x10);					//cursor move & shift left
	delay_us(160);
	lcd_cmd(0x06);					//entry mode = increment
	delay_us(160);
	lcd_cmd(0x0e);					//display on - cursor blink on
	delay_us(160);
	lcd_cmd(0x01);					//clear display
	delay_ms(40);
}

void strobe_e(void)
{
	FIO0SET = E;
	delay_us(1);
	FIO0CLR = E;
	delay_us(160);
}

void delay_ms(int x)
{
	int a,b;
	for(a=0;a<x;a++){
		for(b=0;b<3500;b++);
	}
}

void delay_us(int x)
{
	int a,b;
	for(a=0;a<x;a++){
		for(b=0;b<4;b++);
}
}

void clkinit(void)
{
	PLLCFG=0x24;				//set multiplier and divider values
	PLLFEED=0xAA;
	PLLFEED=0x55;
	PLLCON=0x01;				//enable PLL
	PLLFEED=0xAA;
	PLLFEED=0x55;
	while(!(PLLSTAT & PLOCK));	//wait for PLL to lock to set frequency
	PLLCON=0x3;					//connect PLL as clock source
	PLLFEED=0xAA;
	PLLFEED=0x55;
	MAMCR=0x02;					//enable MAM
	MAMTIM=0x04;				//set number of clocks used for flash memory fetch
	VPBDIV=0x01;				//set peripheral clock (pclk) to system clock (cclk)
}

void IRQ_Routine (void) {
	while (1) ;	
}
void FIQ_Routine (void)  {
	while (1) ;	
}
void SWI_Routine (void)  {
	while (1) ;	
}
void UNDEF_Routine (void) {
	while (1) ;	
}

And here is proof that it works :grin:

http://ghmicro.com/images/stories/LPC20 … t008sm.jpg

thank you very much, I just tried the code , still not working …

I’ve replaced the D7-D4 with LEDs, to see if the output change, and yes the LEDs blinks randomly. I tried the code without delays (using RW) but it don’t work, so I can conclude that the problem is not delays … (I guess!)

I think that the problem is power … the system is powered trough the onboard +5v. Olimex says that the board is able to deliver up to 800mA

the board is powered using ONLY USB.

what do you think about ?

zanak:
I think that the problem is power … the system is powered trough the onboard +5v. Olimex says that the board is able to deliver up to 800mA

the board is powered using ONLY USB.

800mA should be plenty, but I thought [[USB](http://en.wikipedia.org/wiki/USB) wouldn't deliver more than 100mA (or is it 500mA?) without the code asking for more.

Try powering it from a separate power supply. Can’t hurt to find out if that’s the problem.

The USB specification provides a 5 V supply on a single wire from which connected USB devices may draw power. The specification provides for no more than 5.25 V and no less than 4.75 V (5 V±5%) between the positive and negative bus power lines.

A unit load is defined as 100mA in USB 2.0, and was raised to 150mA in USB 3.0. A maximum of 5 unit loads can be drawn from a port in USB 2.0, and was raised to 6 in USB 3.0. There are two types of devices: low-power and high-power. Low-power devices draw at most 1 unit load, with minimum operating voltage of 4.4V in USB 2.0, and 4V in USB 3.0. High-power devices draw the maximum number of unit loads supported by the standard. All devices default as low-power but the device’s software may request high-power as long as the power is available on the providing bus.

A bus-powered hub is initialized at 1 unit load and transitions to maximum unit loads after hub configuration is obtained. Any device connected to the hub will draw 1 unit load regardless of the current draw of devices connected to other ports of the hub (i.e 1 device connected on a 4 port hub will only draw 1 unit load despite the fact that all unit loads are being supplied to the hub).

A self-powered hub will supply maximum supported unit loads to any device connected to it. A battery powered hub may supply maximum unit loads to port. In addition, the VBUS will supply 1 unit load upstream for communication if parts of the Hub are powered down.

](USB - Wikipedia)