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 }
View Code

 

部分代码来源网络人士,如有问题,请联系本人

 

posted @ 2013-10-30 16:43  天王星天  阅读(822)  评论(0)    收藏  举报