ubuntu c语言 读取GPS数据,并写入txt文件中
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<sys/types.h> 5 #include<sys/stat.h> 6 #include<fcntl.h> 7 #include<unistd.h> 8 #include<termios.h> 9 #include<string.h> 10 // 测试时使用的文件 11 #define SRC_FILE_NAME (const char *)"GPS.txt" 12 // 文件头预留64个字节 13 #define FILE_HEADER_LEN 64 14 15 #define uchar unsigned char 16 #define uint unsigned int 17 18 typedef struct{ 19 int year; 20 int month; 21 int day; 22 int hour; 23 int minute; 24 int second; 25 }DATE_TIME; 26 27 typedef struct{ 28 double latitude; //经度 29 double longitude; //纬度 30 int latitude_Degree; //度 31 int latitude_Cent; //分 32 int latitude_Second; //秒 33 int longitude_Degree; //度 34 int longitude_Cent; //分 35 int longitude_Second; //秒 36 float speed; //速度 37 float direction; //航向 38 float height_ground; //水平面高度 39 float height_sea; //海拔高度 40 uchar NS; 41 uchar EW; 42 DATE_TIME D; 43 uchar status; //接收状态 44 int GPS_Num; //使用卫星个数 45 }GPS_INFO; 46 47 48 GPS_INFO gps_info;//存储GPS信息变量 49 50 static uchar GetComma(uchar num,char* str); 51 static double Get_Double_Number(char *s); 52 static float Get_Float_Number(char *s); 53 static void UTC2BTC(DATE_TIME *GPS); 54 55 int GPS_RMC_Parse(char *line,GPS_INFO *GPS); 56 int GPS_GGA_Parse(char *line,GPS_INFO *GPS); 57 58 void Int_To_Str(int x,char *Str); 59 60 /*============================================================================== 61 函 数 名 : GetFile 62 功 能 : 获取文件句柄 63 算法实现 : 无 64 参 数 : [in] const char *pFileName - 文件名 65 返 回 值 : 成功-得到的文件句柄,失败-NULL 66 日 期 : 2011/02/11 67 作 者 : jernymy 68 ==============================================================================*/ 69 static FILE *GetFile(const char *pFileName) 70 { 71 // 使用rt+的方式打开文件 72 FILE *fpSrc = fopen(pFileName, "rt+"); 73 74 if (NULL != fpSrc) 75 { 76 // 文件存在 77 return fpSrc; 78 } 79 printf("open %s \"rt\" fail, may be create first!/n", pFileName); 80 // 创建文件 81 fpSrc = fopen(pFileName, "wt"); 82 if (NULL != fpSrc) 83 { 84 // 文件创建成功 85 printf("create %s \"wt\" succ, pointer:%p!/n", pFileName, fpSrc); 86 } 87 else 88 { 89 // 文件创建失败 90 printf("create %s \"wt\" fail, pointer:%p!/n", pFileName, fpSrc); 91 } 92 return fpSrc; 93 } 94 95 /*============================================================================== 96 函 数 名 : WriteFile 97 功 能 : 写文件操作 98 算法实现 : 无 99 参 数 : [in] const char *pFileName - 文件名 100 [in] const char *pchStr - 写入的字符串buffer 101 返 回 值 : 成功-0,失败--1 102 日 期 : 2011/02/11 103 作 者 : jernymy 104 ==============================================================================*/ 105 static int WriteFile(const char *pFileName, const char *pchStr) 106 { 107 FILE *fpSrc = NULL; 108 int nFileLen; 109 if (NULL == pFileName) 110 { 111 printf("pFileName is NULL, exit!/n"); 112 return -1; 113 } 114 if (NULL == pchStr) 115 { 116 printf("pchStr is NULL, exit!/n"); 117 return -1; 118 } 119 fpSrc = GetFile(pFileName); 120 if (NULL == fpSrc) 121 { 122 printf("get file fail! exit/n"); 123 return -1; 124 } 125 126 // 得到文件大小-文件长度 127 fseek(fpSrc, 0L, SEEK_END); 128 nFileLen = ftell(fpSrc); 129 // 写文件头后面部分 130 if (0 == nFileLen) 131 { 132 nFileLen = FILE_HEADER_LEN; 133 } 134 fseek(fpSrc, nFileLen, SEEK_SET); 135 if (FILE_HEADER_LEN == nFileLen) 136 { 137 fprintf(fpSrc, "\n");//用于写文件头部分 138 } 139 fprintf(fpSrc, "%s\n", pchStr); 140 // 写文件头部分 141 fseek(fpSrc, 0L, SEEK_END); 142 nFileLen = ftell(fpSrc); 143 fseek(fpSrc, 0L, SEEK_SET); 144 fprintf(fpSrc, "#FavorGPS#File size:%09d", nFileLen); 145 // 关闭文件 146 if (NULL != fpSrc) 147 { 148 fclose(fpSrc); 149 fpSrc = NULL; 150 } 151 return 0; 152 } 153 154 void show_gps(GPS_INFO *GPS) 155 { 156 printf("STATUS : %c\n",GPS->status); 157 printf("DATE : %4d-%02d-%02d \n",GPS->D.year,GPS->D.month,GPS->D.day); 158 printf("TIME : %02d:%02d:%02d \n",GPS->D.hour,GPS->D.minute,GPS->D.second); 159 printf("Latitude : %10.8f %c\n",GPS->latitude,GPS->NS); 160 printf("Longitude: %10.8f %c\n",GPS->longitude,GPS->EW); 161 printf("high : %10.4f \n",GPS->height_sea); 162 printf("Speed : %10.4f Km/h\n",GPS->speed); 163 printf("GPS_Num : %2d\n",GPS->GPS_Num); 164 // 165 if(GPS->status=='A') 166 { 167 char pchStr[1024]; 168 sprintf(pchStr,"%4d-%02d-%02d %02d:%02d:%02d|%10.8f %c|%10.8f %c|%10.4f",GPS->D.year,GPS->D.month,GPS->D.day,GPS->D.hour,GPS->D.minute,GPS->D.second,GPS->latitude,GPS->NS,GPS->longitude,GPS->EW,GPS->height_sea); 169 170 WriteFile(SRC_FILE_NAME, pchStr); //写GPS信息到文件 171 } 172 } 173 //====================================================================// 174 // 语法格式:int GPS_RMC_Parse(char *line, GPS_INFO *GPS) 175 // 实现功能:把gps模块的GPRMC信息解析为可识别的数据 176 // 参 数:存放原始信息字符数组、存储可识别数据的结构体 177 // 返 回 值: 178 // 1: 解析GPRMC完毕 179 // 0: 没有进行解析,或数据无效 180 //====================================================================// 181 int GPS_RMC_Parse(char *line,GPS_INFO *GPS) 182 { 183 uchar ch, status, tmp; 184 float lati_cent_tmp, lati_second_tmp; 185 float long_cent_tmp, long_second_tmp; 186 float speed_tmp; 187 char *buf = line; 188 ch = buf[5]; 189 status = buf[GetComma(2, buf)]; 190 GPS->status =status; 191 if (ch == 'C') //如果第五个字符是C,($GPRMC) 192 { 193 if (status == 'A') //如果数据有效,则分析 194 { 195 GPS -> NS = buf[GetComma(4, buf)]; 196 GPS -> EW = buf[GetComma(6, buf)]; 197 198 GPS->latitude = Get_Double_Number(&buf[GetComma(3, buf)])*0.01; 199 GPS->longitude = Get_Double_Number(&buf[GetComma( 5, buf)])*0.01; 200 201 GPS->latitude_Degree = (int)GPS->latitude / 100; //分离纬度 202 lati_cent_tmp = (GPS->latitude - GPS->latitude_Degree * 100); 203 GPS->latitude_Cent = (int)lati_cent_tmp; 204 lati_second_tmp = (lati_cent_tmp - GPS->latitude_Cent) * 60; 205 GPS->latitude_Second = (int)lati_second_tmp; 206 207 GPS->longitude_Degree = (int)GPS->longitude / 100; //分离经度 208 long_cent_tmp = (GPS->longitude - GPS->longitude_Degree * 100); 209 GPS->longitude_Cent = (int)long_cent_tmp; 210 long_second_tmp = (long_cent_tmp - GPS->longitude_Cent) * 60; 211 GPS->longitude_Second = (int)long_second_tmp; 212 213 speed_tmp = Get_Float_Number(&buf[GetComma(7, buf)]); //速度(单位:海里/时) 214 GPS->speed = speed_tmp * 1.85; //1海里=1.85公里 215 GPS->direction = Get_Float_Number(&buf[GetComma(8, buf)]); //角度 216 217 GPS->D.hour = (buf[7] - '0') * 10 + (buf[8] - '0'); //时间 218 GPS->D.minute = (buf[9] - '0') * 10 + (buf[10] - '0'); 219 GPS->D.second = (buf[11] - '0') * 10 + (buf[12] - '0'); 220 tmp = GetComma(9, buf); 221 GPS->D.day = (buf[tmp + 0] - '0') * 10 + (buf[tmp + 1] - '0'); //日期 222 GPS->D.month = (buf[tmp + 2] - '0') * 10 + (buf[tmp + 3] - '0'); 223 GPS->D.year = (buf[tmp + 4] - '0') * 10 + (buf[tmp + 5] - '0')+2000; 224 225 UTC2BTC(&GPS->D); 226 227 return 1; 228 } 229 } 230 231 return 0; 232 } 233 234 //====================================================================// 235 // 语法格式:int GPS_GGA_Parse(char *line, GPS_INFO *GPS) 236 // 实现功能:把gps模块的GPGGA信息解析为可识别的数据 237 // 参 数:存放原始信息字符数组、存储可识别数据的结构体 238 // 返 回 值: 239 // 1: 解析GPGGA完毕 240 // 0: 没有进行解析,或数据无效 241 //====================================================================// 242 int GPS_GGA_Parse(char *line,GPS_INFO *GPS) 243 { 244 uchar ch, status; 245 char *buf = line; 246 ch = buf[4]; 247 status = buf[GetComma(2, buf)]; 248 if (ch == 'G') //$GPGGA 249 { 250 if (status != ',') 251 { 252 GPS->height_sea = Get_Float_Number(&buf[GetComma(9, buf)]); 253 GPS->height_ground = Get_Float_Number(&buf[GetComma(11, buf)]); 254 GPS->GPS_Num=(int)Get_Double_Number(&buf[GetComma(7, buf)]); 255 return 1; 256 } 257 } 258 259 return 0; 260 } 261 262 //====================================================================// 263 // 语法格式: static float Str_To_Float(char *buf) 264 // 实现功能: 把一个字符串转化成浮点数 265 // 参 数:字符串 266 // 返 回 值:转化后单精度值 267 //====================================================================// 268 static float Str_To_Float(char *buf) 269 { 270 float rev = 0; 271 float dat; 272 int integer = 1; 273 char *str = buf; 274 int i; 275 while(*str != '\0') 276 { 277 switch(*str) 278 { 279 case '0': 280 dat = 0; 281 break; 282 case '1': 283 dat = 1; 284 break; 285 case '2': 286 dat = 2; 287 break; 288 case '3': 289 dat = 3; 290 break; 291 case '4': 292 dat = 4; 293 break; 294 case '5': 295 dat = 5; 296 break; 297 case '6': 298 dat = 6; 299 break; 300 case '7': 301 dat = 7; 302 break; 303 case '8': 304 dat = 8; 305 break; 306 case '9': 307 dat = 9; 308 break; 309 case '.': 310 dat = '.'; 311 break; 312 } 313 if(dat == '.') 314 { 315 integer = 0; 316 i = 1; 317 str ++; 318 continue; 319 } 320 if( integer == 1 ) 321 { 322 rev = rev * 10 + dat; 323 } 324 else 325 { 326 rev = rev + dat / (10 * i); 327 i = i * 10 ; 328 } 329 str ++; 330 } 331 return rev; 332 333 } 334 335 //====================================================================// 336 // 语法格式: static float Get_Float_Number(char *s) 337 // 实现功能: 把给定字符串第一个逗号之前的字符转化成单精度型 338 // 参 数:字符串 339 // 返 回 值:转化后单精度值 340 //====================================================================// 341 static float Get_Float_Number(char *s) 342 { 343 char buf[10]; 344 uchar i; 345 float rev; 346 i=GetComma(1, s); 347 i = i - 1; 348 strncpy(buf, s, i); 349 buf[i] = 0; 350 rev=Str_To_Float(buf); 351 return rev; 352 } 353 354 //====================================================================// 355 // 语法格式: static double Str_To_Double(char *buf) 356 // 实现功能: 把一个字符串转化成浮点数 357 // 参 数:字符串 358 // 返 回 值:转化后双精度值 359 //====================================================================// 360 static double Str_To_Double(char *buf) 361 { 362 double rev = 0; 363 double dat; 364 int integer = 1; 365 char *str = buf; 366 int i; 367 while(*str != '\0') 368 { 369 switch(*str) 370 { 371 case '0': 372 dat = 0; 373 break; 374 case '1': 375 dat = 1; 376 break; 377 case '2': 378 dat = 2; 379 break; 380 case '3': 381 dat = 3; 382 break; 383 case '4': 384 dat = 4; 385 break; 386 case '5': 387 dat = 5; 388 break; 389 case '6': 390 dat = 6; 391 break; 392 case '7': 393 dat = 7; 394 break; 395 case '8': 396 dat = 8; 397 break; 398 case '9': 399 dat = 9; 400 break; 401 case '.': 402 dat = '.'; 403 break; 404 } 405 if(dat == '.') 406 { 407 integer = 0; 408 i = 1; 409 str ++; 410 continue; 411 } 412 if( integer == 1 ) 413 { 414 rev = rev * 10 + dat; 415 } 416 else 417 { 418 rev = rev + dat / (10 * i); 419 i = i * 10 ; 420 } 421 str ++; 422 } 423 return rev; 424 } 425 426 //====================================================================// 427 // 语法格式: static double Get_Double_Number(char *s) 428 // 实现功能:把给定字符串第一个逗号之前的字符转化成双精度型 429 // 参 数:字符串 430 // 返 回 值:转化后双精度值 431 //====================================================================// 432 static double Get_Double_Number(char *s) 433 { 434 char buf[10]; 435 uchar i; 436 double rev; 437 i=GetComma(1, s); 438 i = i - 1; 439 strncpy(buf, s, i); 440 buf[i] = 0; 441 rev=Str_To_Double(buf); 442 return rev; 443 } 444 445 //====================================================================// 446 // 语法格式:static uchar GetComma(uchar num,char *str) 447 // 实现功能:计算字符串中各个逗号的位置 448 // 参 数:查找的逗号是第几个的个数,需要查找的字符串 449 // 返 回 值:0 450 //====================================================================// 451 static uchar GetComma(uchar num,char *str) 452 { 453 uchar i,j = 0; 454 int len=strlen(str); 455 456 for(i = 0;i < len;i ++) 457 { 458 if(str[i] == ',') 459 j++; 460 if(j == num) 461 return i + 1; 462 } 463 464 return 0; 465 } 466 467 //====================================================================// 468 // 语法格式:void UTC2BTC(DATE_TIME *GPS) 469 // 实现功能:转化时间为北京时区的时间 470 // 参 数:存放时间的结构体 471 // 返 回 值:无 472 //====================================================================// 473 static void UTC2BTC(DATE_TIME *GPS) 474 { 475 GPS->second ++; 476 if(GPS->second > 59) 477 { 478 GPS->second = 0; 479 GPS->minute ++; 480 if(GPS->minute > 59) 481 { 482 GPS->minute = 0; 483 GPS->hour ++; 484 } 485 } 486 487 GPS->hour = GPS->hour + 8; 488 if(GPS->hour > 23) 489 { 490 GPS->hour -= 24; 491 GPS->day += 1; 492 if(GPS->month == 2 || 493 GPS->month == 4 || 494 GPS->month == 6 || 495 GPS->month == 9 || 496 GPS->month == 11 ) 497 { 498 if(GPS->day > 30) 499 { 500 GPS->day = 1; 501 GPS->month++; 502 } 503 } 504 else 505 { 506 if(GPS->day > 31) 507 { 508 GPS->day = 1; 509 GPS->month ++; 510 } 511 } 512 if(GPS->year % 4 == 0 ) 513 { 514 if(GPS->day > 29 && GPS->month == 2) 515 { 516 GPS->day = 1; 517 GPS->month ++; 518 } 519 } 520 else 521 { 522 if(GPS->day > 28 &&GPS->month == 2) 523 { 524 GPS->day = 1; 525 GPS->month ++; 526 } 527 } 528 if(GPS->month > 12) 529 { 530 GPS->month -= 12; 531 GPS->year ++; 532 } 533 } 534 } 535 //====================================================================// 536 // 语法格式: Int_To_Str(int x,char *Str) 537 // 实现功能: 转化整型值为字符串形式 538 // 参数: x: 转化的整数 539 // Str:转化后的字符串 540 // 返回值: 无 541 //====================================================================// 542 void Int_To_Str(int x,char *Str) 543 { 544 int t; 545 char *Ptr,Buf[5]; 546 int i = 0; 547 Ptr = Str; 548 if(x < 10) // 当整数小于10时,转化为"0x"的格式 549 { 550 *Ptr ++ = '0'; 551 *Ptr ++ = x+0x30; 552 } 553 else 554 { 555 while(x > 0) 556 { 557 t = x % 10; 558 x = x / 10; 559 Buf[i++] = t+0x30; // 通过计算把数字转化成ASCII码形式 560 } 561 i -- ; 562 for(;i >= 0;i --) // 将得到的字符串倒序 563 { 564 *(Ptr++) = Buf[i]; 565 } 566 } 567 *Ptr = '\0'; 568 } 569 570 int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop) 571 { 572 struct termios newtio,oldtio; 573 if ( tcgetattr( fd,&oldtio) != 0) { 574 perror("SetupSerial 1"); 575 return -1; 576 } 577 bzero( &newtio, sizeof( newtio ) ); 578 newtio.c_cflag |= CLOCAL | CREAD; 579 newtio.c_cflag &= ~CSIZE; 580 581 switch( nBits ) 582 { 583 case 7: 584 newtio.c_cflag |= CS7; 585 break; 586 case 8: 587 newtio.c_cflag |= CS8; 588 break; 589 } 590 591 switch( nEvent ) 592 { 593 case 'O': 594 newtio.c_cflag |= PARENB; 595 newtio.c_cflag |= PARODD; 596 newtio.c_iflag |= (INPCK | ISTRIP); 597 break; 598 case 'E': 599 newtio.c_iflag |= (INPCK | ISTRIP); 600 newtio.c_cflag |= PARENB; 601 newtio.c_cflag &= ~PARODD; 602 break; 603 case 'N': 604 newtio.c_cflag &= ~PARENB; 605 break; 606 } 607 608 switch( nSpeed ) 609 { 610 case 2400: 611 cfsetispeed(&newtio, B2400); 612 cfsetospeed(&newtio, B2400); 613 break; 614 case 4800: 615 cfsetispeed(&newtio, B4800); 616 cfsetospeed(&newtio, B4800); 617 break; 618 case 9600: 619 cfsetispeed(&newtio, B9600); 620 cfsetospeed(&newtio, B9600); 621 break; 622 case 115200: 623 cfsetispeed(&newtio, B115200); 624 cfsetospeed(&newtio, B115200); 625 break; 626 case 460800: 627 cfsetispeed(&newtio, B460800); 628 cfsetospeed(&newtio, B460800); 629 break; 630 default: 631 cfsetispeed(&newtio, B9600); 632 cfsetospeed(&newtio, B9600); 633 break; 634 } 635 if( nStop == 1 ) 636 newtio.c_cflag &= ~CSTOPB; 637 else if ( nStop == 2 ) 638 newtio.c_cflag |= CSTOPB; 639 newtio.c_cc[VTIME] = 0;//重要 640 newtio.c_cc[VMIN] = 100;//返回的最小值 重要 641 tcflush(fd,TCIFLUSH); 642 if((tcsetattr(fd,TCSANOW,&newtio))!=0) 643 { 644 perror("com set error"); 645 return -1; 646 } 647 // printf("set done!\n\r"); 648 return 0; 649 } 650 651 652 int main(void) 653 { 654 int buff_num=0;//缓存中字符数为0 655 int fd1,nset1,nread; 656 char buf[1024]; 657 char buff[100],read_buf[1]; 658 char comName[30]; 659 char comPath[80]="/dev/"; 660 printf("please input COM Name:"); 661 scanf("%s",comName); 662 fd1 = open(strcat(comPath,comName), O_RDWR);//打开串口 663 if (fd1 == -1){ 664 printf("\r\n Open COM Port Falid! \r\n"); 665 exit(1); 666 } 667 668 nset1 = set_opt(fd1,4800, 8, 'N', 1);//设置串口属性 669 if (nset1 == -1){ 670 printf("\r\n Set COM Port Falid! \r\n"); 671 exit(1); 672 } 673 674 while(1) 675 { 676 nread = read(fd1, read_buf, 1024);//读串口 677 if (nread > 0){ 678 printf( "GPS:\n %s\n", read_buf); //输出所读数据 679 printf("\r\n++++++++++++++++++++++++++++++++++++++++++\r\n"); 680 681 /* find "$GPGGA" from raw_buf */ 682 char *wellhandled_stringGPGGA; 683 if((wellhandled_stringGPGGA = strstr(read_buf, "$GPGGA"))!=NULL) 684 { 685 int i; 686 for (i=0; i<strlen(wellhandled_stringGPGGA); i++) 687 { 688 if (wellhandled_stringGPGGA[i] == '\n') 689 { 690 wellhandled_stringGPGGA[i] = '\0'; //replace ‘\n’ with null 691 } 692 } 693 printf("%s\n",wellhandled_stringGPGGA); 694 //解析GPGGA 695 GPS_GGA_Parse(wellhandled_stringGPGGA,&gps_info); 696 } 697 698 /* find "$GPRMC" from raw_buf */ 699 char *wellhandled_stringGPRMC; 700 if((wellhandled_stringGPRMC = strstr(read_buf, "$GPRMC"))!=NULL) 701 { 702 int i; 703 for (i=0; i<strlen(wellhandled_stringGPRMC); i++) 704 { 705 if (wellhandled_stringGPRMC[i] == '\n') 706 { 707 wellhandled_stringGPRMC[i] = '\0'; //replace ‘\n’ with null 708 } 709 } 710 printf("%s\n",wellhandled_stringGPRMC); 711 //解析GPRMC 712 GPS_RMC_Parse(wellhandled_stringGPRMC,&gps_info); 713 } 714 show_gps(&gps_info); 715 printf("\r\n++++++++++++++++++++++++++++++++++++++++++\r\n"); 716 } 717 sleep(2);//睡眠,等待数据多一点 718 } 719 close(fd1); 720 return 0; 721 }
部分代码来源网络人士,如有问题,请联系本人
浙公网安备 33010602011771号