1284 views|0 replies

2015

Posts

0

Resources
The OP
 

MSP430 and ATK-NEO-6M GPS module [Copy link]

This post was last edited by Aguilera on 2019-11-4 22:03

Next, let me take a look at my hardware environment.

Hardware environment: MPS430 development board, FYD12864LCD display, USB to serial cable, ATK-NEO-6M GPS module

Software environment: IAR integrated development environment, serial port debugging tool, Secure CRT

Achievement goal: MSP430 receives GPS information through serial port 2 and displays it on the LCD, and sends the received data to the PC through serial port 1.

1. First adjust the sentence analysis part of msp430.

Idea: Transplant the GPS sentence analysis code mentioned by the manufacturer, manually send GPS data through the serial port, and display it on the LCD after analysis.

Post the GPS sentence analysis code provided by the manufacturer (only for reference and study)

#ifndef __GPS_H
#define __GPS_H

#include <math.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>

#include "../inc/uart.h"

//GPS NMEA-0183 protocol important parameter structure definition
//Satellite information
typedef struct  
{										    
 	uchar num; //Satellite number
	uchar eledeg; //Satellite elevation angle
	uint azideg; //Satellite azimuth
	uchar sn; //Signal to noise ratio		   
}nmea_slmsg;  
//UTC time information
typedef struct  
{										    
 	uint year; //year
	uchar month; //month
	uchar date; //date
	uchar hour; //hour
	uchar min; //minutes
	uchar sec; //seconds
}nmea_utc_time;   	   
//NMEA 0183 protocol parsed data storage structure
typedef struct  
{										    
 	uchar svnum; //Number of visible satellites
	nmea_slmsg slmsg[12]; //Maximum 12 satellites
	nmea_utc_time utc; //UTC time
	int latitude; //The latitude is enlarged by 100000 times, so it should be divided by 100000
	uchar nshemi; //North Latitude/South Latitude, N: North Latitude; S: South Latitude				  
	int longitude; //Longitude is enlarged 100000 times, actually divided by 100000
	uchar ewhemi; //East longitude/West longitude, E: East longitude; W: West longitude
	uchar gpssta; //GPS status: 0, not positioned; 1, non-differential positioning; 2, differential positioning; 6, estimating.				  
 	uchar posslnum; //The number of satellites used for positioning, 0~12.
 	uchar possl[12]; //Satellite number used for positioning
	uchar fixmode; // Positioning type: 1, no positioning; 2, 2D positioning; 3, 3D positioning
	uint pdop; //Position precision factor 0~500, corresponding to actual value 0~50.0
	uint hdop; //Horizontal precision factor 0~500, corresponding to actual value 0~50.0
	uint vdop; //Vertical precision factor 0~500, corresponding to actual value 0~50.0

	int altitude; //Altitude, magnified 10 times, actually divided by 10. Unit: 0.1m	 
	uint speed; // Ground speed, magnified 1000 times, actually divided by 10. Unit: 0.001 km/h	 
}nmea_msg; 
//////////////////////////////////////////////////////////////////////////////////////////////////// 	
//UBLOX NEO-6M clock pulse configuration structure
typedef struct  
{										    
 	uint header; //cfg header, fixed to 0X62B5 (little endian mode)
	uint id; //CFG TP ID:0X0706 (little endian mode)
	uint dlength; //data length
	int interval; //clock pulse interval, unit is us
	int length; //Pulse width, unit is us
	signed char status; //Clock pulse configuration: 1, high level is valid; 0, off; -1, low level is valid.			  
	uchar timeref; //Reference time: 0, UTC time; 1, GPS time; 2, local time.
	uchar flags; //Time pulse setting flag
	uchar reserved; //reserved			  
 	signed short antdelay; //antenna delay
 	signed short rfdelay; //RF delay
	signed int userdelay; //User delay	
	uchar cka; //Check CK_A 							 	 
	uchar ckb; //Check CK_B							 	 
}_ublox_cfg_tp; 
//UBLOX NEO-6M refresh rate configuration structure
typedef struct  
{										    
 	uint header; //cfg header, fixed to 0X62B5 (little endian mode)
	uint id; //CFG RATE ID:0X0806 (little endian mode)
	uint dlength; //data length
	uint measrate; //Measurement time interval, in ms, must not be less than 200ms (5Hz)
	uint navrate; //Navigation rate (cycle), fixed at 1
	uint timeref; //Reference time: 0=UTC Time; 1=GPS Time;
 	uchar cka; //Check CK_A 							 	 
	uchar ckb; //Check CK_B							 	 
}_ublox_cfg_rate; 
				 
