GPS.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. /**********************************************************************************
  2. * File Name: GPS.c
  3. * Function Describe:device for GPS
  4. * Relate Module:
  5. ***********************************************************************************/
  6. #define THIS_FILE_ID 112
  7. /* Includes ------------------------------------------------------------------*/
  8. #include "GPS.h"
  9. #include "includes.h"
  10. SUT_GPS_INF sutGpsInfo;
  11. const static unsigned char SetBDEnCmd[]={
  12. 0xB5,0x62,0x06,0x3E,0x2C,0x00,0x00,0x00,0x20,0x05,0x00,0x08,0x10,0x00,0x01,0x00,0x01,0x01,0x01,0x01,0x03,0x00,0x00,0x00,0x01,0x01,0x03,
  13. 0x08,0x10,0x00,0x01,0x00,0x01,0x01,0x05,0x00,0x03,0x00,0x00,0x00,0x01,0x01,0x06,0x08,0x0E,0x00,0x00,0x00,0x01,0x01,0xFD,0x25,0xB5,0x62,
  14. 0x06,0x17,0x14,0x00,0x00,0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x75,0x50,0xB5,
  15. 0x62,0x05,0x01,0x02,0x00,0x06,0x17,0x25,0x4E
  16. };
  17. void GpsInit(void)
  18. {
  19. GPIO_InitTypeDef GPIO_InitStructure;
  20. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
  21. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  22. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  23. GPIO_InitStructure.GPIO_Pin = GPS_PWR_PIN;
  24. GPIO_Init(GPS_PWR_PORT, &GPIO_InitStructure);
  25. memset(&sutGpsInfo,0,sizeof(SUT_GPS_INF));
  26. GPS_PWR_DIS;
  27. FEED_EXTWATCHDOG();//喂狗
  28. IWDG_ReloadCounter();//喂狗
  29. os_dly_wait(50);
  30. FEED_EXTWATCHDOG();//喂狗
  31. IWDG_ReloadCounter();//喂狗
  32. GPS_PWR_EN;
  33. RunMake(THIS_FILE_ID);
  34. os_dly_wait(1);
  35. Uart2Init();
  36. #if GPS_TYPE==GPS_TYPE_UBLOX //UBlox方案才需要发如下指令给GPS模块,启动北斗功能
  37. os_dly_wait(50);
  38. FEED_EXTWATCHDOG();//喂狗
  39. IWDG_ReloadCounter();//喂狗
  40. Uart2Send((char *)SetBDEnCmd,sizeof(SetBDEnCmd));
  41. os_dly_wait(50);
  42. FEED_EXTWATCHDOG();//喂狗
  43. IWDG_ReloadCounter();//喂狗
  44. Uart2Send((char *)SetBDEnCmd,sizeof(SetBDEnCmd));
  45. #endif
  46. }
  47. int HEX_2_INT32(int hex_val)
  48. {
  49. char tmp_buf[13] = {0};
  50. int val;
  51. sprintf(tmp_buf, "%x", hex_val);
  52. val = atoi (tmp_buf);
  53. return val;
  54. }
  55. static unsigned char translate_digitAscii_to_bcd(char *ascii_number, unsigned char len, char *bcd_number)
  56. {
  57. int i, j;
  58. char temp[10] = ""; /* extra + and NULL */
  59. unsigned char bcd_index = 0; /* Index into output bcd_number */
  60. int num_len = len;
  61. /* Translate or skip over invalid characters */
  62. for (i = 0, j = 0; i < num_len; i++)
  63. {
  64. temp[j++] = ascii_number[i] & 0x0F;
  65. }
  66. ascii_number[len] = 0;
  67. /* Now that temp has the bcd codes in natural order... Squish them together
  68. * and reverse the order per bcd coding.
  69. */
  70. for (i = 0; i < j; i+=2)
  71. bcd_number[bcd_index++] = ((char)(temp[i] << 4)) | temp[i+1];
  72. bcd_number[len] = 0;
  73. return 0;
  74. }
  75. /*=====================================
  76. UTC time:hms status latitue north? longitue east? ??(?) ??? UTC time ??? ?? ?? checksum
  77. $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
  78. For example: $GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50
  79. */
  80. #define GPRMC_UTC1_TOKEN_INDEX 0
  81. #define GPRMC_STATUS_TOKEN_INDEX 1
  82. #define GPRMC_LATITUE_TOKEN_INDEX 2
  83. #define GPRMC_NORTH_TOKEN_INDEX 3
  84. #define GPRMC_longitue_TOKEN_INDEX 4
  85. #define GPRMC_EAST_TOKEN_INDEX 5
  86. #define GPRMC_SPEED_TOKEN_INDEX 6
  87. #define GPRMC_ASPECT_TOKEN_INDEX 7
  88. #define GPRMC_UTC2_TOKEN_INDEX 8
  89. /*
  90. 从str找到第一个字符为ch的位置返回其位置
  91. 位置从0开始计算
  92. */
  93. int FindChIndex(char *str,char ch)
  94. {
  95. char *p=str;
  96. int i=0;
  97. while(*p){
  98. if(*p==ch)return i;
  99. i++;
  100. p++;
  101. }
  102. }
  103. /*************************************************************************************
  104. *process_gps_number
  105. 获取卫星个数
  106. $GPGSA,A,3,33,14,22,27,31,32,08,35,21,,,,1.6,1.1,1.2*38
  107. $BDGSA,A,3,01,02,03,04,08,09,13,06,,,,,1.6,1.1,1.2*26
  108. **************************************************************************************/
  109. void process_gps_number(char *buf,uint32_t size)
  110. {
  111. int flag=0;
  112. int i,j,num;
  113. char ch,ch1,ch2;
  114. if(buf[1]=='G' && buf[2]=='P')flag=1;
  115. else if(buf[1]=='B' && buf[2]=='D') flag=2;
  116. else return;
  117. i=11;j=0;num=0;
  118. while(i<size && j<11){
  119. ch=buf[i];
  120. if(ch==','){
  121. i++;
  122. j++;
  123. }else if(ch>='0' && ch<='9'){
  124. i+=2;
  125. num++;
  126. }else{//非法
  127. break;
  128. }
  129. }
  130. if(flag==1){
  131. sutGpsInfo.GPSNum=num;
  132. }else if(flag==2){
  133. sutGpsInfo.BDNum=num;
  134. }
  135. }
  136. /*************************************************************************************
  137. *process_gps_data
  138. **************************************************************************************/
  139. void process_gps_data(char *buf,uint32_t size)
  140. {
  141. char tmp_char[16] = {0};
  142. char bcd_tmp[8] = {0};
  143. char *token[16] = {NULL};
  144. char size_each_token[16] = {0};
  145. unsigned char hh,hl;
  146. unsigned char token_index = 0;
  147. char ch;
  148. int i = 0;
  149. int index = 0;
  150. int dig_bit_num = 0;
  151. int ptr_each = 0;
  152. unsigned short speed;
  153. unsigned short aspect;
  154. double speed_jie = 0.0;
  155. token[token_index] = buf;
  156. RunMake(THIS_FILE_ID);
  157. while(index < size )
  158. {
  159. if(buf[index] == ',')
  160. {
  161. size_each_token[token_index] = ptr_each;
  162. if(ptr_each == 0)
  163. token[token_index] = NULL;
  164. ptr_each = 0;
  165. token_index++;
  166. token[token_index] = buf+index+1; //skip this ','
  167. if(*(token[token_index]+1) == '*')
  168. {
  169. size_each_token[token_index] = 1; //cut of *hh\r\n
  170. }
  171. }
  172. else
  173. {
  174. ptr_each++;
  175. }
  176. index++;
  177. }
  178. RunMake(THIS_FILE_ID);
  179. //UTC time:hms
  180. //014216 = 01:42:16
  181. if(token[GPRMC_UTC1_TOKEN_INDEX])
  182. { //,040831.00, 一般长度为9
  183. if(size_each_token[0]<6 && size_each_token[0]>10){
  184. //printf("GPS Error1 %d\r\n",size_each_token[0]);
  185. return;
  186. }
  187. strncpy((char*)tmp_char,(char*)token[0],size_each_token[0]);
  188. translate_digitAscii_to_bcd(tmp_char,6,bcd_tmp); //??.xx
  189. sutGpsInfo.hour=bcd_tmp[0];
  190. sutGpsInfo.minu = bcd_tmp[1];
  191. sutGpsInfo.sec = bcd_tmp[2];
  192. }
  193. RunMake(THIS_FILE_ID);
  194. //UTC2
  195. //250219 = 19-02-25
  196. if(token[GPRMC_UTC2_TOKEN_INDEX])
  197. {
  198. memset(tmp_char , 0 ,sizeof(tmp_char));
  199. memset(bcd_tmp , 0 ,sizeof(bcd_tmp));
  200. if(size_each_token[GPRMC_UTC2_TOKEN_INDEX]!=6){
  201. //printf("GPS Error2\r\n");
  202. return;
  203. }
  204. strncpy((char*)tmp_char,(char*)token[GPRMC_UTC2_TOKEN_INDEX],size_each_token[GPRMC_UTC2_TOKEN_INDEX]);
  205. translate_digitAscii_to_bcd(tmp_char,6,bcd_tmp);
  206. sutGpsInfo.day = bcd_tmp[0];
  207. sutGpsInfo.month= bcd_tmp[1];
  208. sutGpsInfo.year = bcd_tmp[2];
  209. }
  210. RunMake(THIS_FILE_ID);
  211. //Fix status
  212. if(token[GPRMC_STATUS_TOKEN_INDEX])
  213. {
  214. memset(tmp_char , 0 ,sizeof(tmp_char));
  215. if(size_each_token[1]!=1){
  216. SlwTrace(DEBUG,"GpsDataError!\r\n");
  217. return;
  218. }
  219. strncpy((char*)tmp_char,(char*)token[1],size_each_token[1]);
  220. if(*tmp_char == 'A'){
  221. sutGpsInfo.isGpsValid = 1;
  222. }else{
  223. sutGpsInfo.isGpsValid = 0;
  224. sutGpsInfo.Altitude=0;
  225. sutGpsInfo.Latitude=0;
  226. sutGpsInfo.Longitude=0;
  227. sutGpsInfo.Aspect=0;
  228. sutGpsInfo.Speed=0;
  229. return;
  230. }
  231. }
  232. RunMake(THIS_FILE_ID);
  233. //latitude ??
  234. /*=====================================
  235. UTC time:hms status latitue north? longitue east? ??(?) ??? UTC time ??? ?? ?? checksum
  236. $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
  237. For example: $GPRMC,024813.640,A,3158.4608,N,11848.3737,E,010.5,324.7,150706,,,A*50
  238. */
  239. if(token[GPRMC_LATITUE_TOKEN_INDEX])
  240. {
  241. ch=*token[GPRMC_NORTH_TOKEN_INDEX];
  242. char *p=token[GPRMC_LATITUE_TOKEN_INDEX];
  243. //Ublox格式:ddmm.mmmmm
  244. //中科微电格式:ddmm.mmmm
  245. int ddmm=atoi(p);
  246. int mmmmm=atoi((p+5));
  247. int dd=ddmm/100;
  248. int mm=ddmm%100;
  249. //double fmm=(double)mm+(double)mmmmm/100000.0;
  250. //sutGpsInfo.latitude=(double)dd+fmm/60.0;
  251. sutGpsInfo.Latitude=dd*1000000;//度 放大1000000倍,整数部分
  252. mm*=1000000;
  253. #if GPS_TYPE==GPS_TYPE_UBLOX
  254. mmmmm*=10;
  255. #else
  256. mmmmm*=100;
  257. #endif
  258. mm+=mmmmm;//分 放大1000000倍
  259. dd=mm/60;//度 放大1000000倍 小数部分
  260. sutGpsInfo.Latitude+=dd;//度 放大1000000倍
  261. if(ch=='S'){
  262. sutGpsInfo.South=1;
  263. }else{
  264. sutGpsInfo.South=0;
  265. }
  266. //sprintf(sutGpsInfo.vv1,"%d%d.%d\r\n",dd,mm,mmmm);
  267. }
  268. //longitude ??
  269. if(token[GPRMC_longitue_TOKEN_INDEX])
  270. {//dddmm.mmmmm,E/W
  271. #if 0
  272. memset(tmp_char , 0 ,sizeof(tmp_char));
  273. memset(bcd_tmp , 0 ,sizeof(bcd_tmp));
  274. RunMake(THIS_FILE_ID);
  275. strncpy((char*)tmp_char,(char*)token[4],size_each_token[4]);
  276. for(i = 5; i < 8;i++)
  277. tmp_char[i] = tmp_char[i+1];
  278. tmp_char[8] = 0;
  279. translate_digitAscii_to_bcd(tmp_char,8,bcd_tmp); //??.xx
  280. RunMake(THIS_FILE_ID);
  281. //east or west
  282. if(token[GPRMC_EAST_TOKEN_INDEX])
  283. {
  284. memset(tmp_char , 0 ,sizeof(tmp_char));
  285. strncpy((char*)tmp_char,(char*)token[5],size_each_token[5]);
  286. sutGpsInfo.EWFlag=*tmp_char;
  287. sutGpsInfo.longitude = (bcd_tmp[3] | (bcd_tmp[2] << 8) |(bcd_tmp[1] << 16) |(bcd_tmp[0] << 24));
  288. }
  289. #else
  290. ch=*token[GPRMC_EAST_TOKEN_INDEX];
  291. if(ch=='W')sutGpsInfo.West=1;
  292. else sutGpsInfo.West=0;
  293. char *p=token[GPRMC_longitue_TOKEN_INDEX];
  294. int dddmm=atoi(p);
  295. int mmmmm=atoi((p+6));
  296. int ddd=dddmm/100;
  297. int mm=dddmm%100;
  298. //double fmm=(double)mm+(double)mmmmm/100000.0;
  299. //sutGpsInfo.longitude=(double)ddd+fmm/60.0;
  300. sutGpsInfo.Longitude=ddd*1000000;//度 放大1000000倍 整数部分
  301. mm*=1000000;
  302. #if GPS_TYPE==GPS_TYPE_UBLOX
  303. mmmmm*=10;
  304. #else
  305. mmmmm*=100;
  306. #endif
  307. mm+=mmmmm;//分 放大1000000倍
  308. ddd=mm/60;//度 放大1000000倍 小数部分
  309. sutGpsInfo.Longitude+=ddd;
  310. #endif
  311. }
  312. //Speed
  313. //0.094
  314. if(token[GPRMC_SPEED_TOKEN_INDEX])
  315. {
  316. RunMake(THIS_FILE_ID);
  317. memset(tmp_char , 0 ,sizeof(tmp_char));
  318. strncpy((char*)tmp_char,(char*)token[GPRMC_SPEED_TOKEN_INDEX],size_each_token[GPRMC_SPEED_TOKEN_INDEX]);
  319. index = 0;
  320. while(index < size_each_token[GPRMC_SPEED_TOKEN_INDEX])
  321. {
  322. if(tmp_char[index] == '.')break;
  323. index++;
  324. }
  325. dig_bit_num = size_each_token[GPRMC_SPEED_TOKEN_INDEX]-index-1;
  326. RunMake(THIS_FILE_ID);
  327. speed_jie = atoi(tmp_char);
  328. if(dig_bit_num>0)speed_jie += (tmp_char[index+1]-0x30)*0.1;
  329. //sutGpsInfo.Speed=(int)(speed_jie/0.1852);// 1/10 km/h
  330. sutGpsInfo.Speed=(int)(speed_jie*18.52);// 1/10 km
  331. }
  332. RunMake(THIS_FILE_ID);
  333. //Aspect ??
  334. if(token[GPRMC_ASPECT_TOKEN_INDEX])
  335. {
  336. memset(tmp_char , 0 ,sizeof(tmp_char));
  337. if(size_each_token[GPRMC_ASPECT_TOKEN_INDEX]==0){
  338. sutGpsInfo.Aspect=0;
  339. }else{
  340. strncpy((char*)tmp_char,(char*)token[GPRMC_ASPECT_TOKEN_INDEX],size_each_token[GPRMC_ASPECT_TOKEN_INDEX]);
  341. aspect=atoi(tmp_char);
  342. sutGpsInfo.Aspect= aspect;
  343. }
  344. }else sutGpsInfo.Aspect=0;
  345. RunMake(THIS_FILE_ID);
  346. }
  347. #ifdef GPS_DEBUG_VALID
  348. static unsigned char sucTimeH,sucTimeL;
  349. static unsigned long susTime=(7*3600+30*60+0);
  350. static unsigned long sucLatitue=0x02237542;//;
  351. static unsigned long sucLongitue=0x11401316;//;
  352. #endif
  353. /*************************************************************************************
  354. process_nema
  355. **************************************************************************************/
  356. void process_nema(char *nema)
  357. {
  358. static int susTime=61200;
  359. uint8_t sucTimeH,sucTimeL;
  360. static unsigned char sucCt=0;
  361. int len;
  362. len=strlen(nema);
  363. //$GPRMC or $GNRMC or $GPGSA or $BDGSA
  364. if(nema[0]!='$')return;
  365. if(nema[3]=='R' && nema[4]=='M' && nema[5]=='C'){
  366. //获取时间、经纬度、速度、方位
  367. process_gps_data(&nema[7],len);
  368. }
  369. // else if(nema[3]=='G' && nema[4]=='S' && nema[5]=='A'){
  370. // //获取使用卫星个数
  371. // process_gps_number(&nema[0],len);
  372. // }
  373. #ifdef GPS_DEBUG_VALID
  374. SlwTrace(DEBUG,"GPS_DEBUG_VALID!!!");
  375. if(sutGpsInfo.isGpsValid==0){
  376. sutGpsInfo.isGpsValid=1;
  377. sutGpsInfo.latitue=sucLatitue;
  378. sutGpsInfo.longitue=sucLongitue;
  379. sutGpsInfo.speed=0x4321;
  380. sutGpsInfo.aspect=0x7654;
  381. sutGpsInfo.StatisticsMile=0x123456;
  382. sutGpsInfo.year=0x15;
  383. sutGpsInfo.month=0x07;
  384. sutGpsInfo.day=0x26;
  385. susTime++;
  386. sutGpsInfo.hour=(unsigned char)(susTime/3600);
  387. sutGpsInfo.minu=(unsigned char)((susTime%3600)/60);
  388. sutGpsInfo.sec=(unsigned char)(susTime%60);
  389. sucTimeH=sutGpsInfo.hour/10;
  390. sucTimeL=sutGpsInfo.hour%10;
  391. sutGpsInfo.hour=(sucTimeH<<4)+sucTimeL;
  392. sucTimeH=sutGpsInfo.minu/10;
  393. sucTimeL=sutGpsInfo.minu%10;
  394. sutGpsInfo.minu=(sucTimeH<<4)+sucTimeL;
  395. sucTimeH=sutGpsInfo.sec/10;
  396. sucTimeL=sutGpsInfo.sec%10;
  397. sutGpsInfo.sec=(sucTimeH<<4)+sucTimeL;
  398. }
  399. #endif
  400. }
  401. /*
  402. UTC(BCD) 时间转换为 北京时间
  403. unsigned short Years;
  404. char Months;
  405. char Days;
  406. char Hours;
  407. char Minute;
  408. char Seconds;
  409. */
  410. void GpsConversionTime(void)
  411. {
  412. unsigned short t;
  413. if(sutGpsInfo.year==0){
  414. sutGpsInfo.Years=0;
  415. sutGpsInfo.Months=0;
  416. sutGpsInfo.Days=0;
  417. sutGpsInfo.Hours=0;
  418. sutGpsInfo.Minute=0;
  419. sutGpsInfo.Seconds=0;
  420. return;
  421. }
  422. #if 0 //test
  423. sutGpsInfo.year=0x19;
  424. sutGpsInfo.month=0x02;
  425. sutGpsInfo.day=0x28;
  426. sutGpsInfo.hour=0x20;
  427. #endif
  428. t=sutGpsInfo.year>>4;
  429. t*=10;
  430. t+=(sutGpsInfo.year&0x0f);
  431. sutGpsInfo.Years=2000+t;
  432. t=sutGpsInfo.month>>4;
  433. t*=10;
  434. t+=(sutGpsInfo.month&0x0f);
  435. sutGpsInfo.Months=t;
  436. t=sutGpsInfo.day>>4;
  437. t*=10;
  438. t+=(sutGpsInfo.day&0x0f);
  439. sutGpsInfo.Days=t;
  440. t=sutGpsInfo.hour>>4;
  441. t*=10;
  442. t+=(sutGpsInfo.hour&0x0f);
  443. sutGpsInfo.Hours=t;
  444. t=sutGpsInfo.minu>>4;
  445. t*=10;
  446. t+=(sutGpsInfo.minu&0x0f);
  447. sutGpsInfo.Minute=t;
  448. t=sutGpsInfo.sec>>4;
  449. t*=10;
  450. t+=(sutGpsInfo.sec&0x0f);
  451. sutGpsInfo.Seconds=t;
  452. //转换为北京时间
  453. sutGpsInfo.Hours+=8;
  454. if(sutGpsInfo.Hours>23){
  455. sutGpsInfo.Hours-=24;
  456. if(++sutGpsInfo.Days>MonthDays(sutGpsInfo.Years,sutGpsInfo.Months)){
  457. sutGpsInfo.Days=1;
  458. if(++sutGpsInfo.Months>12){
  459. sutGpsInfo.Months=1;
  460. sutGpsInfo.Years++;
  461. }
  462. }
  463. }
  464. }