本文主要是介绍刚学C写的东西,纪念下:),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
这个程序用来模拟从串口读出NMEA协议的数据并校检和解析~~
因为刚用C,C++写代码,写的应该还蛮难看的~~
#include <iostream> #include <fstream> #include <sys/select.h> //author:snail //070403 typedef unsigned char U8; typedef signed int S32; typedef unsigned short int U16; typedef signed short int S16; typedef unsigned int U32; using namespace std; //################################################################################## //utility method!!! //################################################################################## void millisleep(int ms) //sleep some million seconds { if (ms>0) { struct timeval tv; tv.tv_sec=0; tv.tv_usec=ms*1000; select(0, 0, 0, 0, &tv); } } unsigned char Hex2ToUint8(unsigned char *ahex) { unsigned char sum,Ch; if ((Ch=*ahex++)<='9') sum=Ch-'0'; else sum=Ch-'A'+10; if ((Ch=*ahex)<='9') sum=sum*16+Ch-'0'; else sum=sum*16+Ch-'A'+10; return sum; } int cstringToInt(char* str,char len) { int sum=0; for (char i=0; i<len; i++) { sum=sum*10+str[i]-'0'; } return sum; } double cstringToDouble(char* str,char len) { char* dotPtr = strchr(str,'.'); char intLen = dotPtr - str; char douLen = len -intLen -1; int douPart = cstringToInt(dotPtr+1,douLen); int div = 1; for (int i=0;i<douLen;i++) { div*=10; } return cstringToInt(str,intLen)+((double)douPart)/div; } double negcstringToDouble(char* str,char len) { if (*str=='-')return 0-cstringToDouble(str+1,len-1); else return cstringToDouble(str,len); } //################################################################################## //utility method!!! //################################################################################## //################################################################################### // NMEAæpackage checkSumæ //################################################################################### bool __gpsCheckSum(unsigned char *buf,unsigned char len) { cout << "begine checkSum!!" << endl; unsigned char i,chksum,value=0; chksum=Hex2ToUint8(&buf[len-2]); len-=3; for (i=1;i<len;i++) value^= buf[i]; if (chksum==value) return true; return false; } //################################################################################### //################################################################################### //################################################################################### //################################################################################### //###########################struct userfule data ################################ //################################################################################### struct _NMEA_DATA { S32 Latitude; //1/60000 deg S32 Longitude; //1/60000 deg S16 Altitude; //mm U16 Speed; //km/h U16 Azimuth; //1e-5 deg U16 Year; U8 Mon; U8 Day; U8 Hour; U8 Min; U8 Sec; U8 GPSfix; //0=no fix,2=2D-fix,3=3D-fix,5=Time only fix U8 SVnum; //æ }; void DEBUGINFO(_NMEA_DATA& data) { cout << "#######################################################################/n"; cout << "receive a gps message!/n"; cout << "Year: " << (int)data.Year <<"/n"; cout << "Month: " << (int)data.Mon <<"/n"; cout << "Day: " << (int)data.Day <<"/n"; cout << "Hour: " << (int)data.Hour << "/n"; cout << "Minute: " << (int)data.Min << "/n"; cout << "Sec: " << (int)data.Sec << "/n"; cout << "Sate: " << (int)data.SVnum << "/n"; cout << "Latitude:" << data.Latitude << '/n'; cout << "Longitude:" << data.Longitude << '/n'; cout << "Speed:" << data.Speed << '/n'; cout << "Azimuth" <<data.Azimuth << '/n'; cout << "GPSFix: " << ((data.GPSfix==1)?"fix":"notFix") << "/n"; cout << "Altitude: " << data.Altitude << '/n'; cout << "#######################################################################/n"; millisleep(5000); } //################################################################################### //###########################struct userfule data ################################ //################################################################################### //############################################################################################ //################################## vitrual serialPort#################################### //############################################################################################ //############################################################################################ class SmallPort { public: SmallPort(ifstream&stream):in(stream) {}; int readLine(char *,uint); int size(); protected: int readBlock(char *,int); ifstream& in; }; int SmallPort::size() { //read 10 char from the serialPort one time return 10; } int SmallPort::readBlock(char *c,int size) { //read a char form file in.get(*c); } int SmallPort::readLine(char *data, uint maxlen) { int bytesAvail=(int)size(); char* pCur=data; /*if nothing waiting, return 0 length*/ if (bytesAvail<1) { return 0; } /*read a byte at a time for MIN(bytesAvail, maxlen) iterations, or until a newline*/ while (pCur<(data+bytesAvail) && --maxlen) { readBlock(pCur, 1); if (*pCur++ == '/n') { break; } } *pCur++='/0'; /*return size of data read*/ return (pCur-data); } //############################################################################################ //################################## vitrual serialPort####################################### //############################################################################################ //############################################################################################ //############################################################################################ //#####################################PortDataParser######################################### //############################################################################################ //############################################################################################ class PortDataParser { public: void start(); private: void parse(); int __ggaLength; int __rmcLength; char __buffer[1000]; char __ggaBuffer[1000]; char __rmcBuffer[1000]; }; //################################################################################### //ä¾startParseNMEADataå //################################################################################### void PortDataParser::parse(void) { _NMEA_DATA data; if (__ggaLength==-1 || __rmcLength==-1) { return; } //************************************************************** //ä»$GPGGAç¬ get the satellite number (between 7-8 comma)¸ª //************************************************************** { char *ptr; ptr = __ggaBuffer; for (int i=0; i<7; i++) { if ((ptr = strchr(ptr+1,','))==NULL) return; } char* ptrNext=strchr(ptr+1,','); if (ptrNext == NULL)return; if ( ptrNext-ptr>0) { data.SVnum = (U8)cstringToInt(ptr+1, ptrNext-ptr); } else { data.SVnum = 0; } ptr=ptrNext+1; if ((ptrNext = strchr(ptr,','))==NULL) return; ptr=ptrNext+1; if ((ptrNext = strchr(ptr,','))==NULL) return; if ((ptrNext-ptr)>0) { data.Altitude = (S16)negcstringToDouble(ptr,ptrNext-ptr); } } //************************************************************** //************************************************************** //************************************************************** //ä»$GPRMCä //************************************************************** char *ptr; char *ptrNext; ptr = __rmcBuffer; cout << "/n rmcbuffer->" << ptr; if ((ptr = strchr(ptr,',')) == NULL) return; ptr++; ptrNext=strchr(ptr,','); if ((ptrNext-ptr)==9) { data.Hour = (U8)cstringToInt(ptr,2); data.Min = (U8)cstringToInt(ptr+2,2); data.Sec = (U8)cstringToInt(ptr+4,2); } //第¯GPSæ ptr = ptrNext+1; if ((ptrNext = strchr(ptr,','))==NULL) return; if (*ptr=='A') data.GPSfix=1; else data.GPSfix = 0; //ç¬longitudeï¼ ddmm.mmmmï¼ ptr = ptrNext+1; if ((ptrNext = strchr(ptr,','))==NULL) return; if ((ptrNext-ptr)>0) { double d = cstringToDouble(ptr,ptrNext-ptr); data.Longitude = (S32)((d-40*((int)d/100))*1000); } //ç¬(æN or S) ptr = ptrNext+1; if ((ptrNext = strchr(ptr,','))==NULL) return; if (*ptr=='S') data.Longitude = 0 - data.Longitude; //ç¬( latitude ddmm.mmmm) ptr = ptrNext+1; if ((ptrNext = strchr(ptr,','))==NULL) return; if ((ptrNext-ptr)>0) { double d = cstringToDouble(ptr,ptrNext-ptr); data.Latitude = (S32)((d-40*((int)d/100))*1000); } //· (E or W) ptr = ptrNext+1; if ((ptrNext = strchr(ptr,','))==NULL) return; if (*ptr=='W') data.Latitude = 0 - data.Latitude; //ç(spd,knots ) ptr = ptrNext+1; if ((ptrNext = strchr(ptr,','))==NULL) return; if ((ptrNext-ptr)>0) { data.Speed = (int)(cstringToDouble(ptr,ptrNext-ptr)*18.42); } //ç(cog,degrees); ptr = ptrNext+1; if ((ptrNext = strchr(ptr,','))==NULL) return; if ((ptrNext-ptr)>0) { data.Azimuth = (int)(cstringToDouble(ptr,ptrNext-ptr)*10); } //ç¬( ddmmyy); ptr = ptrNext+1; if ((ptrNext = strchr(ptr,','))==NULL) return; if ((ptrNext-ptr)==6) { data.Day = (U8)cstringToInt(ptr,2); data.Mon= (U8)cstringToInt(ptr+2,2); data.Year = (U16)cstringToInt(ptr+4,2); } //************************************************************** //************************************************************** //--------------------------------------------------------------------------------------------------------------------------------------- DEBUGINFO(data); //--------------------------------------------------------------------------------------------------------------------------------------- __ggaLength = -1; __rmcLength = -1; } void PortDataParser::start() { ifstream in("./data"); SmallPort testPort(in); int time = 0; while (time++<=10) { cout << "/n/n/n/n/n/n/n start load ! /n"; //############################################################################ //1 load some chars from port to __buffer until to a line //############################################################################ int address=0; bool NotMoveToBuffer = true; while (NotMoveToBuffer) { //int i = __serialPort.readLine(&__buffer[address],MAXLEN_SERIALPORT - address); int i = testPort.readLine(&__buffer[address],1000 - address); if (i>1) { address += i - 1; } if (i==0 || address > 1 && __buffer[address-1]!='/n') { //if (address >= MAXLEN_SERIALPORT) address = 0; millisleep(100); } else { NotMoveToBuffer = false; } cout << "buffer-> " << __buffer << endl << '/n'; } cout << "-----------------------------------------------------------------------------------/n"; cout << "move " << address << " bytes into buffer!" << "/n"; cout << "-----------------------------------------------------------------------------------/n"; //############################################################################ // 2 start checksum //############################################################################ //æfind the char'$'符ç int dollerAddress=-1; for (int i=0; i<address-1; i++) { if (__buffer[i] == '$' || __buffer[i]=='/n') { if (__buffer[i]=='$') { dollerAddress = i; } break; } } //cout << "find '$' in " << dollerAddress << endl; //cout << "__buffer[address-1]" << (int)__buffer[address-1]; //cout << "__buffer[address-2]" << (int)__buffer[address-2] << "/n"; if (dollerAddress==-1 || __buffer[address-2]!='/r' || !__gpsCheckSum((unsigned char *)&__buffer[dollerAddress],address-dollerAddress-2)) { cout << "-------------------------------------------------------------------------------------------------/n"; cout << "The data in buffer is wrong!"; cout << "-------------------------------------------------------------------------------------------------/n"; continue; } cout << "-----------------------------------------------------------------------------------------------------/n"; cout << "The data in buffer is valid!"; cout << "-----------------------------------------------------------------------------------------------------/n"; //############################################################################ // 3 move useful data to other buffers! //############################################################################ bool parseNMEAData = false; if (strncmp(&__buffer[dollerAddress],"$GPGGA",6)==0) { __ggaLength = address-dollerAddress; strncpy(__ggaBuffer,&__buffer[dollerAddress],__ggaLength); __ggaBuffer[__ggaLength]='/0'; } else if (strncmp(&__buffer[dollerAddress],"$GPRMC",6)==0) { __rmcLength = address-dollerAddress; strncpy(__rmcBuffer,&__buffer[dollerAddress],__rmcLength); __rmcBuffer[__rmcLength]='/0'; parseNMEAData = true; } else { continue; } //############################################################################# // 4 start parse! //############################################################################# if (parseNMEAData) { parse(); } } } int main() { PortDataParser parse; parse.start(); return 0; } |
这是NMEA协议的数据
$GPGSV,3,1,11,02,52,114,49,26,60,206,48,42,46,143,41,04,13,123,45*7D
$GPGSV,3,2,11,29,77,199,47,07,29,298,,06,38,283,18,08,21,073,*7C
$GPGSV,3,3,11,27,11,047,,24,42,320,27,10,56,023,*48
$GPGLL,3201.85399,N,11849.58941,E,055602.00,A,A*67
$GPZDA,055602.00,25,03,2007,00,00*63
$GPRMC,055603.00,A,3201.85411,N,11849.58933,E,0.003,,250307,,,A*7D
$GPVTG,,T,,M,0.003,N,0.005,K,A*25
$GPGGA,055603.00,3201.85411,N,11849.58933,E,1,05,3.02,49.9,M,5.3,M,,*57
$GPGSA,A,3,02,26,04,29,06,,,,,,,,3.59,3.02,1.93*08
$GPGSV,3,1,11,02,52,114,49,26,60,206,48,42,46,143,40,04,13,124,44*7A
$GPGSV,3,2,11,29,77,199,47,07,29,298,,06,38,283,16,08,21,073,*72
$GPGSV,3,3,11,27,11,047,,24,42,320,26,10,56,023,*49
$GPGLL,3201.85411,N,11849.58933,E,055603.00,A,A*64
$GPZDA,055603.00,25,03,2007,00,00*62
$GPRMC,055604.00,A,3201.85424,N,11849.58925,E,0.024,143.86,250307,,,A*68
$GPVTG,143.86,T,,M,0.024,N,0.044,K,A*33
$GPGGA,055604.00,3201.85424,N,11849.58925,E,1,05,3.03,49.7,M,5.3,M,,*5E
$GPGSA,A,3,02,26,04,29,06,,,,,,,,3.59,3.03,1.93*09
$GPGSV,3,1,11,02,52,114,49,26,60,206,48,42,46,143,41,04,13,124,44*7B
$GPGSV,3,2,11,29,77,199,47,07,29,298,,06,38,283,14,08,21,073,*70
$GPGSV,3,3,11,27,11,047,,24,42,320,27,10,56,023,*48
$GPGLL,3201.85424,N,11849.58925,E,055604.00,A,A*62
$GPZDA,055604.00,25,03,2007,00,00*65
$GPRMC,055605.00,A,3201.85438,N,11849.58918,E,0.009,,250307,,,A*73
$GPVTG,,T,,M,0.009,N,0.016,K,A*2D
$GPGGA,055605.00,3201.85438,N,11849.58918,E,1,05,3.03,49.5,M,5.3,M,,*5E
程序运行后的结果
#######################################################################
receive a gps message!
Year: 7
Month: 3
Day: 25
Hour: 5
Minute: 56
Sec: 4
Sate: 46
Latitude:7129589
Longitude:1921854
Speed:0
Azimuth1438
GPSFix: fix
Altitude: 49
#######################################################################
这篇关于刚学C写的东西,纪念下:)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!