#AP NEW GPS Interfacing with LPC2148 (Two Files)

//**  Save this file as main.c

#include<lpc214x.h>
#include "stdio.h"


#define LCD_PORT 0x00FF0000
#define EN 1<<10 //define RS pin
#define RS 1<<11 //define EN pin
#define RW 1<<20 //define RW pin
#define LCD_SHIFT 16 //shift data by LCD_SHIFT bits

void delay(unsigned int time);
void LCD_data(unsigned char);    //function to send data
void LCD_cmd(unsigned char);    //function to send command
void LCD_init(void);
void LCD_display(int, int, unsigned char*);

void UartInit(unsigned int);
int UART_GetChar(void);
int UART_PutChar(unsigned char);

void GPS_string(unsigned char *temp);
void GPS_display(unsigned char *lat, unsigned char *lon);

/* In the main function, we will continuously keep checking the serial port for character '$'
** If the character '$' is received, fetch all the characters between '$' and '*'
** Extract the latitude and longitude details from the string and display it on the LCD
** Eg: $GPGGA,155635,3730.4379,N,02357.4137,E,1,04,5.6,3.8,M,34.5,M,,*41
*/
int main()
{
unsigned char ch, temp[20],lat[10],lon[10];
unsigned int i=0,j=0;
LCD_init();
UartInit(9600);
LCD_display(1,1,"GPS Program");  
delay(200000);
LCD_cmd(0x01); //Clear Display
LCD_display(1,1,"LAT:");
LCD_display(2,1,"LON:");
while(1)
{
if((ch = UART_GetChar()) == '$') //if '$' is received
{
GPS_string(temp); //fetch all characters upto '*'
if(temp[2] == 'G' && temp[3] == 'G' && temp[4] == 'A')
{
i=0;
j=0;
while(temp[i++] != ','); //$GPGGA (ignore)
while(temp[i++] != ','); //Time Stamp (ignore)
while(temp[i] != ',') //Capture Latitude
lat[j++] = temp[i++];
while(temp[i++] != ','); //North/South
lat[j++] = temp[i++];

j=0;
while(temp[i++] != ',');
while(temp[i] != ',') //Capture Longitude
lon[j++] = temp[i++];
while(temp[i++] != ','); //East/West
lon[j++] = temp[i++];
//(ignore the rest part of the string)
GPS_display(lat,lon); //display latitude and longitude on the LCD
}
}
}
return 0;
}

void delay(unsigned int time)
{
int i,j;
for(i=0;i<time;i++)
for(j=0;j<200;j++);
}

void LCD_strobe()    //Enable pulse
{
delay(100);
IOSET0 = EN;
delay(100);
IOCLR0 = EN;
delay(100);
}

void LCD_data(unsigned char ch)    //function to send data
{
IOCLR1 = LCD_PORT;    //clear LCD pins
IOSET1 = ch<<LCD_SHIFT;    //shift data and set only the data bits
IOSET0 = RS;    //RS =1
IOCLR0 = RW;    //RW = 0
LCD_strobe();    //EN pulse
}

void LCD_cmd(unsigned char ch)    //function to send command
{
IOCLR1 = LCD_PORT;
IOSET1 = ch<<LCD_SHIFT;
IOCLR0 = RS;   //RS = 0  
IOCLR0 = RW;   //RW = 0
LCD_strobe();   //EN pulse
}

void LCD_init(void)
{
PINSEL0 &= 0xFF0FFFFF;   //Pins P0.10 and P0.11 as GPIO
PINSEL1 &= 0xFFFFFCFF; //Pin P0.20 as GPIO
PINSEL2 &= 0xFFFFFFF3; //PORT1 as GPIO

IODIR0 |= RS | EN | RW; //set the pins as output
IODIR1 |= LCD_PORT;  

LCD_cmd(0x38); //8bit use both lines
LCD_cmd(0x06); //Entry mode
LCD_cmd(0x0C); //display ON cursor OFF
LCD_cmd(0x01); //Clear display
LCD_cmd(0x80); //cursor at 1st line 1st position
}

void LCD_display(int row, int pos, unsigned char *ch)
{
unsigned char temp;

if(row==1)
{
temp = 0x80 | (pos-1); //set cursor at 1st line pos position
}
else
{
temp = 0xC0 | (pos-1); //set cursor at 2nd line pos position
}
LCD_cmd(temp);
while(*ch) //while data is valid, display the string
LCD_data(*ch++);
}



/* This function fetches a string from the serial port using UART_GetChar() function
** In case of GPS, the co-ordinate string starts with a character '$'
** And ends with a character '*' followed by CRC
*/
void GPS_string(unsigned char *temp)
{
unsigned int i=0;
do
{
temp[i] = UART_GetChar();
}
while(temp[i++] != '*'); //while '*' character is not received, keep fetching the string
temp[i] = '\0'; //add a NULL character at the end of the string
}


/* This function takes the latitude and longitude string pointers as the input parameters
** And displays them on the LCD in a proper fashion
*/
void GPS_display(unsigned char *lat, unsigned char *lon)
{
unsigned int i;

LCD_cmd(0x84);   //cursor on 1st line 5th position
for(i=0;i<2;i++)
LCD_data(*lat++); //display degrees
LCD_data('\''); //degree symbol
for(i=0;i<8;i++) //display rest of the string
LCD_data(*lat++);

LCD_cmd(0xC4); //cursor on 2nd line 5th position
for(i=0;i<3;i++)
LCD_data(*lon++); //display degrees
LCD_data('\''); //degree icon
for(i=0;i<8;i++) //display rest of the string
LCD_data(*lon++);
}



/***********************************************************************

//** Save this file as UART.c

#include "lpc214x.h"
#include "stdio.h"
void UartInit(unsigned int baudrate)   //setting the baud rate for 115200 baud
{
 int i,FDiv;

 i = PINSEL0;    // read the value of the pins function
 i = i & 0xFFF0FFF0;    // modify the value
 PINSEL0 = (i | 0x50005);    // set the functionality of the TxD and Rxd Pin :01

//set the baud rate
U1LCR = 0x83; // Line control register :DLAB=1 ; 8 bits ; 1 stop bit ; no parity
FDiv = (15000000 / 16 ) / baudrate ; //
U1DLM = FDiv /256; //0x00;
U1DLL = FDiv %256; //0x97;
U1LCR = 0x03; // Line control register :DLAB=0 ; 8 bits ; 1 stop bit ; no parity
U1TER = 0x80;
}

int UART_GetChar(void)
{
while(!(U1LSR & 0x1));     //wait till data is received is receive register
return(U1RBR);
}

int UART_PutChar(unsigned char ch)
{
 while (!(U1LSR & 0x20)); //wait for transmit register to become empty
if (ch == '\n') 
 {
    ch = 0x0D;                       //output <CR>
 } 
U1THR = ch;
return(ch);
}


/* 
** Re-targetting to allow to redefine low-level I/O routines.
** Implements the functionality required to adapt character I/O functions such as printf() and scanf().
** Refer The template file .../Keil/Arm/Startup/RETARGET.C
*/
int fputc(int ch, FILE *f) {
  return (UART_PutChar(ch));
}

struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
  

Comments