C语言解码GPS--实现篇


通过自己这几天的努力终于把GPS数据全部进行了解码,相信看了我的日志的人也期待了好久,资源在于分享,才能获得进步;相对于网上直接调用接口不同的是从C的方向解决问题能让问题更加的清晰,本设计芯片采用的是联星的CC550-BG模块,满足大多数芯片性能,系统是在LINUX系统下面实现,选用ttyS0节点,根据不同借口,串口线选择的是RS-232,相信大家也有所了解,详细的请看我代码,都有详细的解释,希望帮到大家,这里我只解析了GPRMC格式的编码,大家也可以把其他几种格式的编码解析同样解析出来,只要在read_data()函数里面strncmp()的array数组改变名称就可以,可以把他写成Switch格式的解码选择器,好了废话不多说,贴上我的代码!

  1. #include <stdio.h>      /*标准输入输出定义*/  
  2. #include <stdlib.h>     /*标准函数库定义*/  
  3. #include <unistd.h>     /*Unix 标准函数定义*/  
  4. #include <sys/types.h>  
  5. #include <sys/stat.h>  
  6. #include <errno.h>  
  7. #include <string.h>  
  8. #include <fcntl.h>  
  9. #include <termios.h>  
  10.   
  11. //#define  dev  "/dev/ttyS0"  
  12. #define  BUFF_SIZE 512  
  13. #define  MAX_COM_NUM 3  
  14.   
  15. int  SectionID=0,i=0;  
  16.   
  17.  struct data  
  18. {  
  19.     char GPS_time[20];          //UTC时间  
  20.     char GPS_sv;               //使用卫星  
  21.     char GPS_wd[12];           //纬度  
  22.     char GPS_jd[12];           //经度  
  23.     //char GPS_warn;             //定位警告   
  24.     char GPS_speed[5];         //速度  
  25.     char GPS_date[8];          //UTC日期            
  26.           
  27. }GPS_DATA;  
  28.   
  29.   
  30.   
  31. int set_com_config(int fd,int baud_rate,int data_bits,char parity,int stop_bits)  
  32. {  
  33.     struct termios new_cfg,old_cfg;  
  34.     int speed;  
  35.     //保存并测试现有串口参数设置,在这里如果串口号出错,会有相关的出错信息  
  36.       
  37.     if(tcgetattr(fd,&old_cfg)!=0)  
  38.     {  
  39.         perror("tcgetattr");  
  40.         return -1;  
  41.     }  
  42.      tcflush(fd, TCIOFLUSH);  
  43.     new_cfg=old_cfg;  
  44.     cfmakeraw(&new_cfg);//配置为原始模式  
  45.     new_cfg.c_cflag&=~CSIZE;  
  46.   
  47.     //设置波特率  
  48.     switch(baud_rate)  
  49.     {  
  50.         case 2400:  
  51.         {  
  52.             speed = B2400;  
  53.             break;  
  54.         }  
  55.         case 4800:  
  56.         {  
  57.             speed = B4800;  
  58.             break;  
  59.         }  
  60.         case 9600:  
  61.         {  
  62.             speed = B9600;  
  63.             break;  
  64.         }  
  65.         case 19200:  
  66.         {  
  67.             speed = B19200;  
  68.             break;  
  69.         }  
  70.         case 38400:  
  71.         {  
  72.             speed = B38400;  
  73.             break;  
  74.         }  
  75.         case 115200:  
  76.         {  
  77.             speed = B115200;  
  78.             break;   
  79.         }  
  80.           
  81.   
  82.     }  
  83.     cfsetispeed(&new_cfg,speed);  
  84.     cfsetospeed(&new_cfg,speed);  
  85.     //设置数据位  
  86.   
  87.     switch(data_bits)  
  88.     {  
  89.         case 7:  
  90.         {  
  91.             new_cfg.c_cflag|=CS7;  
  92.             break;  
  93.         }  
  94.           
  95.         case 8:  
  96.         {  
  97.             new_cfg.c_cflag|=CS8;  
  98.             break;  
  99.         }  
  100.           
  101.     }  
  102.   
  103.     //设置停止位  
  104.     switch(stop_bits)  
  105.     {  
  106.         case 1:  
  107.         {  
  108.             new_cfg.c_cflag &=~CSTOPB;  
  109.             break;  
  110.         }  
  111.   
  112.         case 2:  
  113.         {  
  114.             new_cfg.c_cflag |=CSTOPB;  
  115.             break;  
  116.         }  
  117.           
  118.           
  119.     }  
  120.   
  121.     //设置奇偶校验位  
  122.     switch(parity)  
  123.     {  
  124.         case 'o':  
  125.         case 'O':  
  126.         {  
  127.             new_cfg.c_cflag|=(PARODD|PARENB);  
  128.             new_cfg.c_iflag|=(INPCK |ISTRIP);  
  129.             break;  
  130.         }  
  131.         case 'e':  
  132.         case 'E':  
  133.         {  
  134.             new_cfg.c_cflag |=PARENB;  
  135.             new_cfg.c_cflag &=~PARODD;  
  136.             new_cfg.c_iflag |=(INPCK | ISTRIP);  
  137.             break;  
  138.         }  
  139.         case 's':  
  140.         case 'S':  
  141.         {  
  142.             new_cfg.c_cflag &=~PARENB;  
  143.             new_cfg.c_cflag &=~CSTOPB;  
  144.             break;  
  145.         }  
  146.           
  147.         case 'n':  
  148.         case 'N':  
  149.         {  
  150.             new_cfg.c_cflag &=~PARENB;  
  151.             new_cfg.c_iflag &=~INPCK;  
  152.             break;  
  153.         }  
  154.           
  155.     }  
  156.   
  157.         new_cfg.c_cc[VTIME] =10;  
  158.     new_cfg.c_cc[VMIN] =5;  
  159.     //处理未接收字符  
  160.      tcflush(fd,TCIFLUSH);  
  161.        
  162.     if((tcsetattr(fd,TCSANOW,&new_cfg))!=0)  
  163.     {  
  164.         perror("tcsetattr");  
  165.         return -1;  
  166.     }  
  167.       
  168.     return 0;  
  169. }  
  170.   
  171.   
  172. //打开串口函数  
  173. int open_port(int com_port)  
  174. {  
  175.     int fd;  
  176.     #if (COM_TYPE == GNR_COM)  //使用普通串口  
  177.          char* dev[] = {"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};  
  178.     #else//使用USB转串口  
  179.          char* dev[] = {"/dev/ttyUSB0","/dev/ttyUSB1","/dev/ttyUSB2"};  
  180.     #endif  
  181.         if((com_port<0)||(com_port > MAX_COM_NUM))  
  182.         {  
  183.             return -1;  
  184.         }  
  185.         //打开串口  
  186.         if((fd=open(dev[com_port-1],O_RDWR|O_NOCTTY|O_NDELAY))<0)  
  187.         {  
  188.             perror("open serial port");  
  189.             return -1;  
  190.         }  
  191.         //恢复串口为堵塞状态  
  192.         if(fcntl(fd,F_SETFL,0) <0 )  
  193.         {  
  194.             perror("fcntl F_SETFL\n");  
  195.             return -1;  
  196.               
  197.         }  
  198.         //测试是否为终端设备  
  199.         if(isatty(STDIN_FILENO)==0)  
  200.         {  
  201.             perror("standard input is not a terminal device");  
  202.         }  
  203.         return fd;  
  204. }  
  205.   
  206. void print_info(void)  
  207. {  
  208.     //打印选择界面,即引导的字符号  
  209.     printf("Now the receive time is %s\n",GPS_DATA.GPS_time);  
  210.     printf("The star is %c 3\n",GPS_DATA.GPS_sv);  
  211.     printf("The earth latitude is :%s\n",GPS_DATA.GPS_wd);  
  212.     printf("The earth longitude is :%s\n",GPS_DATA.GPS_jd);   
  213.     printf("The train speed is:%s km/h\n",GPS_DATA.GPS_speed);  
  214.     printf("The date is:%s\n",GPS_DATA.GPS_date);  
  215.       
  216. }  
  217.   
  218.   
  219. void GPS_resolve_GPRMC(char data)  
  220. {  
  221. //$GPRMC,092427.604,V,4002.1531,N,11618.3097,E,0.000,0.00,280812,,E,N*08  
  222.   
  223.       
  224.     if(data==',')  
  225.     {  
  226.         ++SectionID;  
  227.         i=0;  
  228.     }  
  229.     else  
  230.     {  
  231.         switch(SectionID)  
  232.         {  
  233.             case 1://02:48:13         
  234.                     GPS_DATA.GPS_time[i++]=data;          
  235.                     if(i==2 || i==5)  
  236.                     {         
  237.                         GPS_DATA.GPS_time[i++]=':';       
  238.                     }                 
  239.                     GPS_DATA.GPS_time[8]='\0';  
  240.                 break;  
  241.             case 2:  
  242.                 if(data=='A')  
  243.                     GPS_DATA.GPS_sv='>';  
  244.                 else  
  245.                     GPS_DATA.GPS_sv='<';  
  246.                 break;  
  247.             case 3://3158.4608  
  248.                     GPS_DATA.GPS_wd[++i]=data;    
  249.                     GPS_DATA.GPS_wd[12]='\0';                     
  250.                 break;  
  251.                   
  252.             case 4:  
  253.                 if(data=='N')  
  254.                     GPS_DATA.GPS_wd[0]='N';  
  255.                 else if(data=='S')  
  256.                     GPS_DATA.GPS_wd[0]='S';  
  257.               
  258.                 break;  
  259.             case 5://11848.3737,E  
  260.                   
  261.                     GPS_DATA.GPS_jd[++i]=data;    
  262.                     GPS_DATA.GPS_jd[12]='\0';  
  263.                 break;  
  264.                   
  265.             case 6:  
  266.                 if(data=='E')  
  267.                     GPS_DATA.GPS_jd[0]='E';  
  268.                 else if(data=='W')  
  269.                     GPS_DATA.GPS_jd[0]='W';  
  270.                   
  271.                 break;  
  272.             case 7://10.05  
  273.                     GPS_DATA.GPS_speed[i++]=data;  
  274.                     GPS_DATA.GPS_speed[4]='\0';                       
  275.                 break;  
  276.             case 9://15-07-06 -> 06-07-15  
  277.                     GPS_DATA.GPS_date[i++]=data;      
  278.                     if(i==2 || i==5)                          
  279.                     {  
  280.                         GPS_DATA.GPS_date[i++]='-';  
  281.                     }                                 
  282.                     GPS_DATA.GPS_date[8]='\0';                    
  283.                 break;  
  284.         }  
  285.     }         
  286.   
  287. }  
  288.   
  289. void read_data(int fd)  
  290. {  
  291.     char buffer[BUFF_SIZE],dest[1024];     
  292.     char array[10]="$GPRMC";  
  293.     int  res,i=0,j=0,k;  
  294.     int data=1,len=0;  
  295.     memset(dest,0,sizeof(dest));  
  296.       
  297. do  
  298. {      
  299.      memset(buffer,0,sizeof(buffer));  
  300. //$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50  
  301.         if(res=read(fd,buffer,1)>0)  
  302.         {         
  303.                 //此处源源不断传入参数,一次读到数据可能为($GPRMC,024),res为读到长度,现在把每一位传入函数处理;     
  304.             strcat(dest,buffer);  
  305.             if(buffer[0]=='\n')  
  306.             {  
  307.                 i=0;  
  308.                 if(strncmp(dest,array,6)==0)  
  309.                 {                 
  310.                         printf("%s",dest);  
  311.                         len=strlen(dest);  
  312.                         for(k=0;k<len;k++)  
  313.                         {  
  314.                             GPS_resolve_GPRMC(dest[k]);  
  315.                         }         
  316.                             SectionID=0;  
  317.                               
  318.                         print_info();  
  319.                 }  
  320.                 bzero(dest,sizeof(dest));  
  321.             }  
  322.                   
  323.         }  
  324. }while(1);  
  325.     close(fd);  
  326.   
  327. }  
  328.   
  329. int main(int argc,char*argv[])  
  330. {         
  331.         int fd=0;        
  332.         int HOST_COM_PORT=1;       
  333.         fd=open_port(HOST_COM_PORT);  
  334.         if(fd<0)   
  335.         {  
  336.              perror("open fail!");  
  337.         }  
  338.         printf("open sucess!\n");  
  339.         if((set_com_config(fd,9600,8,'N',1))<0)    
  340.         {  
  341.             perror("set_com_config fail!\n");  
  342.         }  
  343.         printf("The received worlds are:\n");  
  344.         read_data(fd);  
  345.      return 0;  
  346. }  

相关内容