通过FL2440开发板和SF2820模块获取和解析GPS信息

GPS模块解析指南
本文详细介绍如何使用SF2820 GPS模块进行数据获取与解析,包括串口配置、数据包结构解析及显示。

    GPS是英文Global Positioning System(全球定位系统)的简称。GPS起始于1958年美国军方的一个项目,1964年投入使用。20世纪70年代,美国陆海空三军联合研制了新一代卫星定位系统GPS 。主要目的是为陆海空三大领域提供实时、全天候和全球性的导航服务,并用于情报搜集、核爆监测和应急通讯等一些军事目的,经过20余年的研究实验,耗资300亿美元,到1994年,全球覆盖率高达98%的24颗GPS卫星星座己布设完成。在机械领域GPS则有另外一种含义:产品几何技术规范(Geometrical Product Specifications, 简称GPS)。另外一种含义为G/s(GB per second)。GPS(Generalized Processor Sharing)广义为处理器分享,网络服务质量控制中的专用术语。

   现在GPS的应用领域越来越广,就生活中的小黄车,摩拜单车等,都应用了GPS。所以对GPS有一定了解是非常必要的。

:实现开发板和电脑的连接,通过网线。上一篇博客讲了。

:SF2820模块与开发板接在一起。通过有一个USB接口和一个公头串口的数据线连在一起。(USB转串口)

使用microcom命令监听GPS(GPS的波特率为4800)


:串口设置 

struct termios
      {
        tcflag_t  c_iflag;  //input flags
        tcflag_t  c_oflag;  //output flags
        tcflag_t  c_cflag;  //control flags
        tcflag_t  c_lflag;  //local flags
        cc_t      c_cc[NCCS]; //control characters
      }; 

该结构体中c_cflag最为重要,可设置波特率、数据位、校验位、停止位。在设置波特率时需要在数字前加上'B',如B9600,B15200.
编写串口配置的代码

set_ttyS1.c

1 /*********************************************************************************
  2  *      Copyright:  (C) 2017 luliteng<luliteng@gmail.com>
  3  *                  All rights reserved.
  4  *
  5  *       Filename:  set_ttyS1.c
  6  *    Description:  This file 
  7  *                 
  8  *        Version:  1.0.0(2017年05月10日)
  9  *         Author:  luliteng <luliteng@gmail.com>
 10  *      ChangeLog:  1, Release initial version on "2017年05月10日 00时50分20秒"
 11  *                 
 12  ********************************************************************************/
 13 #include <stdio.h>
 14 #include <errno.h>
 15 #include <sys/stat.h>
 16 #include <fcntl.h>
 17 #include <termios.h>
 18 #include <stdlib.h>
 19 #include <string.h>
 20 #include <sys/types.h>
 21 #include <unistd.h>
 22 
 23 
 24 /**************************************************************************************
 25  *  Description: 串口参数配置
 26  *  Input Args: fd:open打开的文件描述符 nspeed:波特率 nBits:数据位数 nEvent:奇偶校验 nStop:停止位
 27  *  Output Argtingzhis: 串口参数设置失败返回-1
 28  * Return Value:
 29  *************************************************************************************/
 30 int set_opt(int fd,int nSpeed,int nBits,char nEvent,int nStop)
 31 {
 32     struct termios newttys1,oldttys1;
 33 
 34     if(tcgetattr(fd,&oldttys1)!=0)         //保存原先串口配置
 35     {
 36         perror("Setupserial 1");
 37         return -1;
 38     }
 39 
 40 bzero(&newttys1,sizeof(newttys1));       //将一段内存区域的内容全清为零
 41 newttys1.c_cflag|=(CLOCAL|CREAD );       //CREAD 开启串行数据接收,CLOCAL并打开本地连接模式 
42
43 newttys1.c_cflag &=~CSIZE;              //设置数据位数
 44 switch(nBits)     //选择数据位  
 45  {
 46         case 7:
 47                 newttys1.c_cflag |=CS7;
 48                 break;
 49         case 8:
 50                 newttys1.c_cflag |=CS8;
 51                 break;
 52  }
 53 switch( nEvent )    //设置校验位  
 54  {
 55    case '0':       //奇校验  
 56            newttys1.c_cflag |= PARENB;             //开启奇偶校验  
 57            newttys1.c_iflag |= (INPCK | ISTRIP);   //INPCK打开输入奇偶校验;ISTRIP去除字符的第八个比特  
 58            newttys1.c_cflag |= PARODD;             //启用奇校验(默认为偶校验)  
 59            break;
 60   case 'E' :       //偶校验  
 61            newttys1.c_cflag |= PARENB;             //开启奇偶校验  
 62            newttys1.c_iflag |= ( INPCK | ISTRIP);  //打开输入奇偶校验并去除字符第八个比特  
 63            newttys1.c_cflag &= ~PARODD;            //启用偶校验;  
 64            break;
 65   case 'N':     //关闭奇偶校验
 66            newttys1.c_cflag &= ~PARENB;
 67            break;
 68    }
 69 
 70      switch( nSpeed )        //设置波特率  
 71      {
 72         case 2400:
 73                  cfsetispeed(&newttys1, B2400);           //设置输入速度
 74                  cfsetospeed(&newttys1, B2400);           //设置输出速度
 75                  break;
 76         case 4800:
 77                  cfsetispeed(&newttys1, B4800);
 78                  cfsetospeed(&newttys1, B4800);
 79                  break;
 80         case 9600:
 81                  cfsetispeed(&newttys1, B9600);
82                  cfsetospeed(&newttys1, B9600);
 83                  break;
 84         case 115200:
 85                  cfsetispeed(&newttys1, B115200);
 86                  cfsetospeed(&newttys1, B115200);
 87                  break;
 88         default:
 89                  cfsetispeed(&newttys1, B9600);
 90                  cfsetospeed(&newttys1, B9600);
 91                  break;
 92      }
 93 
 94      if( nStop == 1)                      //设置停止位;若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB。  
 95      {
 96         newttys1.c_cflag &= ~CSTOPB;      //默认为送一位停止位;  
 97      }
 98      else if( nStop == 2)
 99      {
100         newttys1.c_cflag |= CSTOPB;       //CSTOPB表示送两位停止位;  
101      }
102 
103      //设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时
104      newttys1.c_cc[VTIME] = 0;        //非规范模式读取时的超时时间;  
105      newttys1.c_cc[VMIN]  = 0;        //非规范模式读取时的最小字符数;  
106 
107      tcflush(fd ,TCIFLUSH);           //tcflush清空终端未完成的输入/输出请求及数据;TCIFLUSH表示清空正收到的数据,且不读取出来 
108 
109      // 在完成配置后,需要激活配置使其生效
110      if((tcsetattr( fd, TCSANOW,&newttys1))!=0) //TCSANOW不等数据传输完毕就立即改变属性  
111      {
112          perror("com set error");
113          return -1;
114      }
115     return 0;
116 } /* ----- End of if()  ----- */
117 
 ~/gps/set_ttyS1.c   CWD: /home/luliteng/gps   Line: 117/117:0       
                                                               


