Continue to Site

Welcome to EDAboard.com

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

Why doesn't my display routine work properly?

Status
Not open for further replies.

myru28

Member level 1
Joined
Jun 22, 2012
Messages
33
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,288
Activity points
1,558
I believe the following piece of code:

Code:
...
unsigned char dataString[10]="1234567890";
...

void main()
...
LCDinit();
while (1)			 // this is how to make a never ending loop.
	{
	lcdcmd(0x1);
	lcdcmd(0x2);
	//itoa (integer, biginin);
	stringtoLCD(dataString);
	}

void LCDinit(void)
{
	TRISE=0;
	lcdcmd(0x28);					//set 4-bit upper mode and 2 lines
	lcdcmd(0x10);					//cursor move & shift left
	lcdcmd(0x06);					//entry mode = increment
	lcdcmd(0x0d);					//display on - cursor blink on
	lcdcmd(0x01);					//clear display
}

void stringtoLCD(unsigned char *m)
{
unsigned char i;
     i = 0;
     while(i<10)
	 {
     LCDdata(m[i]);
	i++;
	}
}

void lcdcmd(unsigned char temp)
{
busylcd();
RS=0;
RW=0;
TRISD=0;
DATALCD=temp;
E=1;
LCDDelay();
E=0;
}

void LCDDelay(void)
{
int i=0;
int j=0;
int k=0;
int l=0;
int ll=0;

while (i<10)
{
j=0;
while (j<10)
{
j++;
l++;
ll++;
k++;
}
i++;
}

}

should display 1234567890 but instead it shows some sort of repeated random symbols everytime I execute the program.

What am I doing wrong?

Thanks.

[/code]
 

Post your LCDdata function here, May be It has following described problem:

you're not adding 30 in all your digits, you need to do it because you are sending just 1,2,3... one by one.
but instead you need to send their ASCII values, & you'll get them by adding 30 to your decimal values.
so send 31,32,33... to print 1,2,3....
 

Post your LCDdata function here, May be It has following described problem:

you're not adding 30 in all your digits, you need to do it because you are sending just 1,2,3... one by one.
but instead you need to send their ASCII values, & you'll get them by adding 30 to your decimal values.
so send 31,32,33... to print 1,2,3....

Oh, right, I forgot to put it. This is my routine:

Code:
void LCDdata (unsigned char value)
{
busylcd();
TRISD = 0;
DATALCD = value;
RS=1;
RW=0;
E=1;
LCDDelay();
E=0;
 
}

Magvitron said:
from the looks of waht you said, it may be due to improper data pin assigned.

I checked them and they are connected right.
 

Code:
void LCDdata (unsigned char value)
{
busylcd();
TRISD = 0;
DATALCD = value;
RS=1;
RW=0;
E=1;
LCDDelay();
E=0;
 
}

Instead of above use this code and check it:
Code:
void LCDdata (unsigned char value)
{
busylcd();
TRISD = 0;
value+=30;
DATALCD = value;
RS=1;
RW=0;
E=1;
LCDDelay();
E=0;
 
}
 

Instead of above use this code and check it:
Code:
void LCDdata (unsigned char value)
{
busylcd();
TRISD = 0;
value+=30;
DATALCD = value;
RS=1;
RW=0;
E=1;
LCDDelay();
E=0;
 
}

Doesn't work... It still shows things that doesn't have to do anything with the 1234567890.anyway at least now it shows, at least partially, meaningful things as numbers or letters, with the original LCDdata it displays "3"s and with your LCDData things like F,f or d. But the strange thing is that the output can change any time the code is executed.
 

Instead of above use this code and check it:
Code:
void LCDdata (unsigned char value)
{
busylcd();
TRISD = 0;
[B][COLOR="#FF0000"]value+=30;[/COLOR][/B]
DATALCD = value;
RS=1;
RW=0;
E=1;
LCDDelay();
E=0;
 
}

In order to convert the integer to an ascii format you either need to add hex 0x30 or decimal 48 , if you add decimal 30 then you will get wrong result

- - - Updated - - -

@myru28

Try with