int NMEA_Str2num(fly *buf,fly*dx);
void GPS_Analysis(nmea_msg *gpsx,uchar *buf);
void NMEA_GPGSV_Analysis(nmea_msg *gpsx,uchar *buf);
void NMEA_GPGGA_Analysis(nmea_msg *gpsx,uchar *buf);
void NMEA_GPGSA_Analysis(nmea_msg *gpsx,uchar *buf);
void NMEA_GPGSA_Analysis(nmea_msg *gpsx,uchar *buf);
void NMEA_GPRMC_Analysis(nmea_msg *gpsx,uchar *buf);
void NMEA_GPVTG_Analysis(nmea_msg *gpsx,uchar *buf);
void Ublox_Cfg_Tp(int interval,int length,signed char status);
void Ublox_Cfg_Rate(uint measrate,uchar reftime);

#endif  /* __GPS_H  */

#include "../inc/gps.h"

/*******************************************
Function Name: NMEA_Comma_Pos
Function: Get the position of the cxth comma from buf
parameter:
Return value: 0~0XFE, representing the offset of the comma position
          0XFF, indicating that the cxth comma does not exist
********************************************/
fly NMEA_Comma_Pos(fly *buf,fly cx)
{	 		    
	fly *p=buf;
	while(cx)
	{		 
		if(*buf=='*'||*buf<' '||*buf>'z')return 0XFF; //If '*' or illegal characters are encountered, the cxth comma does not exist
		if(*buf==',')cx--;
		buf++;
	}
	return buf-p;	 
}

/*******************************************
Function name: NMEA_Pow
Function: m^n function
parameter:
Return value: m^n power.
********************************************/
int NMEA_Pow(fly m,fly n)
{
	int result=1;	 
	while(n--)result*=m;    
	return result;
}

/*******************************************
Function name: NMEA_Str2num
Function: Convert str to a number, ending with ',' or '*'
Parameters: buf: digital storage area; dx: number of decimal places, returned to the calling function
Return value: the converted value
********************************************/
int NMEA_Str2num(fly *buf,fly*dx)
{
	fly *p=buf;
	int ires=0,fres=0;
	uchar ilen=0,flen=0,i;
	fly mask=0;
	int res;
	while(1) //Get the length of integers and decimals
	{
		if(*p=='-'){mask|=0X02;p++;} //is a negative number
		if(*p==','||(*p=='*'))break; //Ended
		if(*p=='.'){mask|=0X01;p++;} // Encountered a decimal point
		else if(*p>'9'||(*p<'0')) // There are illegal characters
		{	
			ilen=0;
			flen=0;
			break;
		}	
		if(mask&0X01)flen++;
		else ilen++;
		p++;
	}
	if(mask&0X02)buf++; //remove the minus sign
	for(i=0;i<ilen;i++) //Get the integer part of the data
	{  
		ires+=NMEA_Pow(10,ilen-1-i)*(buf-'0');
	}
	if(flen>5)flen=5; //Maximum 5 decimal places
	*dx=flen; //Decimal places
	for(i=0;i<flen;i++) //Get the decimal part of the data
	{  
		fres+=NMEA_Pow(10,flen-1-i)*(buf[ilen+1+i]-'0');
	} 
	res=ires*NMEA_Pow(10,flen)+fres;
	if(mask&0X02)res=-res;		   
	return res;
}	  							 