五:GPS数据解析

信息类型为: 
GPGSV:可见卫星信息 
GPGLL:地理定位信息 
GPRMC:推荐最小定位信息 
GPVTG:地面速度信息 
GPGGA:GPS定位信息 
GPGSA:当前卫星信息

       $GPRMC,055043.350,V,,,,,,,310517,,,N*4D

$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh 
1) 标准定位时间(UTC time)格式:时时分分秒秒.秒秒秒(hhmmss.sss) 。(前面的0也将被传输) 
2) 定位状态,A= 数据可用,V = 数据不可用。 
3) 纬度,格式:度度分分.分分分分(ddmm.mmmm) 。(前面的0也将被传输) 
4) 纬度区分,北半球(N)或南半球(S) 。 
5) 经度,格式:度度分分.分分分分。(前面的0也将被传输) 
6) 经度区分,东(E)半球或西(W)半球。 
7) 地面速率(000.0~999.9节,前面的0也将被传输) 
8) 地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输) 
9) 日期,格式:日日月月年年(ddmmyy) 。 
10) 磁偏角(000.0~180.0度,前面的0也将被传输) 
11) 磁偏角方向,E(东)或W(西) 
12) 模式指示(仅NMEA01833.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)


解析内容: 
1.时间,这个是格林威治时间,是世界时间(UTC),我们需要把它转换成北京时间(BTC),BTC和UTC差了8个小时,要在这个时间基础上加8个小时。 
2. 定位状态,在接收到有效数据前,这个位是‘V’,后面的数据都为空,接到有效数据后,这个位是‘A’,后面才开始有数据。 
3. 纬度,我们需要把它转换成度分秒的格式,计算方法:如接收到的纬度是:4546.40891 
4546.40891/100=45.4640891可以直接读出45度, 4546.40891–45*100=46.40891, 可以直接读出46分 
46.40891–46 =0.40891*60=24.5346读出24秒, 所以纬度是:45度46分24秒。 
4. 南北纬,这个位有两种值‘N’(北纬)和‘S’(南纬) 
5. 经度的计算方法和纬度的计算方法一样 
6. 东西经,这个位有两种值‘E’(东经)和‘W’(西经) 
7.速率,这个速率值是海里/时,单位是节,要把它转换成千米/时,根据:1海里=1.85公里,把得到的速率乘以1.85。 
8. 航向,指的是偏离正北的角度 
9. 日期,这个日期是准确的,不需要转换

