/************************************************************************************ * 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 *************************************************************************************/ #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 /************************************************************************************* * **************************************************************************************/ void process_gps_data(char *buf,uint32_t size) //这里的buf就是从GPRMC,后开始 { char tmp_char[16] = {0}; char bcd_tmp[8] = {0}; char *token[16] = {NULL}; 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; token[token_index] = buf; SetHFH(0,1); 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++; } SetHFH(0,2); //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区 hl=bcd_tmp[0]&0x0f; hh=bcd_tmp[0]&0xf0; hl+=8; if(hl>=10){ hl-=10; hh+=0x10; if(hh>0x20)hh=0; } sutGpsInfo.hour=(hh | hl); sutGpsInfo.minu = bcd_tmp[1]; sutGpsInfo.sec = bcd_tmp[2]; } SetHFH(0,3); //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; } else if(*tmp_char == 'V') { sutGpsInfo.isGpsValid = 0; } } SetHFH(0,4); if(sutGpsInfo.isGpsValid == 0)return; //latitue /*===================================== 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]) { SetHFH(0,5); 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'; SetHFH(0,6); 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)); } SetHFH(0,7); } //longitue if(token[GPRMC_longitue_TOKEN_INDEX]) { memset(tmp_char , 0 ,sizeof(tmp_char)); memset(bcd_tmp , 0 ,sizeof(bcd_tmp)); SetHFH(0,8); 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 SetHFH(0,9); //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]) { SetHFH(0,10); 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代表小数点后面有多少位 SetHFH(0,11); //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); } SetHFH(0,12); //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) ); } SetHFH(0,13); //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]; } SetHFH(0,14); } /************************************************************************************* * 根据GPS模块返回的nema数据,提取并放入sutGpsInfo中 **************************************************************************************/ void process_nema(char *nema) { static unsigned char sucCt=0; int len; if(++sucCt>2){ sucCt=0; SlwTrace(INF,nema); if(sutGpsInfo.isGpsValid)SlwTrace(INF,"[GPS Valid]\r\n"); else SlwTrace(INF,"[GPS INValid]\r\n"); } if(nema[0]!='$' || nema[3]!='R' || nema[5]!='C')return; len=strlen(&nema[7]); process_gps_data(&nema[7],len); sutGpsInfo.isGpsWork=1; }