Need help with my code for GPS

Status
Not open for further replies.

Naumanpak

Member level 2
Joined
Nov 19, 2009
Messages
51
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,288
Location
Pakistan
Activity points
1,635
Hi experts, need help once more..


I am trying to get data from serial pin TXD of GPS module Holux GR-89 and then display on the LCD using 8051 microcontroller.

Module works perfectly when interfaced with PC.


With your guidance, I was successfully able to interface the 16x4 LCD.

But now, I am getting dummy values displayed on LCD.

GPS(TXD)------>89c51(P3.0)RXD------>LCD(getting dummy values)

LCD displays every thing right other than the data from serial pin.

here is my code:



Code:
#include <regx51.h>
#include <lcd.h>
#define lcd_port P0
#define XTAL     11.059200  
#define XDIVIDER 12.0       

#define delay_1ms 164 * (XTAL/XDIVIDER)

void delay(unsigned char);
void delay_ms(unsigned int);

void SerialInit() 
{  		
				TMOD = 0x20;	 // timer 1 (8 bit auto-reloed) 
				TH1 = 0xFA; //to obtain 4800 baud rate 
				TR1 = 1;	 //start timer 
				SCON = 0x50; 
 				return; 
}

unsigned char SerialRecvChar() 
{	
				while(!RI);	 //waits till a byte is recieved 
				RI = 0; 
				return (SBUF); 
} 



main()
{
	              unsigned char ch;
			      unsigned int i=0;
			      lcd_command(0x01);
			      Lcd_Ini();
			      lcd_display('G');
			      lcd_display('P'); 
			      lcd_display('S');
			      lcd_display(' ');
			      lcd_display('B');
			      lcd_display('a');
			      lcd_display('s');
			      lcd_display('e');
			      lcd_display('d');
			
			      lcd_command(0xC2); 
			      lcd_display('N');
			      lcd_display('a');
			      lcd_display('v');
			      lcd_display('i');
			      lcd_display('g');
			      lcd_display('a');
		            lcd_display('t');
			      lcd_display('i');
				lcd_display('o'); 
			      lcd_display('n');

				lcd_command(0x94); 
			      lcd_display('*');
			      lcd_display('*');
			      lcd_display('*');
			      lcd_display('*');


				while(1)	   
               		{
				
				 		SerialInit();
						ch=SerialRecvChar();
						lcd_command(0xd0);
				                lcd_display(ch);


						ch=SerialRecvChar();
						lcd_command(0xd1);
				                lcd_display(ch);

						ch=SerialRecvChar();
						lcd_command(0xd2);
						lcd_display(ch);

						ch=SerialRecvChar();
						lcd_command(0xd3);
						lcd_display(ch);

						ch=SerialRecvChar();
						lcd_command(0xd4);
				                lcd_display(ch);

						ch=SerialRecvChar();
						lcd_command(0xd5);
				            lcd_display(ch);

						ch=SerialRecvChar();
						lcd_command(0xd6);
				                lcd_display(ch);

						ch=SerialRecvChar();
						lcd_command(0xd7);
				               lcd_display(ch);

						ch=SerialRecvChar();
						lcd_command(0xd8);
				                lcd_display(ch);

						ch=SerialRecvChar();
						lcd_command(0xd9);
				                lcd_display(ch);
  
						ch=SerialRecvChar();
						lcd_command(0xda);
				                lcd_display(ch);

						ch=SerialRecvChar();
						lcd_command(0xdb);
				                lcd_display(ch);
				}             
}
 

You may check the serial initialization routine. SCON = 0x50; should be in before start the timer (TR1 = 1; )

Code:
void SerialInit()
{        
            SCON = 0x50;
            TMOD = 0x20;    // timer 1 (8 bit auto-reloed)
            TH1 = 0xFA; //to obtain 4800 baud rate
            TR1 = 1;    //start timer
            return;
}


regards
bassa
 

    Naumanpak

    Points: 2
    Helpful Answer Positive Rating
How much delay you are using in the LCD routine?

You must empty the serial buffer within 2 msec so that it will not overflow.

Also the
Code:
SerialInit();
routine should be called out side the main loop.

Also check the SMOD bit.
 

    Naumanpak

    Points: 2
    Helpful Answer Positive Rating
Check this part also