解析函数与 analyse_gps.c

1 /*********************************************************************************
  2  *      Copyright:  (C) 2017 luliteng<luliteng@gmail.com>
  3  *                  All rights reserved.
  4  *
  5  *       Filename:  analyse_gps.c
  6  *    Description:  This file 
  7  *                 
  8  *        Version:  1.0.0(2017年05月10日)
  9  *         Author:  luliteng <luliteng@gmail.com>
 10  *      ChangeLog:  1, Release initial version on "2017年05月10日 00时35分12秒"
 11  *                 
 12  ********************************************************************************/
 13 #include <stdio.h>
 14 #include <string.h>
 15 #include <stdlib.h>
 16 #include <sys/types.h>
 17 #include <errno.h>
 18 #include <sys/stat.h>
 19 #include <fcntl.h>
 20 
 21 #include "gps.h"
 22 
 23 /**************************************************************************************
 24  *  Description:从GPS数据包中抽取出GPRMC最小定位信息
 25  *   Input Args:buff:GPS返回的数据包 gps_date:GPRMC信息存储结构体
 26  *  Output Args:
 27  * Return Value:
 28  *************************************************************************************/
 29 int gps_analysis(char *buff,GPRMC *gps_date)
 30 {
 31     char *ptr=NULL;
 32 
 33     if(gps_date==NULL)
 34       return -1;
 35 
 36     if(strlen(buff)<10)
 37       return -1;
 38 
 39     if(NULL==(ptr=strstr(buff,"$GPRMC")))
 40      return -1;
 41 
42     sscanf(ptr,"$GPRMC,%d.000,%c,%f,N,%f,E,%f,%f,%d,,,%c*",&(gps_date->time),&(gps_date->pos_state),&(gps_date->latitude),      
    &(gps_date->longitude),&(gps_date->speed),&(gps_date->direction),&(gps_date->date),&(gps_date->mode));
 43 
 44    return 0;
 45 } /* ----- End of if()  ----- */
 46 
 47 /********************************************************************************************
 48 
 49 strstr(str1,str2) 函数用于在字符串str1中搜寻str2,并返回str2在str1中首次出现的地址;否则,返回NULL
 50 sscanf()格式化字符串输入,从一个字符串中读进与指定格式相符的数据并在存入到另一个字符串中
 51 
 52 **********************************************************************************************/
 53 
 54 /**************************************************************************************
 55  *  Description:解析GPRMC最小定位信息,并打印到屏幕上
 56  *   Input Args:gps_date:gps_analysis函数抽取的GPRMC信息
 57  *  Output Args:
 58  * Return Value:
 59  *************************************************************************************/
 60 int print_gps(GPRMC *gps_date)
 61 {
 62     printf("                                                           \n");
 63     printf("                                                           \n");
 64     printf("===========================================================\n");
 65     printf("==                   全球GPS定位导航模块                 ==\n");
 66     printf("==              开发人员:卢立腾                           ==\n");
 67     printf("==              邮箱:852335815@qq.com                  ==\n");
 68     printf("==              平台:fl2440                             ==\n");
 69     printf("==              GPS型号:FIT-GPS_SF2820(代替ET-312)    ==\n");
 70     printf("===========================================================\n");
 71     printf("                                                         \n");
 72     printf("                                                         \n");
 73     printf("===========================================================\n");
 74     printf("==                                                       \n");
 75     printf("==   GPS状态位 : %c  [A:有效状态 V:无效状态]             \n",gps_date->pos_state);
 76     printf("==   GPS模式位 : %c  [A:自主定位 D:差分定位]             \n", gps_date->mode);
 77     printf("==   日期 : 20%02d-%02d-%02d                             \n",gps_date->date%100,(gps_date->date%10000)/100,gps_date-
    >date/10000);
 ~/gps/analyse_gps.c   CWD: /home/luliteng/gps   Line: 70/86:1                                                                      
 78     printf("==   时间 : %02d:%02d:%02d                               \n",(gps_date->time/10000+8)%24,(gps_date->time%10000)/100,
    gps_date->time%100);
 79     printf("==   纬度 : 北纬:%.3f                                    \n",(gps_date->latitude/100));
 80     printf("==   经度 : 东经:%.3f                                    \n",(gps_date->longitude/100));
 81     printf("==   速度 : %.3f                                         \n",gps_date->speed);
 82     printf("==                                                       \n");
 83     printf("===========================================================\n");
 84     return 0;
 85 } /* ----- End of print_gps()  ----- */
 86 


