// GNRMC_Analysis.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
// http://baike.baidu.com/link?url=OVUwBFU0AmHo3G3KfjZ431T0m8aBoTn3vIegc9oFlD6ie-rxp2zyYYYyE3dIxb9XnySxKVu_tfLCII2UoNMvOK
// $GNRMC,092846.400,A,3029.7317,N,10404.1784,E,000.0,183.8,070417,,,A*73
/*
$GNRMC,
092846.400, // UTC时间,hhmmss.sss(时分秒.毫秒)格式
A, // 定位状态,A=有效定位,V=无效定位
3029.7317,N, // 纬度
10404.1784,E, // 经度
000.0, // 地面速率
183.8, // 地面航向
070417, // UTC日期
, // 磁俯角
, // 磁方向角
A*73 // 模式指示
*/
struct GNRMC_Info
{
unsigned int year;
unsigned char month;
unsigned char day;
unsigned char hour;
unsigned char Minute;
unsigned char second;
unsigned int longitude; // 经度
unsigned char longitude_suffix; // 经度半球E(东经)或W(西经)
unsigned int latitude; // 纬度
unsigned char latitude_suffix; // 纬度半球N(北半球)或S(南半球)
unsigned char position_valid; // 定位是否有效
};
int comma_split(unsigned char* pstr,char* buf,int buflen,int s,int e )
{
int i , k ;
int commaCount = 0;
int rc = -1;
i=k=0;
if( e <= s )
{
return -1;
}
while(pstr[i]!=‘\0‘)
{
if( pstr[i]==‘,‘)
{
commaCount++;
}
if( commaCount == s )
{
k = ++i;
break;
}
i++;
}
while(pstr[i]!=‘\0‘)
{
if( pstr[i]==‘,‘)
{
commaCount++;
}
if( commaCount == e )
{
if( i - k + 1 > buflen)
{
return -1;
}
memset(buf,0,sizeof(buf));
memcpy(buf,pstr+k,i-k);
rc = i - k;
buf[rc] =‘\0‘;
printf("%s\n",buf);
break;
}
i++;
}
return rc;
}
int GNRMC_Parse(unsigned char* pstr,struct GNRMC_Info* pGNRMCInfo )
{
int len = 0;
int commaCount=0;
double temp = 0;
char buf[32]={0};
// 计算字符串长度
while(pstr[len] != ‘\0‘ )
{
if( pstr[len] == ‘,‘)
{
commaCount++;
}
len++;
}
// 逗号个数是12个
if( commaCount != 12 )
{
return -1;
}
// 判断开始字符是:$GNRMC
if( ! ((pstr[0]== ‘$‘) && (pstr[1]== ‘G‘) && (pstr[2]== ‘N‘) && (pstr[3]== ‘R‘) && (pstr[4]== ‘M‘) && (pstr[5]== ‘C‘)))
{
return -1;
}
// 判断结束字符是:\r\n
if( (pstr[len-2]!= ‘\r‘) && (pstr[len-1]!= ‘\n‘) )
{
return -1;
}
// UTC时间:第1个逗号与第2个逗号之前 (eg:092846.400 hhmmss.sss )
len = comma_split(pstr,buf,sizeof(buf),1,2);
if( len < 0 )
{
return -1;
}
pGNRMCInfo->hour = (buf[0]-‘0‘)*10+(buf[1]-‘0‘);
pGNRMCInfo->Minute = (buf[2]-‘0‘)*10+(buf[3]-‘0‘);
pGNRMCInfo->second = (buf[4]-‘0‘)*10+(buf[5]-‘0‘);
// 定位状态:第2个逗号与第3个逗号之前
len = comma_split(pstr,buf,sizeof(buf),2,3);
if( len != 1 )
{
return -1;
}
pGNRMCInfo->position_valid = ((buf[0]==‘A‘ ) ?1:0) ;
// 经度
len = comma_split(pstr,buf,sizeof(buf),3,4);
if( len < 0 )
{
return -1;
}
temp = atof(buf);
temp = temp*10000;
pGNRMCInfo->longitude = temp;
// 经度半球E(东经)或W(西经)
len = comma_split(pstr,buf,sizeof(buf),4,5);
if( len != 1 )
{
return -1;
}
pGNRMCInfo->longitude_suffix = buf[0];
// 纬度
len = comma_split(pstr,buf,sizeof(buf),5,6);
if( len < 0 )
{
return -1;
}
temp = atof(buf);
temp = temp*10000;
pGNRMCInfo->latitude = temp;
// 纬度半球N(北半球)或S(南半球)
len = comma_split(pstr,buf,sizeof(buf),6,7);
if( len != 1 )
{
return -1;
}
pGNRMCInfo->latitude_suffix = buf[0];
// UTC日期:ddmmyy(日月年)格式 eg:070417
len = comma_split(pstr,buf,sizeof(buf),9,10);
if( len < 0 )
{
return -1;
}
pGNRMCInfo->day = (buf[0]-‘0‘)*10+(buf[1]-‘0‘);
pGNRMCInfo->month = (buf[2]-‘0‘)*10+(buf[3]-‘0‘);
pGNRMCInfo->year = (buf[4]-‘0‘)*10+(buf[5]-‘0‘) + 2000;
return 0;
}
int main(int argc, char* argv[])
{
struct GNRMC_Info GNRMC;
char* p= "$GNRMC,092846.400,A,3029.7317,N,10404.1784,E,000.0,183.8,070417,,,A*73\r\n";
GNRMC_Parse((unsigned char *)p,&GNRMC);
printf("时间:%d-%d-%d %d:%d:%d\n",GNRMC.year,GNRMC.month,GNRMC.day,GNRMC.hour,GNRMC.Minute,GNRMC.second);
printf("%u %c ---- %u %c 定位是否有效果:%d\n",GNRMC.longitude,GNRMC.longitude_suffix,GNRMC.latitude,GNRMC.latitude_suffix,GNRMC.position_valid);
getchar();
return 0;
}