/*******************************************
Function name: NMEA_GPGSV_Analysis
Function: Analyze GPGSV information
Parameters: gpsx: nmea information structure; buf: the first address of the received GPS data buffer
Return value:
********************************************/
void NMEA_GPGSV_Analysis(nmea_msg *gpsx,uchar *buf)
{
	fly *p,*p1,dx;
	fly len,i,j,slx=0;
	flying poskh;   	 
	p=buf;
	p1=(uchar*)strstr((const char *)p,"$GPGSV");
	len=p1[7]-'0'; //Get the number of GPGSV
	posx=NMEA_Comma_Pos(p1,3); //Get the total number of visible satellites
	if(posx!=0XFF)gpsx->svnum=NMEA_Str2num(p1+posx,&dx);
	for(i=0;i<len;i++)
	{	 
		p1=(uchar*)strstr((const char *)p,"$GPGSV");  
		for(j=0;j<4;j++)
		{	  
			posx=NMEA_Comma_Pos(p1,4+j*4);
			if(posx!=0XFF)gpsx->slmsg[slx].num=NMEA_Str2num(p1+posx,&dx); //Get satellite number
			else break; 
			posx=NMEA_Comma_Pos(p1,5+j*4);
			if(posx!=0XFF)gpsx->slmsg[slx].eledeg=NMEA_Str2num(p1+posx,&dx); //Get satellite elevation angle
			else break;
			posx=NMEA_Comma_Pos(p1,6+j*4);
			if(posx!=0XFF)gpsx->slmsg[slx].azideg=NMEA_Str2num(p1+posx,&dx); //Get satellite azimuth
			else break;
			posx=NMEA_Comma_Pos(p1,7+j*4);
			if(posx!=0XFF)gpsx->slmsg[slx].sn=NMEA_Str2num(p1+posx,&dx); //Get satellite signal-to-noise ratio
			else break;
			slx++;	   
		}   
 		p=p1+1; //Switch to the next GPGSV information
	}   
}

/*******************************************
Function name: NMEA_GPGGA_Analysis
Function: Analyze GPGGA information
Parameters: gpsx: nmea information structure; buf: the first address of the received GPS data buffer
Return value:
********************************************/
void NMEA_GPGGA_Analysis(nmea_msg *gpsx,uchar *buf)
{
	fly *p1,dx;			 
	flying poskh;    
	p1=(uchar*)strstr((const char *)buf,"$GPGGA");
	posx=NMEA_Comma_Pos(p1,6); //Get GPS status
	if(posx!=0XFF)gpsx->gpssta=NMEA_Str2num(p1+posx,&dx);	
	posx=NMEA_Comma_Pos(p1,7); //Get the number of satellites used for positioning
	if(posx!=0XFF)gpsx->posslnum=NMEA_Str2num(p1+posx,&dx); 
	posx=NMEA_Comma_Pos(p1,9); //Get the altitude
	if(posx!=0XFF)gpsx->altitude=NMEA_Str2num(p1+posx,&dx);  
}

/*******************************************
Function name: NMEA_GPGSA_Analysis
Function: Analyze GPGSA information
Parameters: gpsx: nmea information structure; buf: the first address of the received GPS data buffer
Return value:
********************************************/
void NMEA_GPGSA_Analysis(nmea_msg *gpsx,uchar *buf)
{
	fly *p1,dx;			 
	flying poskh;
	flying i;   
	p1=(uchar*)strstr((const char *)buf,"$GPGSA");
	posx=NMEA_Comma_Pos(p1,2); //Get positioning type
	if(posx!=0XFF)gpsx->fixmode=NMEA_Str2num(p1+posx,&dx);	
	for(i=0;i<12;i++) //Get the positioning satellite number
	{
		posx=NMEA_Comma_Pos(p1,3+i);					 
		if(posx!=0XFF)gpsx->possl=NMEA_Str2num(p1+posx,&dx);
		else break; 
	}				  
	posx=NMEA_Comma_Pos(p1,15); //Get PDOP position precision factor
	if(posx!=0XFF)gpsx->pdop=NMEA_Str2num(p1+posx,&dx);  
	posx=NMEA_Comma_Pos(p1,16); //Get HDOP position precision factor
	if(posx!=0XFF)gpsx->hdop=NMEA_Str2num(p1+posx,&dx);  
	posx=NMEA_Comma_Pos(p1,17); //Get VDOP position precision factor
	if(posx!=0XFF)gpsx->vdop=NMEA_Str2num(p1+posx,&dx);  
}

