📄 nmea.c
字号:
for (i = 0; i < 11; i++) { pNmeaGSVData->PRNs[i] = TrackingPRNs[i].PRN; }/* if (gSimulate) { pNmeaGSVData->PRNs[0] = 7; pNmeaGSVData->PRNs[1] = 9; pNmeaGSVData->PRNs[2] = 24; pNmeaGSVData->PRNs[3] = 4; } */ pNmeaGSVData->PDOP = GetPDOP (); /* ( float )2.5; */ pNmeaGSVData->HDOP = GetHDOP (); /* ( float )1.3; */ pNmeaGSVData->VDOP = GetVDOP (); /* ( float )2.1; */ return NMEA_SUCCESS;}/** * GSA - GPS DOP and active satellites **//** * GSA - GPS DOP and active satellites. This sentence provides details * on the nature of the fix. It includes the numbers of the * satellites being used in the current solution and the DOP. DOP * (dilution of precision) is an indication of the effect of satellite * geometry on the accuracy of the fix. It is a unitless number where * smaller is better. For 3D fixes using 4 satellites a 1.0 would be * considered to be a perfect number, however for overdetermined * solutions it is possible to see numbers below 1.0. * * There are differences in the way the PRN's are presented which * can effect the ability of some programs to display this data. For * example, in the example shown below there are 5 satellites in the * solution and the null fields are scattered indicating that the * almanac would show satellites in the null positions that are not * being used as part of this solution. Other receivers might output * all of the satellites used at the beginning of the sentence with * the null field all stacked up at the end. This difference accounts * for some satellite display programs not always being able to * display the satellites being tracked. Some units may show all * satellites that have ephemeris data without regard to their use as * part of the solution but this is non-standard. * * $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39 * * Where: * GSA Satellite status * A Auto selection of 2D or 3D fix (M = manual) * 3 3D fix - values include: 1 = no fix * 2 = 2D fix * 3 = 3D fix * 04,05... PRNs of satellites used for fix (space for 12) * 2.5 PDOP (dilution of precision) * 1.3 Horizontal dilution of precision (HDOP) * 2.1 Vertical dilution of precision (VDOP) * *39 the checksum data, always begins with * * **/NMEA_STATUSNMEASendGPGSA (void){ NMEA_GSA_DATA NmeaGSAData; char pFieldBuffer[MAX_NMEA_FIELD]; int i, TXBufferIndex = 0; char TransmitBuffer[MAX_NMEA_BUFFER]; memset (TransmitBuffer, 0, MAX_NMEA_BUFFER); /** * Get the necessary data from the FW. **/ memset (&NmeaGSAData, 0, sizeof (NMEA_GSA_DATA)); NMEAGetGPGSAData (&NmeaGSAData); /** * Add the header **/ NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_START); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_GPGSA); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); /** * Field 0 Mode **/ if (NmeaGSAData.Mode == NMEA_MODE_A) { strcpy (pFieldBuffer, NMEA_MODE_A_STR); NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); } else if (NmeaGSAData.Mode == NMEA_MODE_M) { strcpy (pFieldBuffer, NMEA_MODE_M_STR); NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); } NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); /** * Field 1 FixMode **/ sprintf (pFieldBuffer, "%d", NmeaGSAData.FixMode); NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); /** * Now the satellites **/ for (i = 0; i < 12; i++) { if (NmeaGSAData.PRNs[i]) { sprintf (pFieldBuffer, "%02d", NmeaGSAData.PRNs[i]); /* itoa( NmeaGSAData.PRNs[ i ], pFieldBuffer, 10 ); */ NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); } else { NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); } } /** * PDOP **/ ftoa (NmeaGSAData.PDOP, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); /** * HDOP **/ ftoa (NmeaGSAData.HDOP, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); /** * VDOP **/ ftoa (NmeaGSAData.VDOP, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); /* NMEAAddField( TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA );*/ /** * Check Sum **/ NMEAAddCheckSum (TransmitBuffer, &TXBufferIndex); /** * CR/LF **/ NMEAAddCRLF (TransmitBuffer, &TXBufferIndex); /** * Now send the sentence. **/ if (!ComPortWrite ((unsigned char *) &TransmitBuffer[0], TXBufferIndex)) { return NMEA_FAILED; } else { return NMEA_SUCCESS; }}NMEA_STATUSNMEAGetGPGSVData (pNMEA_GSV_DATA pNmeaGSVData){ int Satellite; pVISIBLE_SV_DATA pVisibleSVData; pNmeaGSVData->NumberOfSatellites = GetNumberOfVisibleSVs (); /** * Calculate the number of sentences. **/ if (pNmeaGSVData->NumberOfSatellites <= 4) { pNmeaGSVData->NumberOfSentences = 1; } else { pNmeaGSVData->NumberOfSentences = pNmeaGSVData->NumberOfSatellites / 4; if (pNmeaGSVData->NumberOfSatellites % 4) { pNmeaGSVData->NumberOfSentences += 1; } } pVisibleSVData = GetVisibleSVData (); for (Satellite = 0; Satellite < pNmeaGSVData->NumberOfSatellites; Satellite++) { pNmeaGSVData->SvViewData[Satellite].Valid = 1; /* pNmeaGSVData->SvViewData[ Satellite ].Azimuth = pVisibleSVData[ Satellite ].azimuth; */ if (pVisibleSVData[Satellite].azimuth < 0) { pNmeaGSVData->SvViewData[Satellite].Azimuth = 180 + (180 - ((abs (pVisibleSVData[Satellite].azimuth)))); } else { pNmeaGSVData->SvViewData[Satellite].Azimuth = pVisibleSVData[Satellite].azimuth; } pNmeaGSVData->SvViewData[Satellite].Elevation = pVisibleSVData[Satellite].elevation; pNmeaGSVData->SvViewData[Satellite].SatellitePRN = pVisibleSVData[Satellite].PRN; pNmeaGSVData->SvViewData[Satellite].SNR = pVisibleSVData[Satellite].CNo; } return NMEA_SUCCESS;}/** * GSV - Satellites in View shows data about the satellites that the * unit might be able to find based on its viewing mask and almanac * data. It also shows current ability to track this data. Note that * one GSV sentence only can provide data for up to 4 satellites and * thus there may need to be 3 sentences for the full information. It * is reasonable for the GSV sentence to contain more satellites than * GGA might indicate since GSV may include satellites that are not * used as part of the solution. It is not a requirment that the GSV * sentences all appear in sequence. To avoid overloading the data * bandwidth some receivers may place the various sentences in totally * different samples since each sentence identifies which one it is. * * The field called SNR (Signal to Noise Ratio) in the NMEA standard * is often referred to as signal strength. SNR is an indirect but * more useful value that raw signal strength. It can range from 0 to * 99 and has units of dB according to the NMEA standard, but the * various manufacturers send different ranges of numbers with * different starting numbers so the values themselves cannot * necessarily be used to evaluate different units. The range of * working values in a given gps will usually show a difference of * about 25 to 35 between the lowest and highest values, however 0 is * a special case and may be shown on satellites that are in view but * not being tracked. * * * $GPGSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75 * * Where: * GSV Satellites in view * 2 Number of sentences for full data * 1 sentence 1 of 2 * 08 Number of satellites in view * * 01 Satellite PRN number * 40 Elevation, degrees * 083 Azimuth, degrees * 46 SNR - higher is better * for up to 4 satellites per sentence * *75 the checksum data, always begins with * * **/NMEA_STATUSNMEASendGPGSV (void){ NMEA_GSV_DATA NmeaGSVData; char pFieldBuffer[MAX_NMEA_FIELD]; int TXBufferIndex = 0; char TransmitBuffer[MAX_NMEA_BUFFER]; TRACKING_PRNs TrackingPRNs[12]; int Satellite = 0; int SequenceNumber; int NumSatelliteThisSentence; memset (TransmitBuffer, 0, MAX_NMEA_BUFFER); memset (&NmeaGSVData, 0, sizeof (NMEA_GSV_DATA)); /** * Get the necessary data from the FW. **/ NMEAGetGPGSVData (&NmeaGSVData); GetTrackingPRNs (&TrackingPRNs[0]); for (SequenceNumber = 0; SequenceNumber < NmeaGSVData.NumberOfSentences; SequenceNumber++) { TXBufferIndex = 0; /** * Add the header **/ NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_START); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_GPGSV); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); /** * Field 0 Number of sentences for full data **/ sprintf (pFieldBuffer, "%d", NmeaGSVData.NumberOfSentences); NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); /** * Field 1 SequenceNumber **/ sprintf (pFieldBuffer, "%d", SequenceNumber + 1); NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); /** * Field 2 Number of satellites in view **/ sprintf (pFieldBuffer, "%02d", NmeaGSVData.NumberOfSatellites); /*itoa( NmeaGSVData.NumberOfSatellites, pFieldBuffer, 10 );*/ NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); /** * Now add the satellite data. **/ for (NumSatelliteThisSentence = 0; NumSatelliteThisSentence < 4; NumSatelliteThisSentence++) { if (NmeaGSVData.SvViewData[Satellite].Valid) { int i; /** * PRN **/ sprintf (pFieldBuffer, "%02d", NmeaGSVData.SvViewData[Satellite].SatellitePRN); /* itoa( NmeaGSVData.SvViewData[ Satellite ].SatellitePRN, pFieldBuffer, 10 ); */ NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); /** * Elevation **/ sprintf (pFieldBuffer, "%02d", NmeaGSVData.SvViewData[Satellite].Elevation); /*itoa( NmeaGSVData.SvViewData[ Satellite ].Elevation, pFieldBuffer, 10 );*/ NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); /** * Azimuth Needs to be 0 - 360 **/ sprintf (pFieldBuffer, "%03d", NmeaGSVData.SvViewData[Satellite].Azimuth); /* itoa( NmeaGSVData.SvViewData[ Satellite ].Azimuth, pFieldBuffer, 10 ); */ NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); /** * SNR * * * If we are not tracking then do not display * the SNR. **/ for (i = 0; i < 11; i++) { /** * See if we are tracking this guy. **/ if ((unsigned) NmeaGSVData.SvViewData[Satellite].SatellitePRN == TrackingPRNs[i].PRN) { sprintf (pFieldBuffer, "%02d", NmeaGSVData.SvViewData[Satellite].SNR); NMEAAddField (TransmitBuffer, &TXBufferIndex, pFieldBuffer); break; } } if (NumSatelliteThisSentence < 3) { NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); } } else { NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); if (NumSatelliteThisSentence < 3) { NMEAAddField (TransmitBuffer, &TXBufferIndex, NMEA_SENTENCE_COMMA); } } Satellite++; /*SequenceNumber++; */ } /** * Check Sum **/ NMEAAddCheckSum (TransmitBuffer, &TXBufferIndex); /** * CR/LF **/ NMEAAddCRLF (TransmitBuffer, &TXBufferIndex); /** * Now send the sentence. **/ if (!ComPortWrite ((unsigned char *) &TransmitBuffer[0], TXBufferIndex)) { return NMEA_FAILED; } memset (TransmitBuffer, 0, MAX_NMEA_BUFFER); } return NMEA_SUCCESS;}/** * * RMC - NMEA has its own version of essential gps pvt (position, * velocity, time) data. It is called RMC, The Recommended Minimum, * which will look similar to: * * $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A * * Where: * RMC Recommended Minimum sentence C * 123519 Fix taken at 12:35:19 UTC * A Status A=active or V=Void. * 4807.038,N Latitude 48 deg 07.038' N * 01131.000,E Longitude 11 deg 31.000' E * 022.4 Speed over the ground in knots * 084.4 Track angle in degrees True * 230394 Date - 23rd of March 1994 * 003.1,W Magnetic Variation * *6A The checksum data, always begins with * * * **/NMEA_STATUSNMEAGetGPVTGData (pNMEA_VTG_DATA pNmeaVTGData){ pNmeaVTGData->TrueHeading = GetTrueHeading (); pNmeaVTGData->MagHeading = 180.32; pNmeaVTGData->GroundSpeedKnots = GetGroundSpeedKnots (); pNmeaVTGData->GroundSpeedKilos = GroundSpeedKilos (); return NMEA_SUCCESS;}/** * VTG - Velocity made good. The gps receiver may use the LC prefix * instead of GP if it is emulating Loran output. * * $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K * * where: * VTG Track made good and ground speed
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -