1785 views|2 replies

3836

Posts

19

Resources
The OP
 

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

I was learning about MSP430 microcontrollers, so I decided to combine the GPS module with MSP430 and posted the code. I found that many materials I searched online require registration before downloading, and some require money. Only by using your own brain can you entertain yourself.

1. Test

I just got the ATK-NEO-6M GPS module. I can't believe that this nearly 100 yuan thing is only 3cm in size. I downloaded relevant information online before. The first quick test must be done with the help of a computer. There is a max232 module on the msp430 development board. I directly connected the TX of the GPS module to the TX of the max232, and the same for RX. Install u-center on the PC. u-center is a GPS evaluation software provided by ublox. It is very powerful and can conduct a comprehensive test on our ATK-NEO-6M GPS module. After installation, click the connect/disconnect button and select your serial port number. Generally, the test is to select the automatic configuration button, which is the magic-style button. After clicking, it will configure the baud rate by itself. If the communication is normal, the status bar in the lower right corner will display yellow. When the GPS module has been successfully located, the current basic information, such as longitude, latitude, etc., will be displayed on the interface. If you want to view the original information received, press F8 to display it. After I tested it, it worked normally and I could basically search for 9 satellite signals in the house.

2. Development

When I first got the GPS module, I felt that it would be very troublesome to develop it. Later, after experimenting, it was actually very simple because the information provided by the seller was sufficient for development. The analysis functions of the sentence segments were already provided, and we only needed to write the interface. Next, let's 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
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; //Minute
uchar sec; //Second
}nmea_utc_time;
//NMEA 0183 protocol parsed data storage structure
typedef struct
{
uchar svnum; //Number of visible satellites
nmea_slmsg slmsg[12]; //Up to 12 satellites
nmea_utc_time utc; //UTC time
int latitude; //Latitude is enlarged 100000 times, actually divided by 100000
uchar nshemi; //North/South latitude, N: North latitude; S: South latitude
int longitude; //Longitude is enlarged 100000 times, actually divided by 100000
uchar ewhemi; //East/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; //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, actual divided by 10. Unit: 0.1m uint speed ; // ground
speed, magnified 1000 times, actual divided by 10. Unit: 0.001 km/h } nmea_msg ; ///
... //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, unit is ms, not less than 200ms (5Hz) uint navrate; //Navigation rate (cycle), fixed to 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(uchar *buf,uchar*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_PosFunction
: Get the position of the cxth comma from buf
Parameter:
Return value: 0~0XFE, represents the offset of the comma position
0XFF, represents the absence of the cxth comma
****************************************/
uchar NMEA_Comma_Pos(uchar *buf,uchar cx)
{
uchar *p=buf;
while(cx)
{
if(*buf=='*'||*buf<' '||*buf>'z')return 0XFF;//If '*' or illegal characters are encountered, the cxth comma does not existif
(*buf==',')cx--;
buf++;
}
return buf-p;
}

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