/*******************************************
Function name: NMEA_GPRMC_Analysis
Function: Analyze GPRMC information
Parameters: gpsx: nmea information structure; buf: the first address of the received GPS data buffer
Return value:
********************************************/
void NMEA_GPRMC_Analysis(nmea_msg *gpsx,uchar *buf)
{
	fly *p1,dx;			 
	flying poskh;     
	int temp;	   
	float rs;  
	p1=(uchar*)strstr((const char *)buf,"$GPRMC");
	posx=NMEA_Comma_Pos(p1,1); //Get UTC time
	if(posx!=0XFF)
	{
		temp=NMEA_Str2num(p1+posx,&dx)/NMEA_Pow(10,dx); //Get UTC time, remove ms
		gpsx->utc.hour=temp/10000;
		gpsx->utc.min=(temp/100)%100;
		gpsx->utc.sec=temp%100;	 	 
	}			  			  
	posx=NMEA_Comma_Pos(p1,3); //Get latitude
	if(posx!=0XFF)
	{
		temp=NMEA_Str2num(p1+posx,&dx);		 	 
		gpsx->latitude=temp/NMEA_Pow(10,dx+2); //get degrees
		rs=temp%NMEA_Pow(10,dx+2); //get'		 
		gpsx->latitude = gpsx->latitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60; //Convert to degrees
	}
	posx=NMEA_Comma_Pos(p1,4); //South latitude or north latitude
	if(posx!=0XFF)gpsx->nshemi=*(p1+posx);					 
 	posx=NMEA_Comma_Pos(p1,5); //Get longitude
	if(posx!=0XFF)
	{												  
		temp=NMEA_Str2num(p1+posx,&dx);		 	 
		gpsx->longitude=temp/NMEA_Pow(10,dx+2); //get degrees
		rs=temp%NMEA_Pow(10,dx+2); //get'		 
		gpsx->longitude=gpsx->longitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60; //Convert to degrees
	}
	posx=NMEA_Comma_Pos(p1,6); //East longitude or west longitude
	if(posx!=0XFF)gpsx->ewhemi=*(p1+posx);		 
	posx=NMEA_Comma_Pos(p1,9); //Get UTC date
	if(posx!=0XFF)
	{
		temp=NMEA_Str2num(p1+posx,&dx); //Get UTC date
		gpsx->utc.date=temp/10000;
		gpsx->utc.month=(temp/100)%100;
		gpsx->utc.year=2000+temp%100;	 	 
	} 
}

/*******************************************
Function name: NMEA_GPVTG_Analysis
Function: Analyze GPVTG information
Parameters: gpsx: nmea information structure; buf: the first address of the received GPS data buffer
Return value:
********************************************/
void NMEA_GPVTG_Analysis(nmea_msg *gpsx,uchar *buf)
{
	fly *p1,dx;			 
	flying poskh;    
	p1=(uchar*)strstr((const char *)buf,"$GPVTG");							 
	posx=NMEA_Comma_Pos(p1,7); //Get ground speed
	if(posx!=0XFF)
	{
		gpsx->speed=NMEA_Str2num(p1+posx,&dx);
		if(dx<3)gpsx->speed*=NMEA_Pow(10,3-dx); //Ensure 1000 times enlargement
	}
}  

/*******************************************
Function name: GPS_Analysis
Function: Extract NMEA-0183 information
Parameters: gpsx: nmea information structure; buf: the first address of the received GPS data buffer
Return value:
********************************************/
void GPS_Analysis(nmea_msg *gpsx,uchar *buf)
{
	NMEA_GPGSV_Analysis(gpsx,buf); //GPGSV analysis
	NMEA_GPGGA_Analysis(gpsx,buf); //GPGGA analysis 	
	NMEA_GPGSA_Analysis(gpsx,buf); //GPGSA analysis
	NMEA_GPRMC_Analysis(gpsx,buf);	//GPRMC解析
	NMEA_GPVTG_Analysis(gpsx,buf);	//GPVTG解析
}

/*******************************************
Function name: Ublox_CheckSum
Function: GPS checksum calculation
Parameters: buf: the first address of the data buffer; len: data length; cka, ckb: two check results.
Return value:
********************************************/
void Ublox_CheckSum(uchar *buf,uint len,uchar* cka,uchar*ckb)
{
	uint i;
	*cka=0;*ckb=0;
	for(i=0;i<len;i++)
	{
		*chka=*chka+buf;
		*ckb=*ckb+*cka;
	}
}

