gps.c
上传用户:yj_qqy
上传日期:2017-01-28
资源大小:2911k
文件大小:27k
- #define GPS_GLOBALS
- #include <includes.h>
- #if GPS_MODULE == DEF_ENABLED
- #define MAXFIELD 25 // maximum field length
- static OS_STK GPS_TaskStk[GPS_TASK_STK_SIZE];
- static OS_EVENT *GPS_Sem;
- NP_STATE m_nState; // Current state protocol parser is in
- INT8U m_btChecksum; // Calculated NMEA sentence checksum
- INT8U m_btReceivedChecksum; // Received NMEA sentence checksum (if exists)
- INT16U m_wIndex; // Index used for command and data
- INT8U m_pCommand[NP_MAX_CMD_LEN]; // NMEA command
- INT8U m_pData[NP_MAX_DATA_LEN]; // NMEA data
- static void GPS_InitOS(void);
- static void GPS_Task(void *p_arg);
- /*
- *********************************************************************************************************
- * INITIALIZE GPS
- *********************************************************************************************************
- */
- void GPS_Init (void)
- {
- m_nState = NP_STATE_SOM;
- m_dwCommandCount = 0;
- GPDataReset();
- GPS_InitOS();
- GPS_InitTarget(); /* Initialize target specific code */
- }
- /*
- *********************************************************************************************************
- * INITIALIZE THE uC/OS-View TASK AND OS OBJECTS
- *********************************************************************************************************
- */
- static void GPS_InitOS (void)
- {
- #if OS_TASK_NAME_SIZE > 7 || OS_EVENT_NAME_SIZE > 7
- INT8U err;
- #endif
- GPS_Sem = OSSemCreate(0);
- #if OS_EVENT_NAME_SIZE > 17
- OSEventNameSet(GPS_Sem, (INT8U *)"GPS Signal", &err);
- #else
- #if OS_EVENT_NAME_SIZE > 7
- OSEventNameSet(GPS_Sem, (INT8U *)"GPS", &err);
- #endif
- #endif
- (void)OSTaskCreateExt(GPS_Task,
- (void *)0, /* No arguments passed to OSView_Task() */
- &GPS_TaskStk[GPS_TASK_STK_SIZE - 1], /* Set Top-Of-Stack */
- GPS_TASK_PRIO, /* Lowest priority level */
- GPS_TASK_PRIO,
- &GPS_TaskStk[0], /* Set Bottom-Of-Stack */
- GPS_TASK_STK_SIZE,
- (void *)0, /* No TCB extension */
- OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear stack */
- #if OS_TASK_NAME_SIZE > 10
- OSTaskNameSet(GPS_TASK_PRIO, (INT8U *)"GPS Task", &err);
- #else
- #if OS_TASK_NAME_SIZE > 7
- OSTaskNameSet(GPS_TASK_PRIO, (INT8U *)"GPS", &err);
- #endif
- #endif
- }
- /*
- *********************************************************************************************************
- * GPS TASK
- *********************************************************************************************************
- */
- static void GPS_Task (void *p_arg)
- {
- //INT8U err;
- //INT8U s[100];
- while(1) {
- //(void)OSSemPend(GPS_Sem, 0, &err);
- OSTimeDlyHMSM(0, 0, 0, 500);
- //sprintf((char *)s, "n时:%2d 分:%2d 秒:%2d 纬度:%f 经度:%f 高度:%fn", GPGGAData.Hour, GPGGAData.Minute, GPGGAData.Second, GPGGAData.Latitude, GPGGAData.Longitude, GPGGAData.Altitude);
- //OSView_TxStr(s, 1);
- }
- }
- /*
- *********************************************************************************************************
- * Rx Handler
- *
- * Description: This routine is called from the Rx interrupt service handler.
- *********************************************************************************************************
- */
- void GPS_RxHandler (INT8U rx_data)
- {
- ProcessNMEA(rx_data);
- }
- /*
- *********************************************************************************************************
- * Tx Handler
- *
- * Description: This routine is called from the transmitter buffer empty interrupt service handler.
- * It will send out the next byte in the buffer.
- *
- * Returns: none
- *********************************************************************************************************
- */
- void GPS_TxHandler (void)
- {
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Reset: Reset all NMEA data to start-up default values.
- ///////////////////////////////////////////////////////////////////////////////
- void GPDataReset(void)
- {
- int i;
- //
- // GPGGA Data
- //
- GPGGAData.Hour = 0; //
- GPGGAData.Minute = 0; //
- GPGGAData.Second = 0; //
- GPGGAData.Latitude = 0.0; // < 0 = South, > 0 = North
- GPGGAData.Longitude = 0.0; // < 0 = West, > 0 = East
- GPGGAData.GPSQuality = 0; // 0 = fix not available, 1 = GPS sps mode, 2 = Differential GPS, SPS mode, fix valid, 3 = GPS PPS mode, fix valid
- GPGGAData.NumOfSatsInUse = 0; //
- GPGGAData.HDOP = 0.0; //
- GPGGAData.Altitude = 0.0; // Altitude: mean-sea-level (geoid) meters
- GPGGAData.Count = 0; //
- GPGGAData.OldVSpeedSeconds = 0; //
- GPGGAData.OldVSpeedAlt = 0.0; //
- GPGGAData.VertSpeed = 0.0; //
- //
- // GPGSA
- //
- GPGSAData.Mode = 'M'; // M = manual, A = automatic 2D/3D
- GPGSAData.FixMode = 1; // 1 = fix not available, 2 = 2D, 3 = 3D
- for(i = 0; i < NP_MAX_CHAN; i++)
- {
- GPGSAData.SatsInSolution[i] = 0; // ID of sats in solution
- }
- GPGSAData.PDOP = 0.0; //
- GPGSAData.HDOP = 0.0; //
- GPGSAData.VDOP = 0.0; //
- GPGSAData.Count = 0; //
- //
- // GPGSV
- //
- GPGSVData.TotalNumOfMsg = 0; //
- GPGSVData.TotalNumSatsInView = 0; //
- for(i = 0; i < NP_MAX_CHAN; i++)
- {
- GPGSVData.SatInfo[i].Azimuth = 0;
- GPGSVData.SatInfo[i].Elevation = 0;
- GPGSVData.SatInfo[i].PRN = 0;
- GPGSVData.SatInfo[i].SignalQuality = 0;
- GPGSVData.SatInfo[i].UsedInSolution = FALSE;
- }
- GPGSVData.Count = 0;
- //
- // GPRMB
- //
- GPRMBData.DataStatus = 'V'; // A = data valid, V = navigation receiver warning
- GPRMBData.CrosstrackError = 0.0; // nautical miles
- GPRMBData.DirectionToSteer = '?'; // L/R
- GPRMBData.OriginWaypoint[0] = ' '; // Origin Waypoint ID
- GPRMBData.DestWaypoint[0] = ' '; // Destination waypoint ID
- GPRMBData.DestLatitude = 0.0; // destination waypoint latitude
- GPRMBData.DestLongitude = 0.0; // destination waypoint longitude
- GPRMBData.RangeToDest = 0.0; // Range to destination nautical mi
- GPRMBData.BearingToDest = 0.0; // Bearing to destination, degrees true
- GPRMBData.DestClosingVelocity = 0.0; // Destination closing velocity, knots
- GPRMBData.ArrivalStatus = 'V'; // A = arrival circle entered, V = not entered
- GPRMBData.Count = 0; //
- //
- // GPRMC
- //
- GPRMCData.Hour = 0; //
- GPRMCData.Minute = 0; //
- GPRMCData.Second = 0; //
- GPRMCData.DataValid = 'V'; // A = Data valid, V = navigation rx warning
- GPRMCData.Latitude = 0.0; // current latitude
- GPRMCData.Longitude = 0.0; // current longitude
- GPRMCData.GroundSpeed = 0.0; // speed over ground, knots
- GPRMCData.Course = 0.0; // course over ground, degrees true
- GPRMCData.Day = 1; //
- GPRMCData.Month = 1; //
- GPRMCData.Year = 2000; //
- GPRMCData.MagVar = 0.0; // magnitic variation, degrees East(+)/West(-)
- GPRMCData.Count = 0; //
- //
- // GPZDA
- //
- GPZDAData.Hour = 0; //
- GPZDAData.Minute = 0; //
- GPZDAData.Second = 0; //
- GPZDAData.Day = 1; // 1 - 31
- GPZDAData.Month = 1; // 1 - 12
- GPZDAData.Year = 2000; //
- GPZDAData.LocalZoneHour = 0; // 0 to +/- 13
- GPZDAData.LocalZoneMinute = 0; // 0 - 59
- GPZDAData.Count = 0; //
- }
- ///////////////////////////////////////////////////////////////////////////////
- // ProcessNMEA: This method is the main state machine which processes individual
- // bytes from the buffer and parses a NMEA sentence. A typical
- // sentence is constructed as:
- //
- // $CMD,DDDD,DDDD,....DD*CS<CR><LF>
- //
- // Where:
- // '$' HEX 24 Start of sentence
- // 'CMD' Address/NMEA command
- // ',DDDD' Zero or more data fields
- // '*CS' Checksum field
- // <CR><LF> Hex 0d 0A End of sentence
- //
- // When a valid sentence is received, this function sends the
- // NMEA command and data to the ProcessCommand method for
- // individual field parsing.
- //
- // NOTE:
- //
- ///////////////////////////////////////////////////////////////////////////////
- void ProcessNMEA(INT8U btData)
- {
- switch(m_nState)
- {
- ///////////////////////////////////////////////////////////////////////
- // Search for start of message '$'
- case NP_STATE_SOM :
- if(btData == '$')
- {
- m_btChecksum = 0; // reset checksum
- m_wIndex = 0; // reset index
- m_nState = NP_STATE_CMD;
- }
- break;
- ///////////////////////////////////////////////////////////////////////
- // Retrieve command (NMEA Address)
- case NP_STATE_CMD :
- if(btData != ',' && btData != '*')
- {
- m_pCommand[m_wIndex++] = btData;
- m_btChecksum ^= btData;
- // Check for command overflow
- if(m_wIndex >= NP_MAX_CMD_LEN)
- {
- m_nState = NP_STATE_SOM;
- }
- }
- else
- {
- m_pCommand[m_wIndex] = ' '; // terminate command
- m_btChecksum ^= btData;
- m_wIndex = 0;
- m_nState = NP_STATE_DATA; // goto get data state
- }
- break;
- ///////////////////////////////////////////////////////////////////////
- // Store data and check for end of sentence or checksum flag
- case NP_STATE_DATA :
- if(btData == '*') // checksum flag?
- {
- m_pData[m_wIndex] = ' ';
- m_nState = NP_STATE_CHECKSUM_1;
- }
- else // no checksum flag, store data
- {
- //
- // Check for end of sentence with no checksum
- //
- if(btData == 'r')
- {
- m_pData[m_wIndex] = ' ';
- ProcessCommand(m_pCommand, m_pData);
- m_nState = NP_STATE_SOM;
- return;
- }
- //
- // Store data and calculate checksum
- //
- m_btChecksum ^= btData;
- m_pData[m_wIndex] = btData;
- if(++m_wIndex >= NP_MAX_DATA_LEN) // Check for buffer overflow
- {
- m_nState = NP_STATE_SOM;
- }
- }
- break;
- ///////////////////////////////////////////////////////////////////////
- case NP_STATE_CHECKSUM_1 :
- if( (btData - '0') <= 9)
- {
- m_btReceivedChecksum = (btData - '0') << 4;
- }
- else
- {
- m_btReceivedChecksum = (btData - 'A' + 10) << 4;
- }
- m_nState = NP_STATE_CHECKSUM_2;
- break;
- ///////////////////////////////////////////////////////////////////////
- case NP_STATE_CHECKSUM_2 :
- if( (btData - '0') <= 9)
- {
- m_btReceivedChecksum |= (btData - '0');
- }
- else
- {
- m_btReceivedChecksum |= (btData - 'A' + 10);
- }
- if(m_btChecksum == m_btReceivedChecksum)
- {
- ProcessCommand(m_pCommand, m_pData);
- }
- m_nState = NP_STATE_SOM;
- break;
- ///////////////////////////////////////////////////////////////////////
- default : m_nState = NP_STATE_SOM;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Process NMEA sentence - Use the NMEA address (*pCommand) and call the
- // appropriate sentense data prossor.
- ///////////////////////////////////////////////////////////////////////////////
- BOOLEAN ProcessCommand(INT8U *pCommand, INT8U *pData)
- {
- //
- // GPGGA
- //
- if( strcmp((char *)pCommand, "GPGGA") == NULL )
- {
- ProcessGPGGA(pData);
- OSSemPost(GPS_Sem);
- }
- //
- // GPGSA
- //
- else if( strcmp((char *)pCommand, "GPGSA") == NULL )
- {
- ProcessGPGSA(pData);
- }
- //
- // GPGSV
- //
- else if( strcmp((char *)pCommand, "GPGSV") == NULL )
- {
- ProcessGPGSV(pData);
- }
- //
- // GPRMB
- //
- else if( strcmp((char *)pCommand, "GPRMB") == NULL )
- {
- ProcessGPRMB(pData);
- }
- //
- // GPRMC
- //
- else if( strcmp((char *)pCommand, "GPRMC") == NULL )
- {
- ProcessGPRMC(pData);
- }
- //
- // GPZDA
- //
- else if( strcmp((char *)pCommand, "GPZDA") == NULL )
- {
- ProcessGPZDA(pData);
- }
- m_dwCommandCount++;
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Check to see if supplied satellite ID is used in the GPS solution.
- // Retruned: BOOL - TRUE if satellate ID is used in solution
- // FALSE if not used in solution.
- ///////////////////////////////////////////////////////////////////////////////
- BOOLEAN IsSatUsedInSolution(INT16U wSatID)
- {
- INT32S i;
- if(wSatID == 0) return FALSE;
- for(i = 0; i < 12; i++)
- {
- if(wSatID == GPGSAData.SatsInSolution[i])
- {
- return TRUE;
- }
- }
- return FALSE;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name: GetField
- //
- // Description: This function will get the specified field in a NMEA string.
- //
- // Entry: INT8U *pData - Pointer to NMEA string
- // INT8U *pField - pointer to returned field
- // INT32S nfieldNum - Field offset to get
- // INT32S nMaxFieldLen - Maximum of bytes pFiled can handle
- ///////////////////////////////////////////////////////////////////////////////
- BOOLEAN GetField(INT8U *pData, INT8U *pField, INT32S nFieldNum, INT32S nMaxFieldLen)
- {
- INT32S i, i2, nField;
- //
- // Validate params
- //
- if(pData == NULL || pField == NULL || nMaxFieldLen <= 0)
- {
- return FALSE;
- }
- //
- // Go to the beginning of the selected field
- //
- i = 0;
- nField = 0;
- while(nField != nFieldNum && pData[i])
- {
- if(pData[i] == ',')
- {
- nField++;
- }
- i++;
- if(pData[i] == NULL)
- {
- pField[0] = ' ';
- return FALSE;
- }
- }
- if(pData[i] == ',' || pData[i] == '*')
- {
- pField[0] = ' ';
- return FALSE;
- }
- //
- // copy field from pData to Field
- //
- i2 = 0;
- while(pData[i] != ',' && pData[i] != '*' && pData[i])
- {
- pField[i2] = pData[i];
- i2++; i++;
- //
- // check if field is too big to fit on passed parameter. If it is,
- // crop returned field to its max length.
- //
- if(i2 >= nMaxFieldLen)
- {
- i2 = nMaxFieldLen-1;
- break;
- }
- }
- pField[i2] = ' ';
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- void ProcessGPZDA(INT8U *pData)
- {
- char pBuff[10];
- INT8U pField[MAXFIELD];
- //
- // Time
- //
- if(GetField(pData, pField, 0, MAXFIELD))
- {
- // Hour
- pBuff[0] = pField[0];
- pBuff[1] = pField[1];
- pBuff[2] = ' ';
- GPZDAData.Hour = atoi(pBuff);
- // minute
- pBuff[0] = pField[2];
- pBuff[1] = pField[3];
- pBuff[2] = ' ';
- GPZDAData.Minute = atoi(pBuff);
- // Second
- pBuff[0] = pField[4];
- pBuff[1] = pField[5];
- pBuff[2] = ' ';
- GPZDAData.Second = atoi(pBuff);
- }
- //
- // Day
- //
- if(GetField(pData, pField, 1, MAXFIELD))
- {
- GPZDAData.Day = atoi((char *)pField);
- }
- else
- {
- GPZDAData.Day = 1;
- }
- //
- // Month
- //
- if(GetField(pData, pField, 2, MAXFIELD))
- {
- GPZDAData.Month = atoi((char *)pField);
- }
- else
- {
- GPZDAData.Month = 1;
- }
- //
- // Year
- //
- if(GetField(pData, pField, 3, MAXFIELD))
- {
- GPZDAData.Year = atoi((char *)pField);
- }
- else
- {
- GPZDAData.Year = 1;
- }
- //
- // Local zone hour
- //
- if(GetField(pData, pField, 4, MAXFIELD))
- {
- GPZDAData.LocalZoneHour = atoi((char *)pField);
- }
- else
- {
- GPZDAData.LocalZoneHour = 0;
- }
- //
- // Local zone hour
- //
- if(GetField(pData, pField, 5, MAXFIELD))
- {
- GPZDAData.LocalZoneMinute = atoi((char *)pField);
- }
- else
- {
- GPZDAData.LocalZoneMinute = 0;
- }
- GPZDAData.Count++;
- }
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- void ProcessGPRMC(INT8U *pData)
- {
- char pBuff[10];
- INT8U pField[MAXFIELD];
- //
- // Time
- //
- if(GetField(pData, pField, 0, MAXFIELD))
- {
- // Hour
- pBuff[0] = pField[0];
- pBuff[1] = pField[1];
- pBuff[2] = ' ';
- GPRMCData.Hour = atoi(pBuff);
- // minute
- pBuff[0] = pField[2];
- pBuff[1] = pField[3];
- pBuff[2] = ' ';
- GPRMCData.Minute = atoi(pBuff);
- // Second
- pBuff[0] = pField[4];
- pBuff[1] = pField[5];
- pBuff[2] = ' ';
- GPRMCData.Second = atoi(pBuff);
- }
- //
- // Data valid
- //
- if(GetField(pData, pField, 1, MAXFIELD))
- {
- GPRMCData.DataValid = pField[0];
- }
- else
- {
- GPRMCData.DataValid = 'V';
- }
- //
- // latitude
- //
- if(GetField(pData, pField, 2, MAXFIELD))
- {
- GPRMCData.Latitude = atof((char *)pField+2) / 60.0;
- pField[2] = ' ';
- GPRMCData.Latitude += atof((char *)pField);
- }
- if(GetField(pData, pField, 3, MAXFIELD))
- {
- if(pField[0] == 'S')
- {
- GPRMCData.Latitude = -GPRMCData.Latitude;
- }
- }
- //
- // Longitude
- //
- if(GetField(pData, pField, 4, MAXFIELD))
- {
- GPRMCData.Longitude = atof((char *)pField+3) / 60.0;
- pField[3] = ' ';
- GPRMCData.Longitude += atof((char *)pField);
- }
- if(GetField(pData, pField, 5, MAXFIELD))
- {
- if(pField[0] == 'W')
- {
- GPRMCData.Longitude = -GPRMCData.Longitude;
- }
- }
- //
- // Ground speed
- //
- if(GetField(pData, pField, 6, MAXFIELD))
- {
- GPRMCData.GroundSpeed = atof((char *)pField);
- }
- else
- {
- GPRMCData.GroundSpeed = 0.0;
- }
- //
- // course over ground, degrees true
- //
- if(GetField(pData, pField, 7, MAXFIELD))
- {
- GPRMCData.Course = atof((char *)pField);
- }
- else
- {
- GPRMCData.Course = 0.0;
- }
- //
- // Date
- //
- if(GetField(pData, pField, 8, MAXFIELD))
- {
- // Day
- pBuff[0] = pField[0];
- pBuff[1] = pField[1];
- pBuff[2] = ' ';
- GPRMCData.Day = atoi(pBuff);
- // Month
- pBuff[0] = pField[2];
- pBuff[1] = pField[3];
- pBuff[2] = ' ';
- GPRMCData.Month = atoi(pBuff);
- // Year (Only two digits. I wonder why?)
- pBuff[0] = pField[4];
- pBuff[1] = pField[5];
- pBuff[2] = ' ';
- GPRMCData.Year = atoi(pBuff);
- GPRMCData.Year += 2000; // make 4 digit date -- What assumptions should be made here?
- }
- //
- // course over ground, degrees true
- //
- if(GetField(pData, pField, 9, MAXFIELD))
- {
- GPRMCData.MagVar = atof((char *)pField);
- }
- else
- {
- GPRMCData.MagVar = 0.0;
- }
- if(GetField(pData, pField, 10, MAXFIELD))
- {
- if(pField[0] == 'W')
- {
- GPRMCData.MagVar = -GPRMCData.MagVar;
- }
- }
- GPRMCData.Count++;
- }
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- void ProcessGPRMB(INT8U *pData)
- {
- INT8U pField[MAXFIELD];
- //
- // Data status
- //
- if(GetField(pData, pField, 0, MAXFIELD))
- {
- GPRMBData.DataStatus = pField[0];
- }
- else
- {
- GPRMBData.DataStatus = 'V';
- }
- //
- // Cross track error
- //
- if(GetField(pData, pField, 1, MAXFIELD))
- {
- GPRMBData.CrosstrackError = atof((char *)pField);
- }
- else
- {
- GPRMBData.CrosstrackError = 0.0;
- }
- //
- // Direction to steer
- //
- if(GetField(pData, pField, 2, MAXFIELD))
- {
- GPRMBData.DirectionToSteer = pField[0];
- }
- else
- {
- GPRMBData.DirectionToSteer = '?';
- }
- //
- // Orgin waypoint ID
- //
- if(GetField(pData, pField, 3, MAXFIELD))
- {
- strcpy(GPRMBData.OriginWaypoint, (char *)pField);
- }
- else
- {
- GPRMBData.OriginWaypoint[0] = ' ';
- }
- //
- // Destination waypoint ID
- //
- if(GetField(pData, pField, 4, MAXFIELD))
- {
- strcpy(GPRMBData.DestWaypoint, (char *)pField);
- }
- else
- {
- GPRMBData.DestWaypoint[0] = ' ';
- }
- //
- // Destination latitude
- //
- if(GetField(pData, pField, 5, MAXFIELD))
- {
- GPRMBData.DestLatitude = atof((char *)pField+2) / 60.0;
- pField[2] = ' ';
- GPRMBData.DestLatitude += atof((char *)pField);
- }
- if(GetField(pData, pField, 6, MAXFIELD))
- {
- if(pField[0] == 'S')
- {
- GPRMBData.DestLatitude = -GPRMBData.DestLatitude;
- }
- }
- //
- // Destination Longitude
- //
- if(GetField(pData, pField, 7, MAXFIELD))
- {
- GPRMBData.DestLongitude = atof((char *)pField+3) / 60.0;
- pField[3] = ' ';
- GPRMBData.DestLongitude += atof((char *)pField);
- }
- if(GetField(pData, pField, 8, MAXFIELD))
- {
- if(pField[0] == 'W')
- {
- GPRMBData.DestLongitude = -GPRMBData.DestLongitude;
- }
- }
- //
- // Range to destination nautical mi
- //
- if(GetField(pData, pField, 9, MAXFIELD))
- {
- GPRMBData.RangeToDest = atof((char *)pField);
- }
- else
- {
- GPRMBData.CrosstrackError = 0.0;
- }
- //
- // Bearing to destination degrees true
- //
- if(GetField(pData, pField, 10, MAXFIELD))
- {
- GPRMBData.BearingToDest = atof((char *)pField);
- }
- else
- {
- GPRMBData.BearingToDest = 0.0;
- }
- //
- // Closing velocity
- //
- if(GetField(pData, pField, 11, MAXFIELD))
- {
- GPRMBData.DestClosingVelocity = atof((char *)pField);
- }
- else
- {
- GPRMBData.DestClosingVelocity = 0.0;
- }
- //
- // Arrival status
- //
- if(GetField(pData, pField, 12, MAXFIELD))
- {
- GPRMBData.ArrivalStatus = pField[0];
- }
- else
- {
- GPRMBData.DestClosingVelocity = 'V';
- }
- GPRMBData.Count++;
- }
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- void ProcessGPGSV(INT8U *pData)
- {
- INT32S i, nTotalNumOfMsg = 0, nMsgNum = 0;
- INT8U pField[MAXFIELD];
- //
- // Total number of messages
- //
- if(GetField(pData, pField, 0, MAXFIELD))
- {
- nTotalNumOfMsg = atoi((char *)pField);
- //
- // Make sure that the nTotalNumOfMsg is valid. This is used to
- // calculate indexes into an array. I've seen corrept NMEA strings
- // with no checksum set this to large values.
- //
- if(nTotalNumOfMsg > 9 || nTotalNumOfMsg < 0) return;
- }
- if(nTotalNumOfMsg < 1 || nTotalNumOfMsg*4 >= NP_MAX_CHAN)
- {
- return;
- }
- //
- // message number
- //
- if(GetField(pData, pField, 1, MAXFIELD))
- {
- nMsgNum = atoi((char *)pField);
- //
- // Make sure that the message number is valid. This is used to
- // calculate indexes into an array
- //
- if(nMsgNum > 9 || nMsgNum < 0) return;
- }
- //
- // Total satellites in view
- //
- if(GetField(pData, pField, 2, MAXFIELD))
- {
- GPGSVData.TotalNumSatsInView = atoi((char *)pField);
- }
- //
- // Satelite data
- //
- for(i = 0; i < 4; i++)
- {
- // Satellite ID
- if(GetField(pData, pField, 3 + 4*i, MAXFIELD))
- {
- GPGSVData.SatInfo[i+(nMsgNum-1)*4].PRN = atoi((char *)pField);
- }
- else
- {
- GPGSVData.SatInfo[i+(nMsgNum-1)*4].PRN = 0;
- }
- // Elevarion
- if(GetField(pData, pField, 4 + 4*i, MAXFIELD))
- {
- GPGSVData.SatInfo[i+(nMsgNum-1)*4].Elevation = atoi((char *)pField);
- }
- else
- {
- GPGSVData.SatInfo[i+(nMsgNum-1)*4].Elevation = 0;
- }
- // Azimuth
- if(GetField(pData, pField, 5 + 4*i, MAXFIELD))
- {
- GPGSVData.SatInfo[i+(nMsgNum-1)*4].Azimuth = atoi((char *)pField);
- }
- else
- {
- GPGSVData.SatInfo[i+(nMsgNum-1)*4].Azimuth = 0;
- }
- // SNR
- if(GetField(pData, pField, 6 + 4*i, MAXFIELD))
- {
- GPGSVData.SatInfo[i+(nMsgNum-1)*4].SignalQuality = atoi((char *)pField);
- }
- else
- {
- GPGSVData.SatInfo[i+(nMsgNum-1)*4].SignalQuality = 0;
- }
- //
- // Update "used in solution" (m_bUsedInSolution) flag. This is base
- // on the GSA message and is an added convenience for post processing
- //
- GPGSVData.SatInfo[i+(nMsgNum-1)*4].UsedInSolution = IsSatUsedInSolution(GPGSVData.SatInfo[i+(nMsgNum-1)*4].PRN);
- }
- GPGSVData.Count++;
- }
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- void ProcessGPGSA(INT8U *pData)
- {
- INT8U pField[MAXFIELD];
- char pBuff[10];
- INT32S i;
- //
- // Mode
- //
- if(GetField(pData, pField, 0, MAXFIELD))
- {
- GPGSAData.Mode = pField[0];
- }
- //
- // Fix Mode
- //
- if(GetField(pData, pField, 1, MAXFIELD))
- {
- GPGSAData.FixMode = pField[0] - '0';
- }
- //
- // Active satellites
- //
- for(i = 0; i < 12; i++)
- {
- if(GetField(pData, pField, 2 + i, MAXFIELD))
- {
- pBuff[0] = pField[0];
- pBuff[1] = pField[1];
- pBuff[2] = ' ';
- GPGSAData.SatsInSolution[i] = atoi(pBuff);
- }
- else
- {
- GPGSAData.SatsInSolution[i] = 0;
- }
- }
- //
- // PDOP
- //
- if(GetField(pData, pField, 14, MAXFIELD))
- {
- GPGSAData.PDOP = atof((char *)pField);
- }
- else
- {
- GPGSAData.PDOP = 0.0;
- }
- //
- // HDOP
- //
- if(GetField(pData, pField, 15, MAXFIELD))
- {
- GPGSAData.HDOP = atof((char *)pField);
- }
- else
- {
- GPGSAData.HDOP = 0.0;
- }
- //
- // VDOP
- //
- if(GetField(pData, pField, 16, MAXFIELD))
- {
- GPGSAData.VDOP = atof((char *)pField);
- }
- else
- {
- GPGSAData.VDOP = 0.0;
- }
- GPGSAData.Count++;
- }
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- void ProcessGPGGA(INT8U *pData)
- {
- INT8U pField[MAXFIELD];
- char pBuff[10];
- INT32S nSeconds;
- //
- // Time
- //
- if(GetField(pData, pField, 0, MAXFIELD))
- {
- // Hour
- pBuff[0] = pField[0];
- pBuff[1] = pField[1];
- pBuff[2] = ' ';
- GPGGAData.Hour = atoi(pBuff);
- // minute
- pBuff[0] = pField[2];
- pBuff[1] = pField[3];
- pBuff[2] = ' ';
- GPGGAData.Minute = atoi(pBuff);
- // Second
- pBuff[0] = pField[4];
- pBuff[1] = pField[5];
- pBuff[2] = ' ';
- GPGGAData.Second = atoi(pBuff);
- }
- //
- // Latitude
- //
- if(GetField(pData, pField, 1, MAXFIELD))
- {
- GPGGAData.Latitude = atof((char *)pField+2) / 60.0;
- pField[2] = ' ';
- GPGGAData.Latitude += atof((char *)pField);
- }
- if(GetField(pData, pField, 2, MAXFIELD))
- {
- if(pField[0] == 'S')
- {
- GPGGAData.Latitude = -GPGGAData.Latitude;
- }
- }
- //
- // Longitude
- //
- if(GetField(pData, pField, 3, MAXFIELD))
- {
- GPGGAData.Longitude = atof((char *)pField+3) / 60.0;
- pField[3] = ' ';
- GPGGAData.Longitude += atof((char *)pField);
- }
- if(GetField(pData, pField, 4, MAXFIELD))
- {
- if(pField[0] == 'W')
- {
- GPGGAData.Longitude = -GPGGAData.Longitude;
- }
- }
- //
- // GPS quality
- //
- if(GetField(pData, pField, 5, MAXFIELD))
- {
- GPGGAData.GPSQuality = pField[0] - '0';
- }
- //
- // Satellites in use
- //
- if(GetField(pData, pField, 6, MAXFIELD))
- {
- pBuff[0] = pField[0];
- pBuff[1] = pField[1];
- pBuff[2] = ' ';
- GPGGAData.NumOfSatsInUse = atoi(pBuff);
- }
- //
- // HDOP
- //
- if(GetField(pData, pField, 7, MAXFIELD))
- {
- GPGGAData.HDOP = atof((char *)pField);
- }
-
- //
- // Altitude
- //
- if(GetField(pData, pField, 8, MAXFIELD))
- {
- GPGGAData.Altitude = atof((char *)pField);
- }
- //
- // Durive vertical speed (bonus)
- //
- nSeconds = (INT32S)GPGGAData.Minute * 60 + (INT32S)GPGGAData.Second;
- if(nSeconds > GPGGAData.OldVSpeedSeconds)
- {
- double dDiff = (double)(GPGGAData.OldVSpeedSeconds-nSeconds);
- double dVal = dDiff/60.0;
- if(dVal != 0.0)
- {
- GPGGAData.VertSpeed = (GPGGAData.OldVSpeedAlt - GPGGAData.Altitude) / dVal;
- }
- }
- GPGGAData.OldVSpeedAlt = GPGGAData.Altitude;
- GPGGAData.OldVSpeedSeconds = nSeconds;
- GPGGAData.Count++;
- }
- #endif