/*******************************************
Function name: NMEA_Str2numFunction
: 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: converted value
********************************************/
int NMEA_Str2num(uchar *buf,uchar*dx)
{
uchar *p=buf;
int ires=0,fres=0;
uchar ilen=0,flen=0,i;
uchar mask=0;
int res;
while(1) //Get the length of integer and decimal
{
if(*p=='-'){mask|=0X02;p++;} //It is a negative numberif
(*p==','||(*p=='*'))break; //End
if(*p=='.'){mask|=0X01;p++;} //Encountered a decimal point
else if(*p>'9'||(*p<'0')) //There is an illegal character
{
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; //Take at most 5 decimal places
*dx=flen; //Number of 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_AnalysisFunction
: 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)
{
uchar *p,*p1,dx;
uchar len,i,j,slx=0;
uchar posx;
p=buf;
p1=(uchar*)strstr((const char *)p,"$GPGSV");
len=p1[7]-'0'; //Get the number of GPGSV lines
posx=NMEA_Comma_Pos(p1,3); //Get the total number of visible satellitesif
(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 the satellite numberelse
break;
posx=NMEA_Comma_Pos(p1,5+j*4);
if(posx!=0XFF)gpsx->slmsg[slx].eledeg=NMEA_Str2num(p1+posx,&dx);//Get the satellite elevation
angleelse break;
posx=NMEA_Comma_Pos(p1,6+j*4);
if(posx!=0XFF)gpsx->slmsg[slx].azideg=NMEA_Str2num(p1+posx,&dx);//Get satellite azimuthelse
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 ratioelsebreak
;
slx++;
}
p=p1+1;//Switch to the next GPGSV information
}
}

/*******************************************
Function name: NMEA_GPGGA_AnalysisFunction
: 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)
{
uchar *p1,dx;
uchar posx;
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_AnalysisFunction
: 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)
{
uchar *p1,dx;
uchar posx;
uchar i;
p1=(uchar*)strstr((const char *)buf,"$GPGSA");
posx=NMEA_Comma_Pos(p1,2); //Get the 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 factorif
(posx!=0XFF)gpsx->pdop=NMEA_Str2num(p1+posx,&dx);
posx=NMEA_Comma_Pos(p1,16); //Get HDOP position precision factorif
(posx!=0XFF)gpsx->hdop=NMEA_Str2num(p1+posx,&dx);
posx=NMEA_Comma_Pos(p1,17); //Get the VDOP position precision factor
if(posx!=0XFF)gpsx->vdop=NMEA_Str2num(p1+posx,&dx);
}

/*******************************************
Function name: NMEA_GPRMC_AnalysisFunction
: 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)
{
uchar *p1,dx;
uchar posx;
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 latitudeif
(posx!=0XFF)
{
temp=NMEA_Str2num(p1+posx,&dx);
gpsx->latitude=temp/NMEA_Pow(10,dx+2); //Get °
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 °
}
posx=NMEA_Comma_Pos(p1,4); //South or North latitudeif
(posx!=0XFF)gpsx->nshemi=*(p1+posx);
posx=NMEA_Comma_Pos(p1,5); //Get longitudeif
(posx!=0XFF)
{
temp=NMEA_Str2num(p1+posx,&dx);
gpsx->longitude=temp/NMEA_Pow(10,dx+2); //Get °
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 °
}
posx=NMEA_Comma_Pos(p1,6); //East or West
longitudeif(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_AnalysisFunction
: 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)
{
uchar *p1,dx;
uchar posx;
p1=(uchar*)strstr((const char *)buf,"$GPVTG");
posx=NMEA_Comma_Pos(p1,7); //Get ground speedif
(posx!=0XFF)
{
gpsx->speed=NMEA_Str2num(p1+posx,&dx);
if(dx<3)gpsx->speed*=NMEA_Pow(10,3-dx); //Ensure 1000 times expansion
}
}

/*******************************************
Function name: GPS_AnalysisFunction
: 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 analysisNMEA_GPGGA_Analysis
(gpsx,buf); //GPGGA analysisNMEA_GPGSA_Analysis
(gpsx,buf); //GPGSA analysisNMEA_GPRMC_Analysis(
gpsx,buf); //GPRMC analysisNMEA_GPVTG_Analysis
(gpsx,buf); //GPVTG analysis
}

/*******************************************
Function name: Ublox_CheckSumFunction
: GPS checksum calculation
Parameters: buf: data buffer first address; 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++)
{
*cka=*cka+buf;
*ckb=*ckb+*cka;
}
}

/*******************************************
Function name: Ublox_Cfg_TpFunction
: Configure the clock pulse output of UBLOX NEO-6
Parameters: interval: pulse interval
length: pulse width
status: pulse configuration: 1, high level valid; 0, off; -1, low level 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 length of the data area 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 is 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_RateFunction
: Configure the update rate of UBLOX NEO-6Parameters
: measrate: measurement time interval, in ms, not 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
directlycfg_rate->header=0X62B5; //cfg header
cfg_rate->id=0X0806; //cfg rate id
cfg_rate->dlength=6; //The length of the data area is 6 bytes.
cfg_rate->measrate=measrate;//Pulse interval, us
cfg_rate->navrate=1; //Navigation rate (cycle), fixed to 1
cfg_rate->timeref=reftime; //The 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 through 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(uchar 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 is set as 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 is set as 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.)

main.c

#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. There is a little problem with the time display because there is no conversion or other reasons. However, after a few days of hard work, the GPS was finally fixed. The next step is to write a Linux driver. . . Below is the result^-^.

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:

main.c

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 statusif 
  ( 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: (Because it is a window in the city, the signal is not very good)

C360_2013-11-25-21-18-53-971C360_2013-11-25-21-19-38-950C360_2013-11-25-21-19-57-439

The data received by the PC serial port is as follows:

The data received by the PC serial port is as follows:

$GPRMC,134856.00,A,2232.50576,N,11354.64802,E,0.084,,251113,,,A*7E
$GPGSV,3,2,09,22,75,191,27,25,58,074,22,29,08,122,16,31,48,276,19*76
gpsx->utc temp: 134857
gpsx->latitude temp: 223250578
gpsx->longitude temp: 1135464798
gpsx->utc.date temp: 251113
$GPRMC,134857.00,A,2232.50578,N,11354.64798,E,0.173,,251113,,,A*74
$GPGSV,3,2,09,22,75,191,27,25,58,074,23,29,08,122,15,31,48,276,20*7E
gpsx->utc temp: 134858
gpsx->latitude temp: 223250575
gpsx->longitude temp: 1135464785
gpsx->utc.date temp: 251113
$GPRMC,134858.00,A,2232.50575,N,11354.64785,E,0.140,,251113,,,A*7A
$GPGSV,3,2,09,22,75,191,27,25,58,074,23,29,08,122,15,31,48,276,19*74
gpsx->utc temp: 134859
gpsx->latitude temp: 223250575
gpsx->longitude temp: 1135464782
gpsx->utc.date temp: 251113
$GPRMC,134859.00,A,2232.50575,N,11354.64782,E,0.130,,251113,,,A*7B
$GPGSV,3,2,09,22,75,191,27,25,58,074,23,29,08,122,15,31,48,276,20*7E
gpsx->utc temp: 134900
gpsx->latitude temp: 223250570
gpsx->longitude temp: 1135464784
gpsx->utc.date temp: 251113
$GPRMC,134900.00,A,2232.50570,N,11354.64784,E,0.112,,251113,,,A*75

This post is from Microcontroller MCU

Latest reply

This module may have many errors, I hope you can take it seriously!!!!   Details Published on 2020-9-15 19:09
 

2618

Posts

0

Resources
2
 

Thanks for sharing, it's good and can be used as a reference.

This post is from Microcontroller MCU
 
 

1

Posts

4

Resources
3
 

This module may have many errors, I hope you can take it seriously!!!!

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