/*******************************************
Function name: Ublox_Cfg_Tp
Function: Configure the clock pulse output of UBLOX NEO-6
Parameter: interval: pulse interval
          length: pulse width
          status: pulse configuration: 1, high level is valid; 0, off; -1, low level is valid.
Return value:
********************************************/
void Ublox_Cfg_Tp(int interval,int length,signed char status)
{/*
	_ublox_cfg_tp *cfg_tp=(_ublox_cfg_tp *)USART2_TX_BUF;
	cfg_tp->header=0X62B5;		//cfg header
	cfg_tp->id=0X0706;			//cfg tp id
	cfg_tp->dlength=20; //The data area length is 20 bytes.
	cfg_tp->interval=interval; //Pulse interval, us
	cfg_tp->length=length; //Pulse width, us
	cfg_tp->status=status; //Clock pulse configuration
	cfg_tp->timeref=0; //reference UTC time
	cfg_tp->flags=0;			//flags为0
	cfg_tp->reserved=0; //Reserved bit is 0
	cfg_tp->antdelay=820; //antenna delay is 820ns
	cfg_tp->rfdelay=0; //RF delay is 0ns
	cfg_tp->userdelay=0; //User delay is 0ns
	Ublox_CheckSum((uchar*)(&cfg_tp->id),sizeof(_ublox_cfg_tp)-4,&cfg_tp->cka,&cfg_tp->ckb);
	while(DMA1_Channel7->CNDTR!=0); //Wait for channel 7 transmission to complete   
	UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_tp)); //Send via dma
  */
}

/*******************************************
Function Name: Ublox_Cfg_Rate
Function: Configure the update rate of UBLOX NEO-6	    
Parameters: measrate: measurement time interval, in ms, must not be less than 200ms (5Hz)
          reftime: reference time, 0=UTC Time; 1=GPS Time (usually set to 1)
Return value:
********************************************/
void Ublox_Cfg_Rate(uint measrate,uchar reftime)
{/*
	_ublox_cfg_rate *cfg_rate=(_ublox_cfg_rate *)USART2_TX_BUF;
 	if(measrate<200)return; //Less than 200ms, exit directly
 	cfg_rate->header=0X62B5;	//cfg header
	cfg_rate->id=0X0806;	 	//cfg rate id
	cfg_rate->dlength=6; //The data area length is 6 bytes.
	cfg_rate->measrate=measrate; //Pulse interval, us
	cfg_rate->navrate=1; //Navigation rate (cycle), fixed at 1
	cfg_rate->timeref=reftime; //reference time is GPS time
	Ublox_CheckSum((uchar*)(&cfg_rate->id),sizeof(_ublox_cfg_rate)-4,&cfg_rate->cka,&cfg_rate->ckb);
	while(DMA1_Channel7->CNDTR!=0); //Wait for channel 7 transmission to complete   
	UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_rate)); //Send via DMA
  */
}

The above is the GPS related code, the following is the MSP430 related code

#ifndef _UART_H_
#define _UART_H_

#include <msp430f149.h>

void UartInit(void);
void SendData(volatile dat);
void SendByte(uchar *pData);
void SendString(char *s);

#endif	/* __UART_H */
#include "../inc/uart.h"

void UartInit(void)
{
  //Serial port 1 configuration
  P3DIR |= BIT4; //p3.4 is set as output
  P3SEL |= BIT4 + BIT5; //P3.4,5 are set to TXD/RXD	
  ME1 |= UTXE0 + URXE0;     //enable tx and rx
  UCTL0 = 0x00;             //reset as 0
  UCTL0 |= CHAR;            //8 bit transfer	
  UTCTL0 = 0x00;            //reset as 0
  UTCTL0 |= SSEL0;          //select aclk(8M)
  UBR00 = 0x03;
  UBR10 = 0x00; //Baud rate is 9600 (ACLK is 8MHz)
  UMCTL0 = 0x4A; 
  UCTL0 &= ~SWRST;          // reset UART	
  IE1 |= URXIE0;            // enable rx inerrupt
  
  //Serial port 2 configuration
  P3DIR |= BIT6; //p3.6 is set as output
  P3SEL |= BIT6 + BIT7; //P3.6,7 are set to TXD/RXD	
  ME2 |= URXE1 + UTXE1;     //enable tx and rx
  UCTL1 = 0x00;             //reset as 0
  UCTL1 |= CHAR;            //8 bit transfer	
  UTCTL1 = 0x00;            //reset as 0
  UTCTL1 |= SSEL0;          //select mclk
  UBR01 = 0x03;
  UBR11 = 0x00; //Baud rate is 9600 (ACLK is 8MHz)
  UMCTL1 = 0x4A;
  UCTL1 &= ~SWRST;          // reset UART	
  IE2 |= URXIE1;            // enable rx inerrupt
} 