Code:
void LCDdata (unsigned char value)
{
busylcd();
TRISD = 0;
value+=0x30;
DATALCD = value;
RS=1;
RW=0;
E=1;
LCDDelay();
E=0;
 
}
 

yes alexan_e is right.
I am so sorry for my wrong answer.

just forget it, but don't know how I forget such thing :(

Thanks alexan_e to correct me and helping myru28.
I am sorry myru28.
 

In order to convert the integer to an ascii format you either need to add hex 0x30 or decimal 48 , if you add decimal 30 then you will get wrong result

- - - Updated - - -

@myru28

Try with

Code:
void LCDdata (unsigned char value)
{
busylcd();
TRISD = 0;
value+=0x30;
DATALCD = value;
RS=1;
RW=0;
E=1;
LCDDelay();
E=0;
 
}

Tried, but no positive result. Instead of all 3s I get all fs. (I managed to solve the problem of strange symbols).

Anyway, I think the most important thing to notice is that it's like it's not reading dataString and reading maybe another memory position, but why could this be happening?
 

Code:
unsigned char dataString[10] = "1234567890";

This doesn't leave space for the null terminator, either use dataString[10] or dataString[]
 

Code:
unsigned char dataString[10] = "1234567890";

This doesn't leave space for the null terminator, either use dataString[10] or dataString[]

Checked with dataString[], same result.

Thanks a million for your help in any case.
 

Yes, it will not make a difference in your case because you don't use a function that expects it but you should still be aware of it.
Usually there is a LCD show string function in which you send the address of the array and it shows all the characters until it finds the null terminator , if there isn't one then the result will be a mess.
You are using your own function that shows a specific number of characters so the null doesn't make a difference.
 

Hi ,
take care of the way you transmit the byte. You configured your lcd in high nibble mode. It means that you have to transmit the byte nibble by nibble :grin:
If your lcd is conected on portx Rx7,Rx6,Rx5,Rx4 (high nibble mode) you transmit value (8 bit = 1 byte of data) like this :
LATx = value; // high nible of value
E=1;LCDDelay();E=0; // pulse
LATx = value<<4 // low nible of value
E=1;LCDDealy();E=0; // pulse

ps: take care of timmings , lcd's are slow
 

problems:

lcdcmd(0x28); //set 4-bit upper mode and 2 lines
you are configuring for 4 bit nah? or 8 bit?
if for 4 bit the data to lcd routine is completely off here.
for data inp
Code:
void four_bit_data(unsigned char datai)
{
	unsigned char datax;
	datax=(datai &0xF0); // data is anded with 0f0 for the upper nibble
	LCDdata(datax); // sent the data.
	data1=((datai<<4)&0xF0); // this for lower nibble
	LCDdata(datax);
}
for command :

Code:
void four_bit_cmd(unsigned char datai)
{
	unsigned char datax;
	datax=(datai &0xF0);
	lcdcmd(datax);
	data1=((datai<<4)&0xF0);
	lcdcmd(datax);
}
and enter it here
Code:
void stringtoLCD(unsigned char *m)
{
unsigned char i;
     i = 0;
     while(i<10)
	 {
          four_bit_data(m[i]);
	i++;
	}
}

and for init

Code:
void lcd_ini()	                    
{
	dis_cmd(0x02);		// To initi LCD in 4-bit mode.
	dis_cmd(0x28);		// To init LCD in 2 lines and have 5x7 dots and in 4bit mode.
	dis_cmd(0x0C);
	dis_cmd(0x06);
	dis_cmd(0x80);
}
 
I believe the following piece of code:

Code:
void stringtoLCD(unsigned char *m)

I got the EXACT LOCATION OF YOUR ERROR.