Code:
unsigned char SerialRecvChar()
{   
            while(RI == 0);    //waits till a byte is recieved
	     ch = SBUF
            RI = 0;
            return (ch);
}


SerialInit(); should be above the while as below

Code:
lcd_display('*');

	SerialInit();
            while(1)      
                     {


And also did you able to display first letters which are "GPS BASED..." ?

Hope your comment after testing above

regards
bassa
 

    Naumanpak

    Points: 2
    Helpful Answer Positive Rating
AMK1971, I have tried to call SerialInit(); outside main.

and here is my lcd code


Code:
void Lcd_Ini()
{
                lcd_command(0x38);
                delay_ms(30);
                lcd_command(0x0c);
                delay_ms(10);
                lcd_command(0x06);
                delay_ms(10);
                lcd_command(0x01);                    
                delay_ms(10);
}
  
void lcd_command(unsigned char command)
{
                rw=0;
				delay_ms(10);
                rs=0;
				delay_ms(10);
                lcd_port=command;
                enable=1;
                enable=0;
                delay_ms(5);
}
  
void lcd_display(unsigned char display)
{
                rw=0;
				delay_ms(10);
                rs=1;
				delay_ms(10);
                lcd_port=display;
				enable=1;
                enable=0;
                delay_ms(1);
}

void delay_ms(unsigned int i)
{
 
       			for(;i!=0x00;i--)
               			{
               			delay(delay_1ms);
                        }
}

void delay(unsigned char j)
{
                for (;j!=0x00;j--)
                        {
                        }
}


thanks

Added after 14 minutes:

Bassa, I have tried your suggestions but still getting dummy values rather than NMEA stream.


Yes I get the other thing displayed correctly.

GPS based
navigation
****


thanks
 

Dear Nauman,

As you may have noticed by now that your lcd_Command function takes 25ms and lcd_display function takes 21ms, but you only have 2 msec time between succesive characters.

one option is to remove the unnecessary delays like below

Code:
void lcd_command(unsigned char command)
{
                rw=0;
//            delay_ms(10);
                rs=0;
//            delay_ms(10);
                lcd_port=command;
                enable=1;
                enable=0;
                delay_ms(1);
}
 
void lcd_display(unsigned char display)
{
                rw=0;
//            delay_ms(10);
                rs=1;
//            delay_ms(10);
                lcd_port=display;
            enable=1;
                enable=0;
                delay_ms(1);
}

more appropriate thing is to poll the status and check if the LCD has finished working on your command.

**broken link removed** contains a source code for AVR devices for the 4 bit interface of LCD with status checking. You can modify it for your purpose.

Also you can use a buffer to store the stream received from serial and start displaying it when the buffer is full.
 

    Naumanpak

    Points: 2
    Helpful Answer Positive Rating
Thank you AMK1971, I have removed maximum of the delay and tried to use buffer as well now but am not getting NMEA streams.

I keep getting dummy characters like this


LLLlllllplpppp
jjjvrppppppp
Jwssrprrrlllll
LLLPPPLLWk


here is a portion of main that replicates.

Code:
	  while(1)
	  {
	  lcd_display(SerialRecvChar());
	  }

And here is the lcd_display()


Code:
void lcd_display(unsigned char display)
{ 
                rw=0; 
                rs=1; 
                lcd_port=display; 
                enable=1; 
                enable=0; 
                delay_ms(1); 
}

Suggest please.



thanks
 

You may try to read data (GPS) through 8051 serial interrupts
 

    Naumanpak

    Points: 2
    Helpful Answer Positive Rating
Thanks for another response Bassa,

I have tried interrupts but same problem.

I am able to receive serial data but the wrong one. Gettting dummy characters rather than receiving NMEA data.

The value read from in SBUF seems incorrect.



thanks

Added after 1 minutes:

Do you think that the problem may be with the baud rate?

Changing the baud rate changes the values on LCD.


thanks

Added after 17 minutes:

It ought to be the issue,

when I change the baud rate on pc, similar things happen.

I have tried keil baud rate generator https://www.keil.com/products/c51/baudrate.asp but things dont seem to get working.


thanks

Added after 17 minutes:

I finally got it working!!!!!!

thank you all!

it was the baud rate that I was struggling with.


thanks again, the problem is resolved now
 

Can you share your schematic ?
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…