void SendData(unsigned char dat)
{
  TXBUF0 = that;
  while(!(IFG1 & UTXIFG0));
  //IFG1 &= ~(UTXIFG0);
}

void SendString(char *s)
{
  while(*s){
    SendData(*s++);
  }
}

void SendByte(uchar *pData)
{
  flying i;
  for(i = 0; i < 8; i++){
    SendData(pData);
  }
}

The serial port operation is to configure the baud rate of both serial port 1 and serial port 2 to 9600 (I have read the application manual of the GPS module before and found that the default baud rate is 38400


, but I set the baud rate of 430 to 38400 and found that the received data was garbled, so I simply set the baud rate of GPS to 9600, and directly removed the R5 resistor on the module, and finally received normal data.)

#include <msp430f149.h>
#include "inc/lcd_fyd12864.h"
#include "inc/uart.h"
#include "inc/gps.h"

uchar Welcom1[] = "Welcome to Embedded";
uchar Welcom2[] = "*************";
uchar Welcom3[] = "Moderator: ******";
uchar Welcom4[] = "DIY Lab";

uchar latitude[] = "Lat: ";
uchar longitude[] = "Long: ";
uchar elevation[] = "Ele: ";
uchar currTime[]  = "Time: ";

float RxBuf[300], TxBuf[300];
float RxLen = 0;
float RxTempLen = 0;
uchar rev_flag = 0;
char dtbuf[50];
nmea_msg gpsx;

void main()
{
  volatile uint i;
  WDTCTL = WDTPW + WDTHOLD; // Turn off the watchdog

  BCSCTL1 &= ~XT2OFF;                       // XT2= HF XTAL
  do
  {
  IFG1 &= ~OFIFG;                           // Clear OSCFault flag
  for (i = 0xFF; i > 0; i--);               // Time for flag to set
  }
  while ((IFG1 & OFIFG));                   // OSCFault flag still set?
  //MCLK=8M,SCLK=1M
  BCSCTL2 |= SELM_2 + SELS + DIVS_3;        // MCLK= XT2 (safe)
  
  UartInit();
  Delay_ms(500);
 
  LCDReset();
  DisplayString(1, 0, Welcom1);
  DisplayString(1, 1, Welcom2);
  DisplayString(1, 2, Welcom3);
  DisplayString(1, 3, Welcom4);
  Delay_ms(2000);
  LCDClear();
  Delay_ms(1000);
/*
  DisplayString(0, 0, latitude);
  DisplayString(0, 1, longitude);
  DisplayString(0, 2, elevation);
  DisplayString(0, 3, currTime);
*/  
  SendString("**************\n");
  _EINT();
  while(1){
     //SendString("UART0 test!\n");
	 if(rev_flag == 1){
		int i,len = 0;
		len = RxLen;
		for(i = 0; i < len; i++)
			TxBuf = RxBuf;
		RxLen = 0;
		TxBuf = 0;
		GPS_Analysis(&gpsx,TxBuf);
		Show_GPS_Info(gpsx);
		SendString(TxBuf);
	 }
     //Delay_ms(1000);
  }
}

void Show_GPS_Info(nmea_msg gpsx)
{
  float tp;
  //Get the longitude string
  tp=gpsx.longitude;	   
  sprintf((char *)dtbuf,"Long:%.5f %1c",tp/=100000,gpsx.ewhemi);
  DisplayString(0, 0, dtbuf);
  //Get the latitude string
  tp=gpsx.latitude;	   
  sprintf((char *)dtbuf,"Lat:%.5f %1c",tp/=100000,gpsx.nshemi);
  DisplayString(0, 1, dtbuf);
  //Get the height string
  tp=gpsx.altitude;	   
  sprintf((char *)dtbuf,"Alt:%.1fm",tp/=10);
  DisplayString(0, 2, dtbuf);
  //Display UTC time
  sprintf((char *)dtbuf,"UTC:%02d:%02d:%02d",gpsx.utc.hour,gpsx.utc.min,gpsx.utc.sec);
  DisplayString(0, 3, dtbuf);
}