try by editing this function (stringtoLCD) as below: (I've implement this code on hardware through 8051 before sometime)

Code:
void stringtoLCD(unsigned char *m)
{
unsigned char i;                                                
     for(i=1;i<=10;i++)
	 {
                LCDdata(*m);
	        m++;
	}
}


Reason : you can't use the pointer as an array.
Just have done on hardware (before an hour).


_____________UPDATED

And ya... delete the line which you've add
value+=0x30;

Because we don't need while displaying the string using pointer.
Keep the lcdDATA function as it was (without value+=0x30; )
 
Last edited:

I got the EXACT LOCATION OF YOUR ERROR.

try by editing this function (stringtoLCD) as below: (I've implement this code on hardware through 8051 before sometime)

Code:
void stringtoLCD(unsigned char *m)
{
unsigned char i;                                                
     for(i=1;i<=10;i++)
	 {
                LCDdata(*m);
	        m++;
	}
}


Reason : you can't use the pointer as an array.

Actually you can, please read https://www.eskimo.com/~scs/cclass/notes/sx10e.html

Pointer assignment is straightforward; the pointer on the left is simply made to point wherever the pointer on the right does. We haven't copied the data pointed to (there's still just one copy, in the same place); we've just made two pointers point to that one place.

The similarities between arrays and pointers end up being quite useful, and in fact C builds on the similarities, leading to what is called ``the equivalence of arrays and pointers in C.'' When we speak of this ``equivalence'' we do not mean that arrays and pointers are the same thing (they are in fact quite different), but rather that they can be used in related ways, and that certain operations may be used between them.

The first such operation is that it is possible to (apparently) assign an array to a pointer:

Code:
	int a[10];
	int *ip;
	ip = a;

What can this mean? In that last assignment ip = a, aren't we mixing apples and oranges again? It turns out that we are not; C defines the result of this assignment to be that ip receives a pointer to the first element of a. In other words, it is as if you had written

Code:
	ip = &a[0];

The second facet of the equivalence is that you can use the ``array subscripting'' notation on pointers, too. If you write

Code:
	ip[3]

it is just as if you had written

Code:
*(ip + 3)

So when you have a pointer that points to a block of memory, such as an array or a part of an array, you can treat that pointer ``as if'' it were an array, using the convenient notation. In other words, at the beginning of this section when we talked about *ip, *(ip+1), *(ip+2), and *(ip+i), we could have written ip[0], ip[1], ip[2], and ip. As we'll see, this can be quite useful (or at least convenient).
 

problems:


you are configuring for 4 bit nah? or 8 bit?
if for 4 bit the data to lcd routine is completely off here.
for data inp
Code:
void four_bit_data(unsigned char datai)
{
	unsigned char datax;
	datax=(datai &0xF0); // data is anded with 0f0 for the upper nibble
	LCDdata(datax); // sent the data.
	data1=((datai<<4)&0xF0); // this for lower nibble
	LCDdata(datax);
}
for command :

Code:
void four_bit_cmd(unsigned char datai)
{
	unsigned char datax;
	datax=(datai &0xF0);
	lcdcmd(datax);
	data1=((datai<<4)&0xF0);
	lcdcmd(datax);
}
and enter it here
Code:
void stringtoLCD(unsigned char *m)
{
unsigned char i;
     i = 0;
     while(i<10)
	 {
          four_bit_data(m[i]);
	i++;
	}
}

and for init

Code:
void lcd_ini()	                    
{
	dis_cmd(0x02);		// To initi LCD in 4-bit mode.
	dis_cmd(0x28);		// To init LCD in 2 lines and have 5x7 dots and in 4bit mode.
	dis_cmd(0x0C);
	dis_cmd(0x06);
	dis_cmd(0x80);
}

i guess the full code would be this way? Or am I getting something wrong?

Code:
#include <stdio.h>
#include <P18CXXX.h>    
#include <delays.h>
#include <timers.h>
 
#pragma code page  // This code make sure the program starts from 0x0004, not from 0x0000
#pragma config WDT = OFF
#pragma config OSC=INTIO67
 
#define RS PORTEbits.RE1
#define dirRS TRISEbits.TRISE1
#define RW PORTBbits.RB1
#define dirRW TRISBbits.TRISB1
#define E PORTEbits.RE2
#define dirE TRISEbits.TRISE2
#define DATALCD PORTD
#define dirDATA TRISD
#define LCDBusy PORTDbits.RD7
 
 
 
void LCDdata (unsigned char);
void busylcd(void);
void LCDinit (void);
void LCDDelay( void );
void lcdcmd(unsigned char);
void stringtoLCD(unsigned char *m);
void four_bit_cmd(unsigned char datai);
void four_bit_data(unsigned char datai);


 
unsigned char dataString[]="2";
 
 
void main (void)		// main  function 
{
TRISD = 0;
PORTD = 0;	
TRISB = 0;				// Port,pin direction configuration
PORTB = 0;
TRISC = 0;
PORTC = 0;
TRISCbits.TRISC7 = 1;  // make sure this pin is input
ADCON1=255;
dirRS = 0;
LCDinit();
while (1)			 // this is how to make a never ending loop.
	{
		lcdcmd(0x1);
	lcdcmd(0x2);
	stringtoLCD(dataString);
	
}

//Con LCDInit propuesto no funciona
//Con LCDInit normal y configurado para 4 bits funciona a veces y da lo mismo y con simbolos raros
//Con LCDInit normal y configurado para 8 suele funcionar sacando el 3
 
}
//////////////////////////////////////////////////////////////////////////////////////
//LCD finctions------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////////////
void LCDdata (unsigned char value)
{
busylcd();
TRISD = 0;
DATALCD = value;
RS=1;
RW=0;
E=1;
LCDDelay();
E=0;
 
}
//--------------------------------------------------------------------------------------
void LCDinit(void)
{
	TRISE=0;
	
				//clear display*/
	four_bit_cmd(0x02);		// To initi LCD in 4-bit mode.
	four_bit_cmd(0x28);		// To init LCD in 2 lines and have 5x7 dots and in 4bit mode.
	four_bit_cmd(0x0C);
	four_bit_cmd(0x06);
	four_bit_cmd(0x80);

}
//-------------------------------------------------------------------------------------
void busylcd(void)
{
RS=0;
RW=1;
TRISD=255;
	E=0;
	LCDDelay();
	E=1;
while(LCDBusy==1){
	E=0;
	LCDDelay();
	E=1;
	}
}
//-------------------------------------------------------------------------------------
void lcdcmd(unsigned char temp)
{
busylcd();
RS=0;
RW=0;
TRISD=0;

DATALCD=temp;
E=1;
LCDDelay();
E=0;
}

void four_bit_data(unsigned char datai)
{
	unsigned char datax;
	unsigned char data1;
	datax=(datai &0xF0); // data is anded with 0f0 for the upper nibble
	LCDdata(datax); // sent the data.
	data1=((datai<<4)&0xF0); // this for lower nibble
	LCDdata(datax);
}

void four_bit_cmd(unsigned char datai)
{
	unsigned char datax;
	unsigned char data1;
	datax=(datai &0xF0);
	lcdcmd(datax);
	data1=((datai<<4)&0xF0);
	lcdcmd(datax);
} 

//--------------------------------------------------------------------------------------
void LCDDelay(void)
{


int i=0;
for (i=0;i<250;i++);

}





void stringtoLCD(unsigned char *m)
{
unsigned char i;
     i = 0;
     while(i<1)
	 {
          four_bit_data(m[i]);
	i++;
	}
}

It even seems to work worse than mine for me as it looks like the display cannot even get out of its reset state (all the first row with black squares), but if I do the LCD Init of my original code instead of the one you have proposed, at least it shows something.
 

hi,
you are close to the solution, first we need to clarify some things : is your LCD module connected to PIC in 4 data bits mode or in 8 data bit mode ? I mean physically : pin 14,13, 12, 11 connected to PIC port and pin 10,9,8,7 to ground ? Or do you have all data pins 14 .....7 connected to PIC's port ?
which port are you using ? Verify IO pins of that port in datasheet , some pins may not have internal pull up rezistors, if so put external one (5...10 K) . Tell us what mcu are you using ?
About data types and lcd function we 'll see later ...
 

Code:
void four_bit_data(unsigned char datai)
{
	unsigned char datax;
	unsigned char data1;
	datax=(datai &0xF0); // data is anded with 0f0 for the upper nibble
	LCDdata(datax); // sent the data.
	[COLOR="#FF0000"]datax[/COLOR]=((datai<<4)&0xF0); // this for lower nibble
	LCDdata(datax);
}
sorry for the error, actualy its datax = ((datai<<4)&0xF0);

try this
Code:
#include <stdio.h>
#include <P18CXXX.h>    
#include <delays.h>
#include <timers.h>
 
#pragma code page  // This code make sure the program starts from 0x0004, not from 0x0000
#pragma config WDT = OFF
#pragma config OSC=INTIO67
/* 
#define RS PORTEbits.RE1
#define dirRS TRISEbits.TRISE1
#define RW PORTBbits.RB1
#define dirRW TRISBbits.TRISB1
#define E PORTEbits.RE2
#define dirE TRISEbits.TRISE2
#define DATALCD PORTD
#define dirDATA TRISD
*/
#define RS LATE.F1
#define RW LATB.F1
#define E LATE.F2
#define DATALCD LATD
//conectar el nibble superior de la pantalla LCD para el nibble b puerto mas alto que es el puerto b 4-7
 
void LCDdata (unsigned char);
void LCDinit (void);
void LCDDelay( void );
void lcdcmd(unsigned char);
void four_bit_cmd(unsigned char datai);
void four_bit_data(unsigned char datai);


 
unsigned char dataString[]="Hola mundo";
 
 
void main (void)		// main  function 
{
	unsigned int i=0;
	TRISD=0;			// Configure Port B as output port
	LATD=0;

LCDinit();
while (1)			 // this is how to make a never ending loop.
	{
	 unsigned int i;
     while(dataString[i]!='\0')
	 {
          four_bit_data(dataString[i]);
       	i++;
	}
	
}

//Con LCDInit propuesto no funciona
//Con LCDInit normal y configurado para 4 bits funciona a veces y da lo mismo y con simbolos raros
//Con LCDInit normal y configurado para 8 suele funcionar sacando el 3
 
}
//////////////////////////////////////////////////////////////////////////////////////
//LCD finctions------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////////////
void LCDdata (unsigned char value)
{
DATALCD = value;
RS=1;
RW=0;
E=1;
Delay_ms(10);
E=0;

}
//--------------------------------------------------------------------------------------
void LCDinit(void)
{
	
				//clear display*/
	four_bit_cmd(0x02);		// To initi LCD in 4-bit mode.
	four_bit_cmd(0x28);		// To init LCD in 2 lines and have 5x7 dots and in 4bit mode.
	four_bit_cmd(0x0C);
	four_bit_cmd(0x06);
	four_bit_cmd(0x80);

}

//-------------------------------------------------------------------------------------
void lcdcmd(unsigned char temp)
{
RS=0;
RW=0;
DATALCD=temp;
E=1;
Delay_ms(10); 
E=0;
}

void four_bit_data(unsigned char datai)
{
	unsigned char datax;
	datax=(datai &0xF0); // data is anded with 0f0 for the upper nibble
	LCDdata(datax); // sent the data.
	data1=((datai<<4)&0xF0); // this for lower nibble
	LCDdata(datax);
}

void four_bit_cmd(unsigned char datai)
{
	unsigned char datax;
	datax=(datai &0xF0);
	lcdcmd(datax);
	data1=((datai<<4)&0xF0);
	lcdcmd(datax);
} 

//--------------------------------------------------------------------------------------

}
 
Last edited:
So when you have a pointer that points to a block of memory, such as an array or a part of an array, you can treat that pointer ``as if'' it were an array, using the convenient notation. In other words, at the beginning of this section when we talked about *ip, *(ip+1), *(ip+2), and *(ip+i), we could have written ip[0], ip[1], ip[2], and ip. As we'll see, this can be quite useful (or at least convenient).


Absolutely not correct.

May be right for some situation but I've tried (on hardware!!!) by using *m = m

No Result (just gets some sign which have different ASCII values than my data)

Then I've again try (on hardware) by using only *m & incrementing it (m++) (as shown in my last reply)
I got the perfect result.

You can try myru28 if you like to analyze this.

- - - Updated - - -

Code:
void stringtoLCD(unsigned char *m)
{
unsigned char i;
     i = 0;
     while(i<1)
	 {
          four_bit_data(m[i]);
	i++;
	}
}

Just give one try to replacing this function by the one which I've post.
Just give it a try.
Because if it is working on at89c51rd2 with Keil uVision 4 also on Proteus and also on hardware then why don't with you?

So I am eager to get the reason what exactly is there.
just try it on proteus first.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top