/************************************************************************************ * File Name: GpsData.c * Function Describe:处理GPS模块发回的数据,提取到sutGpsInfo * Relate Module: * Explain: * Writer: ShiLiangWen * Date: 2015.5.26 $GPGGA,235957.003,,,,,0,0,,,M,,M,,*44 $GPGSA,A,1,,,,,,,,,,,,,,,*1E $GPGSV,1,1,00*79 $GPRMC,235957.003,V,,,,,0.00,0.00,050180,,,N*4D *************************************************************************************/ #define THIS_FILE_ID 10 //-------------------------------------------------------------------------------------------- #include "includes.h" SUT_GPS_INF sutGpsInfo; /************************************************************************************* * **************************************************************************************/ int HEX_2_INT32(int hex_val) { char tmp_buf[13] = {0}; int val; sprintf(tmp_buf, "%x", hex_val); val = atoi (tmp_buf); return val; } /************************************************************************************* * **************************************************************************************/ static unsigned char translate_digitAscii_to_bcd(char *ascii_number, unsigned char len, char *bcd_number) { int i, j; char temp[10] = ""; /* extra + and NULL */ unsigned char bcd_index = 0; /* Index into output bcd_number */ int num_len = len; /* Translate or skip over invalid characters */ for (i = 0, j = 0; i < num_len; i++) { temp[j++] = ascii_number[i] & 0x0F; } ascii_number[len] = 0; /* Now that temp has the bcd codes in natural order... Squish them together * and reverse the order per bcd coding. */ for (i = 0; i < j; i+=2) bcd_number[bcd_index++] = ((char)(temp[i] << 4)) | temp[i+1]; bcd_number[len] = 0; return 0; } /*===================================== UTC time:hms status latitue north? longitue east? 速度(节) 方位角 UTC time 磁偏角 方向 模式 checksum $GPRMC hhmmss.sss A/V ddmm.mmmm N/S dddmm.mmmm E/W speed aspect ddmmyy 000-180 E/W A/D/E/N *hh For example: $GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50 */ #define GPRMC_UTC1_TOKEN_INDEX 0 #define GPRMC_STATUS_TOKEN_INDEX 1 #define GPRMC_LATITUE_TOKEN_INDEX 2 #define GPRMC_NORTH_TOKEN_INDEX 3 #define GPRMC_longitue_TOKEN_INDEX 4 #define GPRMC_EAST_TOKEN_INDEX 5 #define GPRMC_SPEED_TOKEN_INDEX 6 #define GPRMC_ASPECT_TOKEN_INDEX 7 #define GPRMC_UTC2_TOKEN_INDEX 8 #define GPS_UNLOCATE_TIME 6 //unit(5s) 持续多久未定位数据认为未定位上 /************************************************************************************* * **************************************************************************************/ void process_gps_data(char *buf,uint32_t size) //这里的buf就是从GPRMC,后开始 { char tmp_char[16] = {0}; char bcd_tmp[8] = {0}; char *token[16]; char size_each_token[16] = {0}; unsigned char hh,hl; unsigned char token_index = 0; int i = 0; int index = 0; int dig_bit_num = 0; int ptr_each = 0; unsigned short speed; unsigned short aspect; double speed_jie = 0.0; unsigned char temp; static unsigned char unLocateCt=0; memset(token, NULL, sizeof(token)); token[token_index] = buf; RunMake(THIS_FILE_ID); while(index < size ) { if(buf[index] == ',') { size_each_token[token_index] = ptr_each; if(ptr_each == 0) token[token_index] = NULL; //*(token[token_index] + ptr_each) = 0; // ptr_each = 0; token_index++; token[token_index] = buf+index+1; //skip this ',' if(*(token[token_index]+1) == '*') { size_each_token[token_index] = 1; //cut of *hh\r\n } } else { ptr_each++; } index++; } RunMake(THIS_FILE_ID); //检测token地址是否合法,有任何一个不合法则丢掉当前NEMA包 //并认定当前包为非定位包 //一般都未定位包才会有地址不对 for(i=GPRMC_UTC1_TOKEN_INDEX;i= (char *)&RxBuffer3[UART3_RX_BUFFER_SIZE]) &&//超出范围 token[i] != NULL)//非空 {//非法地址值 if(unLocateCt <= GPS_UNLOCATE_TIME) unLocateCt++; else sutGpsInfo.isGpsValid = 0;//持续时间,认为非定位 return; } } ////////////////////////////////////////////////////////////////////////// //UTC time:hms if(token[GPRMC_UTC1_TOKEN_INDEX]) { strncpy((char*)tmp_char,(char*)token[0],size_each_token[0]); translate_digitAscii_to_bcd(tmp_char,6,bcd_tmp); //去掉.xx //小时需要加8 因为北京是东8区 memcpy(tmp_char, (char*)token[0], 2); tmp_char[2]=0; temp=atoi(tmp_char)+8; //if(temp >= 24) temp -= 24; hl=temp%10; hh=temp%100/10; hh <<= 4;hh &= 0xf0; sutGpsInfo.hour=(hh | hl); sutGpsInfo.minu = bcd_tmp[1]; sutGpsInfo.sec = bcd_tmp[2]; } RunMake(THIS_FILE_ID); //Fix status if(token[GPRMC_STATUS_TOKEN_INDEX]) { memset(tmp_char , 0 ,sizeof(tmp_char)); strncpy((char*)tmp_char,(char*)token[1],size_each_token[1]); if(*tmp_char == 'A'){ sutGpsInfo.isGpsValid = 1; unLocateCt=0; }else{ if(unLocateCt <= GPS_UNLOCATE_TIME) unLocateCt++; else sutGpsInfo.isGpsValid = 0;//持续时间,认为非定位 } } RunMake(THIS_FILE_ID); if(sutGpsInfo.isGpsValid == 0)return; //latitude 纬度 /*===================================== UTC time:hms status latitue north? longitue east? 速度(节) 方位角 UTC time 磁偏角 方向 模式 checksum $GPRMC hhmmss.ss A/V ddmm.mmmm N/S dddmm.mmmm E/W speed aspect ddmmyy 000-180 E/W A/D/E/N *hh For example: $GPRMC,024813.640,A,3158.4608,N,11848.3737,E,010.5,324.7,150706,,,A*50 */ if(token[GPRMC_LATITUE_TOKEN_INDEX]) { RunMake(THIS_FILE_ID); memset(tmp_char , 0 ,sizeof(tmp_char)); memset(bcd_tmp , 0 ,sizeof(bcd_tmp)); strncpy((char*)(tmp_char+1),(char*)token[2],size_each_token[2]); tmp_char[0] = '0'; RunMake(THIS_FILE_ID); for(i = 5; i < 8;i++) tmp_char[i] = tmp_char[i+1]; tmp_char[8] = 0; //小数点后面去掉最后1位 translate_digitAscii_to_bcd(tmp_char,8,bcd_tmp); //去掉.xx //North or south memset(tmp_char , 0 ,sizeof(tmp_char)); if(token[GPRMC_NORTH_TOKEN_INDEX]) { strncpy((char*)tmp_char,(char*)token[3],size_each_token[3]); if(*tmp_char == 'S') bcd_tmp[0] |= 0x80; sutGpsInfo.latitue = (bcd_tmp[3] | (bcd_tmp[2] << 8) |(bcd_tmp[1] << 16) |(bcd_tmp[0] << 24)); } RunMake(THIS_FILE_ID); } //longitude 经度 if(token[GPRMC_longitue_TOKEN_INDEX]) { memset(tmp_char , 0 ,sizeof(tmp_char)); memset(bcd_tmp , 0 ,sizeof(bcd_tmp)); RunMake(THIS_FILE_ID); strncpy((char*)tmp_char,(char*)token[4],size_each_token[4]); for(i = 5; i < 8;i++) tmp_char[i] = tmp_char[i+1]; tmp_char[8] = 0; translate_digitAscii_to_bcd(tmp_char,8,bcd_tmp); //去掉.xx RunMake(THIS_FILE_ID); //east or west if(token[GPRMC_EAST_TOKEN_INDEX]) { memset(tmp_char , 0 ,sizeof(tmp_char)); strncpy((char*)tmp_char,(char*)token[5],size_each_token[5]); if(*tmp_char == 'W') bcd_tmp[0] |= 0x80; sutGpsInfo.longitue = (bcd_tmp[3] | (bcd_tmp[2] << 8) |(bcd_tmp[1] << 16) |(bcd_tmp[0] << 24)); } } //Speed if(token[GPRMC_SPEED_TOKEN_INDEX]) { RunMake(THIS_FILE_ID); memset(tmp_char , 0 ,sizeof(tmp_char)); strncpy((char*)tmp_char,(char*)token[GPRMC_SPEED_TOKEN_INDEX],size_each_token[GPRMC_SPEED_TOKEN_INDEX]); index = 0; while(index < size_each_token[GPRMC_SPEED_TOKEN_INDEX]) { if(tmp_char[index] == '.') break; index++; } dig_bit_num = size_each_token[GPRMC_SPEED_TOKEN_INDEX]-index-1; //这里,index代表小数点前有多少位,dig_bit_num代表小数点后面有多少位 RunMake(THIS_FILE_ID); //ol_debug("dig_bit_num:%d,all len:%d",dig_bit_num,size_each_token[GPRMC_SPEED_TOKEN_INDEX]); if(index == 3) { speed_jie = (tmp_char[0]-0x30)*100 + (tmp_char[1]-0x30)*10 + (tmp_char[2]-0x30); } else if(index == 2) { speed_jie = (tmp_char[0]-0x30)*10 + (tmp_char[1]-0x30); } else speed_jie = (tmp_char[0]-0x30); if(dig_bit_num > 0) speed_jie += (tmp_char[index+1]-0x30)*0.1; speed = (unsigned short)(speed_jie*1.852); sutGpsInfo.speed = ( ((speed/100)<<8) | (((speed /10)%10)<<4) | (speed %10) ); //ol_debug("speed_jie to speed:%d,xinan speed:%d",speed,sutGpsInfo.speed); } RunMake(THIS_FILE_ID); //Aspect 方向 if(token[GPRMC_ASPECT_TOKEN_INDEX]) { memset(tmp_char , 0 ,sizeof(tmp_char)); strncpy((char*)tmp_char,(char*)token[GPRMC_ASPECT_TOKEN_INDEX],size_each_token[GPRMC_ASPECT_TOKEN_INDEX]); aspect = (unsigned short)((tmp_char[0]-0x30)*100 + (tmp_char[1]-0x30)*10 + (tmp_char[2]-0x30)); sutGpsInfo.aspect= ( ((aspect/100) << 8) | (((aspect /10)%10)<<4) | (aspect %10) ); } RunMake(THIS_FILE_ID); //UTC2 if(token[GPRMC_UTC2_TOKEN_INDEX]) { memset(tmp_char , 0 ,sizeof(tmp_char)); memset(bcd_tmp , 0 ,sizeof(bcd_tmp)); strncpy((char*)tmp_char,(char*)token[GPRMC_UTC2_TOKEN_INDEX],size_each_token[GPRMC_UTC2_TOKEN_INDEX]); translate_digitAscii_to_bcd(tmp_char,6,bcd_tmp); sutGpsInfo.day = bcd_tmp[0]; sutGpsInfo.month= bcd_tmp[1]; sutGpsInfo.year = bcd_tmp[2]; } } #if(GPS_VIRTUAL_VALUE==1) static unsigned char sucTimeH,sucTimeL; static unsigned long susTime=(7*3600+30*60+0); static unsigned long sucLatitue=0x02237542;//; static unsigned long sucLongitue=0x11401316;//; #endif /************************************************************************************* * 根据GPS模块返回的nema数据,提取并放入sutGpsInfo中 **************************************************************************************/ void process_nema(char *nema) { unsigned char len; //$GPRMC if(nema[0] != '$' || nema[1] != 'G' || nema[3] != 'R' || nema[4] != 'M' || nema[5] != 'C') return; len=strlen(&nema[7]); process_gps_data(&nema[7],len); sutGpsInfo.isGpsWork=1; sutGpsInfo.GpsInactiveCt=0; #if(GPS_VIRTUAL_VALUE==1) if(sutGpsInfo.isGpsValid==0){ sutGpsInfo.isGpsValid=1; sutGpsInfo.latitue=sucLatitue; sutGpsInfo.longitue=sucLongitue; sutGpsInfo.speed=0x4321; sutGpsInfo.aspect=0x7654; sutGpsInfo.StatisticsMile=0x123456; sutGpsInfo.year=0x15; sutGpsInfo.month=0x07; sutGpsInfo.day=0x26; susTime++; sutGpsInfo.hour=(unsigned char)(susTime/3600); sutGpsInfo.minu=(unsigned char)((susTime%3600)/60); sutGpsInfo.sec=(unsigned char)(susTime%60); sucTimeH=sutGpsInfo.hour/10; sucTimeL=sutGpsInfo.hour%10; sutGpsInfo.hour=(sucTimeH<<4)+sucTimeL; sucTimeH=sutGpsInfo.minu/10; sucTimeL=sutGpsInfo.minu%10; sutGpsInfo.minu=(sucTimeH<<4)+sucTimeL; sucTimeH=sutGpsInfo.sec/10; sucTimeL=sutGpsInfo.sec%10; sutGpsInfo.sec=(sucTimeH<<4)+sucTimeL; } #endif }