#pragma vector = UART0RX_VECTOR
__interrupt void UART0RxISR(void)
{
  //Receive data from the serial port
  while(!(IFG1 & UTXIFG0)); 
  RxBuf[RxTempLen++] = RXBUF0;
  while(RxBuf[RxTempLen-1] == '\n'){
	RxLen = RxTempLen;
	RxTempLen = 0;
	rev_flag = 1;
  }
}

#pragma vector = UART1RX_VECTOR
__interrupt void UART1RxISR(void)
{
  //Receive data from the serial port
  while(!(IFG2 & UTXIFG1)); 
  P2OUT = RXBUF1;
}

Among them, the LCD display part will be discussed in detail in other blog posts.

After burning the program to 430, power on, open the serial port debugging tool, and send the text as follows:

$GPGGA,023543.00,2308.28715,N,11322.09875,E,1,06,1.49,41.6,M,-5.3,M,,*7D

The data received will be the same as the one sent, and the LCD will show the altitude as 41.6m.

This indicates that the data can be accepted and processed correctly.

All you need to do next is copy the receive interrupt code of serial port 0 to the receive interrupt code of serial port 1.

Power on the device, and the LCD will display information, but the displayed data will be 0, indicating that GPS has not yet successfully located the device. After about 2 to 3 minutes, the indicator light on the GPS module will begin to flash, and the current longitude, latitude, altitude, and UTC time can be seen on the LCD. At the same time, when connected with ScuetCRT, the original data received by 430 can be seen.

The following figure shows the result of the experiment. The time display has a little problem, because there is no conversion or other reasons. However, after a few days of hard work, the GPS is finally fixed. The next step is to write a Linux driver. . . . Below is a post

Replenish:

I was busy with work before, and now I look back and find that the results of analyzing and displaying the received data are not correct. It is very likely caused by data overflow. The data sent to the PC through serial port 1 can be seen that the data received from the GPS module is correct. The only possibility is that an error occurred during data analysis. Sure enough, I tracked it to gps.c and found that the data processed was too large, and the int of msp430 is only 16 bits, with a maximum value of 65536, so it will definitely overflow when loading the data. I only discovered this when I occasionally looked at it at work today. After returning, I replaced the int type used with the long type, and it should be correct. I look forward to verifying it after returning. . . .

Yesterday I went back to modify the code and replaced the previous uint type with ulong. After burning, the result was displayed correctly. At the same time, I modified the display part based on the previous one, and displayed other information after pressing the button.

The modified main.cpp is as follows:

#include <msp430f149.h>
#include "inc/lcd_fyd12864.h"
#include "inc/uart.h"
#include "inc/gps.h"

uchar Welcom1[] = "Welcome to Embedded";
uchar Welcom2[] = "************";
uchar Welcom3[] = "Moderator: *******";
uchar Welcom4[] = "DIY Lab";

uchar latitude[] = "Lat: ";
uchar longitude[] = "Long: ";
uchar elevation[] = "Ele: ";
uchar currTime[]  = "Time: ";
const uchar *mode[4] = {"Fail", "Fail", "2D", "3D"};

float RxBuf[300], TxBuf[300],RxData[9];
float RxLen = 0;
float RxTempLen = 0;
uchar rev_flag = 0;
char dtbuf[50];
nmea_msg gpsx;
fly swt = 1;

void Show_GPS_Info1(nmea_msg gpsx)
{
  float tp;
  //Get the longitude string
  tp=gpsx.longitude;	   
  sprintf((char *)dtbuf,"Lon: %.5f %1c",tp/=100000,gpsx.ewhemi);
  DisplayString(0, 0, dtbuf);
  //Get the latitude string
  tp=gpsx.latitude;	   
  sprintf((char *)dtbuf,"Lat: %.5f %1c",tp/=100000,gpsx.nshemi);
  DisplayString(0, 1, dtbuf);
  //Get the height string
  tp=gpsx.altitude;	   
  sprintf((char *)dtbuf,"Alt: %.1fm",tp/=10);
  DisplayString(0, 2, dtbuf);
  //Get the speed string
  tp=gpsx.speed;	   
  sprintf((char *)dtbuf,"Speed:%.3fkm/h",tp/=1000);	
  DisplayString(0, 3, dtbuf);
}

