GpsData.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /************************************************************************************
  2. * File Name: GpsData.c
  3. * Function Describe:处理GPS模块发回的数据,提取到sutGpsInfo
  4. * Relate Module:
  5. * Explain:
  6. * Writer: ShiLiangWen
  7. * Date: 2015.5.26
  8. $GPGGA,235957.003,,,,,0,0,,,M,,M,,*44
  9. $GPGSA,A,1,,,,,,,,,,,,,,,*1E
  10. $GPGSV,1,1,00*79
  11. $GPRMC,235957.003,V,,,,,0.00,0.00,050180,,,N*4D
  12. *************************************************************************************/
  13. #define THIS_FILE_ID 10
  14. //--------------------------------------------------------------------------------------------
  15. #include "includes.h"
  16. SUT_GPS_INF sutGpsInfo;
  17. /*************************************************************************************
  18. *
  19. **************************************************************************************/
  20. int HEX_2_INT32(int hex_val)
  21. {
  22. char tmp_buf[13] = {0};
  23. int val;
  24. sprintf(tmp_buf, "%x", hex_val);
  25. val = atoi (tmp_buf);
  26. return val;
  27. }
  28. /*************************************************************************************
  29. *
  30. **************************************************************************************/
  31. static unsigned char translate_digitAscii_to_bcd(char *ascii_number, unsigned char len, char *bcd_number)
  32. {
  33. int i, j;
  34. char temp[10] = ""; /* extra + and NULL */
  35. unsigned char bcd_index = 0; /* Index into output bcd_number */
  36. int num_len = len;
  37. /* Translate or skip over invalid characters */
  38. for (i = 0, j = 0; i < num_len; i++)
  39. {
  40. temp[j++] = ascii_number[i] & 0x0F;
  41. }
  42. ascii_number[len] = 0;
  43. /* Now that temp has the bcd codes in natural order... Squish them together
  44. * and reverse the order per bcd coding.
  45. */
  46. for (i = 0; i < j; i+=2)
  47. bcd_number[bcd_index++] = ((char)(temp[i] << 4)) | temp[i+1];
  48. bcd_number[len] = 0;
  49. return 0;
  50. }
  51. /*=====================================
  52. UTC time:hms status latitue north? longitue east? 速度(节) 方位角 UTC time 磁偏角 方向 模式 checksum
  53. $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
  54. For example: $GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50
  55. */
  56. #define GPRMC_UTC1_TOKEN_INDEX 0
  57. #define GPRMC_STATUS_TOKEN_INDEX 1
  58. #define GPRMC_LATITUE_TOKEN_INDEX 2
  59. #define GPRMC_NORTH_TOKEN_INDEX 3
  60. #define GPRMC_longitue_TOKEN_INDEX 4
  61. #define GPRMC_EAST_TOKEN_INDEX 5
  62. #define GPRMC_SPEED_TOKEN_INDEX 6
  63. #define GPRMC_ASPECT_TOKEN_INDEX 7
  64. #define GPRMC_UTC2_TOKEN_INDEX 8
  65. #define GPS_UNLOCATE_TIME 6 //unit(5s) 持续多久未定位数据认为未定位上
  66. /*************************************************************************************
  67. *
  68. **************************************************************************************/
  69. void process_gps_data(char *buf,uint32_t size) //这里的buf就是从GPRMC,后开始
  70. {
  71. char tmp_char[16] = {0};
  72. char bcd_tmp[8] = {0};
  73. char *token[16];
  74. char size_each_token[16] = {0};
  75. unsigned char hh,hl;
  76. unsigned char token_index = 0;
  77. int i = 0;
  78. int index = 0;
  79. int dig_bit_num = 0;
  80. int ptr_each = 0;
  81. unsigned short speed;
  82. unsigned short aspect;
  83. double speed_jie = 0.0;
  84. unsigned char temp;
  85. static unsigned char unLocateCt=0;
  86. memset(token, NULL, sizeof(token));
  87. token[token_index] = buf;
  88. RunMake(THIS_FILE_ID);
  89. while(index < size )
  90. {
  91. if(buf[index] == ',')
  92. {
  93. size_each_token[token_index] = ptr_each;
  94. if(ptr_each == 0)
  95. token[token_index] = NULL;
  96. //*(token[token_index] + ptr_each) = 0; //
  97. ptr_each = 0;
  98. token_index++;
  99. token[token_index] = buf+index+1; //skip this ','
  100. if(*(token[token_index]+1) == '*')
  101. {
  102. size_each_token[token_index] = 1; //cut of *hh\r\n
  103. }
  104. }
  105. else
  106. {
  107. ptr_each++;
  108. }
  109. index++;
  110. }
  111. RunMake(THIS_FILE_ID);
  112. //检测token地址是否合法,有任何一个不合法则丢掉当前NEMA包
  113. //并认定当前包为非定位包
  114. //一般都未定位包才会有地址不对
  115. for(i=GPRMC_UTC1_TOKEN_INDEX;i<GPRMC_UTC2_TOKEN_INDEX;i++)
  116. {
  117. if((token[i] < (char *)RxBuffer3 || //超出范围
  118. token[i]>= (char *)&RxBuffer3[UART3_RX_BUFFER_SIZE]) &&//超出范围
  119. token[i] != NULL)//非空
  120. {//非法地址值
  121. if(unLocateCt <= GPS_UNLOCATE_TIME) unLocateCt++;
  122. else sutGpsInfo.isGpsValid = 0;//持续时间,认为非定位
  123. return;
  124. }
  125. }
  126. //////////////////////////////////////////////////////////////////////////
  127. //UTC time:hms
  128. if(token[GPRMC_UTC1_TOKEN_INDEX])
  129. {
  130. strncpy((char*)tmp_char,(char*)token[0],size_each_token[0]);
  131. translate_digitAscii_to_bcd(tmp_char,6,bcd_tmp); //去掉.xx
  132. //小时需要加8 因为北京是东8区
  133. memcpy(tmp_char, (char*)token[0], 2);
  134. tmp_char[2]=0;
  135. temp=atoi(tmp_char)+8;
  136. //if(temp >= 24) temp -= 24;
  137. hl=temp%10;
  138. hh=temp%100/10;
  139. hh <<= 4;hh &= 0xf0;
  140. sutGpsInfo.hour=(hh | hl);
  141. sutGpsInfo.minu = bcd_tmp[1];
  142. sutGpsInfo.sec = bcd_tmp[2];
  143. }
  144. RunMake(THIS_FILE_ID);
  145. //Fix status
  146. if(token[GPRMC_STATUS_TOKEN_INDEX])
  147. {
  148. memset(tmp_char , 0 ,sizeof(tmp_char));
  149. strncpy((char*)tmp_char,(char*)token[1],size_each_token[1]);
  150. if(*tmp_char == 'A'){
  151. sutGpsInfo.isGpsValid = 1;
  152. unLocateCt=0;
  153. }else{
  154. if(unLocateCt <= GPS_UNLOCATE_TIME) unLocateCt++;
  155. else sutGpsInfo.isGpsValid = 0;//持续时间,认为非定位
  156. }
  157. }
  158. RunMake(THIS_FILE_ID);
  159. if(sutGpsInfo.isGpsValid == 0)return;
  160. //latitude 纬度
  161. /*=====================================
  162. UTC time:hms status latitue north? longitue east? 速度(节) 方位角 UTC time 磁偏角 方向 模式 checksum
  163. $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
  164. For example: $GPRMC,024813.640,A,3158.4608,N,11848.3737,E,010.5,324.7,150706,,,A*50
  165. */
  166. if(token[GPRMC_LATITUE_TOKEN_INDEX])
  167. {
  168. RunMake(THIS_FILE_ID);
  169. memset(tmp_char , 0 ,sizeof(tmp_char));
  170. memset(bcd_tmp , 0 ,sizeof(bcd_tmp));
  171. strncpy((char*)(tmp_char+1),(char*)token[2],size_each_token[2]);
  172. tmp_char[0] = '0';
  173. RunMake(THIS_FILE_ID);
  174. for(i = 5; i < 8;i++)
  175. tmp_char[i] = tmp_char[i+1];
  176. tmp_char[8] = 0; //小数点后面去掉最后1位
  177. translate_digitAscii_to_bcd(tmp_char,8,bcd_tmp); //去掉.xx
  178. //North or south
  179. memset(tmp_char , 0 ,sizeof(tmp_char));
  180. if(token[GPRMC_NORTH_TOKEN_INDEX])
  181. {
  182. strncpy((char*)tmp_char,(char*)token[3],size_each_token[3]);
  183. if(*tmp_char == 'S')
  184. bcd_tmp[0] |= 0x80;
  185. sutGpsInfo.latitue = (bcd_tmp[3] | (bcd_tmp[2] << 8) |(bcd_tmp[1] << 16) |(bcd_tmp[0] << 24));
  186. }
  187. RunMake(THIS_FILE_ID);
  188. }
  189. //longitude 经度
  190. if(token[GPRMC_longitue_TOKEN_INDEX])
  191. {
  192. memset(tmp_char , 0 ,sizeof(tmp_char));
  193. memset(bcd_tmp , 0 ,sizeof(bcd_tmp));
  194. RunMake(THIS_FILE_ID);
  195. strncpy((char*)tmp_char,(char*)token[4],size_each_token[4]);
  196. for(i = 5; i < 8;i++)
  197. tmp_char[i] = tmp_char[i+1];
  198. tmp_char[8] = 0;
  199. translate_digitAscii_to_bcd(tmp_char,8,bcd_tmp); //去掉.xx
  200. RunMake(THIS_FILE_ID);
  201. //east or west
  202. if(token[GPRMC_EAST_TOKEN_INDEX])
  203. {
  204. memset(tmp_char , 0 ,sizeof(tmp_char));
  205. strncpy((char*)tmp_char,(char*)token[5],size_each_token[5]);
  206. if(*tmp_char == 'W')
  207. bcd_tmp[0] |= 0x80;
  208. sutGpsInfo.longitue = (bcd_tmp[3] | (bcd_tmp[2] << 8) |(bcd_tmp[1] << 16) |(bcd_tmp[0] << 24));
  209. }
  210. }
  211. //Speed
  212. if(token[GPRMC_SPEED_TOKEN_INDEX])
  213. {
  214. RunMake(THIS_FILE_ID);
  215. memset(tmp_char , 0 ,sizeof(tmp_char));
  216. strncpy((char*)tmp_char,(char*)token[GPRMC_SPEED_TOKEN_INDEX],size_each_token[GPRMC_SPEED_TOKEN_INDEX]);
  217. index = 0;
  218. while(index < size_each_token[GPRMC_SPEED_TOKEN_INDEX])
  219. {
  220. if(tmp_char[index] == '.')
  221. break;
  222. index++;
  223. }
  224. dig_bit_num = size_each_token[GPRMC_SPEED_TOKEN_INDEX]-index-1;
  225. //这里,index代表小数点前有多少位,dig_bit_num代表小数点后面有多少位
  226. RunMake(THIS_FILE_ID);
  227. //ol_debug("dig_bit_num:%d,all len:%d",dig_bit_num,size_each_token[GPRMC_SPEED_TOKEN_INDEX]);
  228. if(index == 3)
  229. {
  230. speed_jie = (tmp_char[0]-0x30)*100
  231. + (tmp_char[1]-0x30)*10
  232. + (tmp_char[2]-0x30);
  233. }
  234. else if(index == 2)
  235. {
  236. speed_jie = (tmp_char[0]-0x30)*10
  237. + (tmp_char[1]-0x30);
  238. }
  239. else
  240. speed_jie = (tmp_char[0]-0x30);
  241. if(dig_bit_num > 0)
  242. speed_jie += (tmp_char[index+1]-0x30)*0.1;
  243. speed = (unsigned short)(speed_jie*1.852);
  244. sutGpsInfo.speed = ( ((speed/100)<<8) | (((speed /10)%10)<<4) | (speed %10) );
  245. //ol_debug("speed_jie to speed:%d,xinan speed:%d",speed,sutGpsInfo.speed);
  246. }
  247. RunMake(THIS_FILE_ID);
  248. //Aspect 方向
  249. if(token[GPRMC_ASPECT_TOKEN_INDEX])
  250. {
  251. memset(tmp_char , 0 ,sizeof(tmp_char));
  252. strncpy((char*)tmp_char,(char*)token[GPRMC_ASPECT_TOKEN_INDEX],size_each_token[GPRMC_ASPECT_TOKEN_INDEX]);
  253. aspect = (unsigned short)((tmp_char[0]-0x30)*100
  254. + (tmp_char[1]-0x30)*10
  255. + (tmp_char[2]-0x30));
  256. sutGpsInfo.aspect= ( ((aspect/100) << 8) | (((aspect /10)%10)<<4) | (aspect %10) );
  257. }
  258. RunMake(THIS_FILE_ID);
  259. //UTC2
  260. if(token[GPRMC_UTC2_TOKEN_INDEX])
  261. {
  262. memset(tmp_char , 0 ,sizeof(tmp_char));
  263. memset(bcd_tmp , 0 ,sizeof(bcd_tmp));
  264. strncpy((char*)tmp_char,(char*)token[GPRMC_UTC2_TOKEN_INDEX],size_each_token[GPRMC_UTC2_TOKEN_INDEX]);
  265. translate_digitAscii_to_bcd(tmp_char,6,bcd_tmp);
  266. sutGpsInfo.day = bcd_tmp[0];
  267. sutGpsInfo.month= bcd_tmp[1];
  268. sutGpsInfo.year = bcd_tmp[2];
  269. }
  270. }
  271. #if(GPS_VIRTUAL_VALUE==1)
  272. static unsigned char sucTimeH,sucTimeL;
  273. static unsigned long susTime=(7*3600+30*60+0);
  274. static unsigned long sucLatitue=0x02237542;//;
  275. static unsigned long sucLongitue=0x11401316;//;
  276. #endif
  277. /*************************************************************************************
  278. * 根据GPS模块返回的nema数据,提取并放入sutGpsInfo中
  279. **************************************************************************************/
  280. void process_nema(char *nema)
  281. {
  282. unsigned char len;
  283. //$GPRMC
  284. if(nema[0] != '$' ||
  285. nema[1] != 'G' ||
  286. nema[3] != 'R' ||
  287. nema[4] != 'M' ||
  288. nema[5] != 'C') return;
  289. len=strlen(&nema[7]);
  290. process_gps_data(&nema[7],len);
  291. sutGpsInfo.isGpsWork=1;
  292. sutGpsInfo.GpsInactiveCt=0;
  293. #if(GPS_VIRTUAL_VALUE==1)
  294. if(sutGpsInfo.isGpsValid==0){
  295. sutGpsInfo.isGpsValid=1;
  296. sutGpsInfo.latitue=sucLatitue;
  297. sutGpsInfo.longitue=sucLongitue;
  298. sutGpsInfo.speed=0x4321;
  299. sutGpsInfo.aspect=0x7654;
  300. sutGpsInfo.StatisticsMile=0x123456;
  301. sutGpsInfo.year=0x15;
  302. sutGpsInfo.month=0x07;
  303. sutGpsInfo.day=0x26;
  304. susTime++;
  305. sutGpsInfo.hour=(unsigned char)(susTime/3600);
  306. sutGpsInfo.minu=(unsigned char)((susTime%3600)/60);
  307. sutGpsInfo.sec=(unsigned char)(susTime%60);
  308. sucTimeH=sutGpsInfo.hour/10;
  309. sucTimeL=sutGpsInfo.hour%10;
  310. sutGpsInfo.hour=(sucTimeH<<4)+sucTimeL;
  311. sucTimeH=sutGpsInfo.minu/10;
  312. sucTimeL=sutGpsInfo.minu%10;
  313. sutGpsInfo.minu=(sucTimeH<<4)+sucTimeL;
  314. sucTimeH=sutGpsInfo.sec/10;
  315. sucTimeL=sutGpsInfo.sec%10;
  316. sutGpsInfo.sec=(sucTimeH<<4)+sucTimeL;
  317. }
  318. #endif
  319. }