六:gps_main.c

1 /*********************************************************************************
  2  *      Copyright:  (C) 2017 luliteng<luliteng@gmail.com>
  3  *                  All rights reserved.
  4  *
  5  *       Filename:  gps_main.c
  6  *    Description:  This file 
  7  *                 
  8  *        Version:  1.0.0(2017年05月10日)
  9  *         Author:  luliteng <luliteng@gmail.com>
 10  *      ChangeLog:  1, Release initial version on "2017年05月10日 00时48分12秒"
 11  *                 
 12  ********************************************************************************/
 13 #include <stdio.h>
 14 #include <string.h>
 15 #include <sys/types.h>
 16 #include <errno.h>
 17 #include <sys/stat.h>
 18 #include <fcntl.h>
 19 #include <unistd.h>
 20 #include <termios.h>
 21 #include <stdlib.h>
 22 
 23 #include "gps.h"
 24 
 25 #define GPS_LEN 512 
 26 
 27 int gps_analysis(char *buff,GPRMC *gps_date);
 28 int print_gps(GPRMC *gps_date);
 29 int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop);
 30 
 31 
 32 /********************************************************************************
 33  *  Description:   main():程序执行的入口
 34  *   Input Args:    
 35  *  Output Args:
 36  * Return Value:
 37  ********************************************************************************/
 38 int main (int argc, char **argv)
 39 {
 40      int fd = 0;
 41      int nread = 0;
 42 
 43      GPRMC gprmc;
 44 
 45      char gps_buff[GPS_LEN];
 46      char *dev_name = "/dev/ttyUSB0";//串口转usb
47 
 48      fd=open(dev_name,O_RDWR|O_NOCTTY|O_NDELAY);
 49      if(fd<0)
 50      {
 51          printf("open ttyS1 error!!\n");
 52          return -1;
 53      }
 54 
 55      set_opt( fd,4800,8,'N',1);
 56 
 57      while(1)
 58      {
 59          sleep(2);
 60          nread = read(fd,gps_buff,sizeof(gps_buff));
 61          if(nread<0)
 62          {
 63              printf("read GPS date error!!\n");
 64              return -2;
 65          }
 66          printf("gps_buff: %s\n", gps_buff);
 67 
 68          memset(&gprmc, 0 , sizeof(gprmc));
 69          gps_analysis(gps_buff,&gprmc);
 70 
 71          print_gps(&gprmc);
 72      }
 73 
 74 
 75     close(fd);
 76     return 0;
 77 } /* ----- End of main() ----- */


 78 

七:gps.h头文件

gps.h                                                                                                                              
  

1 /********************************************************************************
  2  *      Copyright:  (C) 2017 luliteng<luliteng@gmail.com>
  3  *                  All rights reserved.
  4  *
  5  *       Filename:  gps.h
  6  *    Description:  This head file 
  7  *
  8  *        Version:  1.0.0(2017年05月10日)
  9  *         Author:  luliteng <luliteng@gmail.com>
 10  *      ChangeLog:  1, Release initial version on "2017年05月10日 00时45分56秒"
 11  *                 
 12  ********************************************************************************/
 13 
 14  #ifndef __GPS_H__
 15   #define __GPS_H__
 16 
 17   typedef unsigned int UINT;
 18   typedef int BYTE;
 19   typedef long int WORD;
 20 
 21   typedef struct __gprmc__
 22   {
 23           UINT time;                  //格林威治时间
 24           char pos_state;             //定位状态
 25           float latitude;             //纬度
 26           float longitude;            //经度
 27           float speed;                //移动速度
 28           float direction;            //方向
 29           UINT date;                  //日期
 30           float declination;          //磁偏角
 31           char dd;                    //磁偏角方向
 32           char mode;
 33   }GPRMC;
 34 
 35   extern int gps_analysis(char *buff,GPRMC *gps_date);
 36   extern int print_gps(GPRMC *gps_date);
 37   extern int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop);
 38 
 39   #endif


八:把analyse_gps.c  gps.h  gps_main.c    set_ttyS1.c放在同一个文件夹下

通过交叉编译器armgcc *.c编译产生a.out可执行文件(我这里将a.out重命名为gps.out)

将gps.out传到开发板下运行


以上就是sf2820模块gps的解析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值