void Show_GPS_Info2(nmea_msg gpsx)
{
  // Positioning status
  if(gpsx.fixmode<=3){	
    sprintf((char *)dtbuf,"Fix Mode: %s",mode[gpsx.fixmode]);	
    DisplayString(0, 0, dtbuf);	
  }
  //Number of satellites used for positioning
  sprintf((char *)dtbuf,"Val sat: %02d",gpsx.posslnum);
  DisplayString(0, 1, dtbuf);	
  //Number of visible satellites
  sprintf((char *)dtbuf,"Vis sat: %02d",gpsx.svnum%100);	
  DisplayString(0, 2, dtbuf);	
}

void Show_GPS_Info3(nmea_msg gpsx)
{
  // Display UTC date
  sprintf((char *)dtbuf,"Date:%04d/%02d/%02d",gpsx.utc.year,gpsx.utc.month,gpsx.utc.date);
  DisplayString(0, 0, dtbuf);
  //Display UTC time
  sprintf((char *)dtbuf,"Time:%02d:%02d:%02d",gpsx.utc.hour,gpsx.utc.min,gpsx.utc.sec);
  DisplayString(0, 1, dtbuf);
}


void main()
{
  volatile uint i;
  WDTCTL = WDTPW + WDTHOLD; // Turn off the watchdog

  BCSCTL1 &= ~XT2OFF;                       // XT2= HF XTAL
  do
  {
  IFG1 &= ~OFIFG;                           // Clear OSCFault flag
  for (i = 0xFF; i > 0; i--);               // Time for flag to set
  }
  while ((IFG1 & OFIFG));                   // OSCFault flag still set?
  //MCLK=8M,SCLK=1M
  BCSCTL2 |= SELM_2 + SELS + DIVS_3;        // MCLK= XT2 (safe)
  Delay_ms(500);
  UartInit();
  Delay_ms(500);
  
  P3DIR &= (~BIT2 + ~BIT3);
  
  LCDReset();
  DisplayString(1, 0, Welcom1);
  DisplayString(1, 1, Welcom2);
  DisplayString(1, 2, Welcom3);
  DisplayString(1, 3, Welcom4);
  Delay_ms(2000);
  LCDClear();
  Delay_ms(1000);
/*
  DisplayString(0, 0, latitude);
  DisplayString(0, 1, longitude);
  DisplayString(0, 2, elevation);
  DisplayString(0, 3, currTime);
*/  
  SendString("Lixiaoming\n");
  _EINT();
  while(1){
     //SendString("UART0 test!\n");
    if(!(P3IN & BIT2)){
      swt++;
      if(swt == 4)
        swt = 1;
    }
    if(rev_flag == 1){
      int i,len = 0;
      len = RxLen;
      for(i = 0; i < len; i++)
        TxBuf = RxBuf;
      RxLen = 0;
      TxBuf = 0;
      GPS_Analysis(&gpsx,TxBuf);
      switch(swt){
      case 1: LCDClear(); Show_GPS_Info1(gpsx); break;
      case 2: LCDClear(); Show_GPS_Info2(gpsx); break;
      default: LCDClear(); Show_GPS_Info3(gpsx); break;
      }
      SendString(TxBuf);
      rev_flag = 0;
    }
     //Delay_ms(1000);
  }
}

#pragma vector = UART0RX_VECTOR
__interrupt void UART0RxISR(void)
{
  //Receive data from the serial port
  while(!(IFG1 & UTXIFG0)); 
  RxBuf[RxTempLen++] = RXBUF0;
  while(RxBuf[RxTempLen-1] == '\n' && RxBuf[RxTempLen-2] == '\r' ){
	RxLen = RxTempLen;
	RxTempLen = 0;
	rev_flag = 1;
  }
}

#pragma vector = UART1RX_VECTOR
__interrupt void UART1RxISR(void)
{
  //Receive data from the serial port
  while(!(IFG2 & UTXIFG1)); 
  RxBuf[RxTempLen++] = RXBUF1;
  while(RxBuf[RxTempLen-1] == '\n'){
	RxLen = RxTempLen;
	RxTempLen = 0;
	rev_flag = 1;
  }
}

The results are as follows:

This post is from Microcontroller MCU
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list