天天看点

嵌入式系统GPS模块设备编程

GPS是英文Global Positioning System(全球定位系统)的简称。GPS起始于1958年美国军方的一个项目,1964年投入使用。利用GPS定位卫星,在全球范围内实时进行定位、导航的系统,称为全球卫星定位系统,简称GPS。GPS是由美国国防部研制建立的一种具有全方位、全天候、全时段、高精度的卫星导航系统,能为全球用户提供低成本、高精度的三维位置、速度和精确定时等导航信息,是卫星通信技术在导航领域的应用典范,它极大地提高了地球社会的信息化水平,有力地推动了数字经济的发展。

NMEA-0183协议

NMEA是National Marine Electronics Association(美国国家海事电子协会)的缩写。NMEA-0183协议是目前GPS接收机上使用最广泛的协议,大多数常见的GPS接收机、GPS数据处理软件、导航软件都遵守或者至少兼容这个协议。

开发板平台: FL2440 

Linux内核版本: linux-3.0 

开发模块: FIT-GPS-SF2820 

analysis.c GPS数据解析函数:

  1

 13 

 14 #include <stdio.h>

 15 #include <string.h>

 16 #include <stdlib.h>

 17 #include <sys/types.h>

 18 #include <errno.h>

 19 #include <sys/stat.h>

 20 #include <fcntl.h>

 21 

 22 #include <gps.h>

 23 

 24 //从GPS数据包中抽取出GPRMC最小定位信息

 25 int gps_analysis(char *buff,GPRMC *gps_date)

 26 {

 27     char *ptr=NULL;

 28 

 29     if(gps_date==NULL)

 30         return -1;

 31 

 32     if(strlen(buff)<10)

 33         return -1;

 34 

 35     if(NULL==(ptr=strstr(buff,"$GPRMC")))

 36         return -1;

 37 

 38     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));

 39     return 0;

 40 }

 41 

 42 //解析GPRMC最小定位信息,并打印到屏幕上

 43 int print_gps(GPRMC *gps_date)

 44 {

 45     printf("                                                                \n");

 46     printf("                                                                \n");

 47     printf("================================================================\n");

 48     printf("==              Global GPS positioning and navigation module  ==\n");

 49     printf("==              Developer:huangjiaming                       ==\n");

 50     printf("==              Email:[email protected]                       ==\n");

 51     printf("==              Development platform:fl2440                  ==\n");

 52     printf("==              GPSmodel:FIT-GPS_SF2820(replace ET-312)    ==\n");

 53     printf("================================================================\n");

 54     printf("                                                                \n");

 55     printf("================================================================\n");

 56     printf("==   GPS Status bit : %c  [A:Effective state V:invalid state]   \n",gps_date->pos_state);

 57     printf("==   GPS Mode bit : %c  [A:Autonomous positioning D:Differential positioning]             \n", gps_date->mode);

 58     printf("==   Date : 20%02d-%02d-%02d                             \n",gps_date->date%100,(gps_date->date%10000)/100,gps_date->date/10000);

 59     printf("==   Time : %02d:%02d:%02d                               \n",(gps_date->time/10000+8)%24,(gps_date->time%10000)/100,gps_date-

    >time%100);

 60     printf("==   latitude  : north latitude :%.3f                                    \n",(gps_date->latitude/100));

 61     printf("==   longitude : east longitude:%.3f                                    \n",(gps_date->longitude/100));

 62     printf("==   Speed     : %.3f                                         \n",gps_date->speed);

 63     printf("================================================================\n");

 64     return 0;

 65 }

sscanf函数

成功则返回参数数目,失败则返回-1,错误原因存于errno中。 经多次测试,在linux系统中成功返回的是成功转换的值的个数,例如: sscanf("1 2 3","%d %d %d",buf1, buf2, buf3); 成功调用返回值为3,即buf1,buf2,buf3均成功转换。 sscanf("1 2","%d %d %d",buf1, buf2, buf3); 成功调用返回值为2,即只有buf1,buf2成功转换。 (注意:此处buf均为地址) strstr函数

    strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否 则,返回NULL。

gps.h头文件:

#ifndef __GPSD_H__

#define __GPSD_H__

typedef unsigned int UINT;    //add by wei

typedef int BYTE;             //add by wei 

typedef long int WORD;        //add by wei

typedef struct __gprmc__

{

    UINT time;                  //时间

    char pos_state;             //定位状态

    float latitude;             //纬度

    float longitude;            //经度

    float speed;                //移动速度

    float direction;            //方向

    UINT date;                  //日期

    float declination;          //磁偏角

    char dd;                    //磁偏角方向

    char mode;

} GPRMC;

extern int open_com(char *device_name);

extern int gprmc_analysis(char *buff,GPRMC *gprmc);

extern int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop);

#endif                                                              

GPS模块与ARM开发板的物理连接

GPS模块属于字符设备,只需要和FL2440开发板的第二个串口连接既可以,然后将GPS测试模块放在室外便可以每隔一段时间向开发板的串口发一个数据包。

~ >: microcom /dev/ttyS1 -s 4800

gps_buff: 18*4E

$GPRMC,091202.000,A,3029.6464,N,11423.6031,E,0.32,268.91,070416,,,A*6E

$GPGGA,091203.000,3029.6467,N,11423.6033,E,1,05,3.5,117.8,M,-13.7,M,,0000*79

$GPGSA,A,3,23,11,09,08,01,,,,,,,,5.2,3.5,3.9*38

$GPRMC,091203.000,A,3029.6467,N,11423.6033,E,0.35,323.51,070416,,,A*6B

$GPGGA,091204.000,3029.6470,N,11423.6034,E,1,05,3.5,117.2,M,-13.7,M,,0000*75

$GPGSA,A,3,23,11,09,08,01,,,,,,,,5.2,3.5,3.9*38

$GPRMC,091204.000,A,3029.6470,N,11423.6034,E,0.30,275.50,070416,,,A*6B

,26,12,077,,01,10,179,37,30,06,315,Ad

Ctrl + x 返回

~>chmod 777 gps_bin 

~>./gps_bin                                                                

============================================================

==          Global GPS positioning and navigation module                               ==

==              Developer:huangjiaming                                                      ==

==              Email:42138[email protected]                                                   ==

==              Development platform:fl2440                                                ==

==              GPSmodel:FIT-GPS_SF2820(replace ET-312)                        ==

============================================================

================================================================

==   GPS Status bit : A  [A:Effective state V:invalid state]   

==   GPS Mode bit : A  [A:Autonomous positioning D:Differential positioning]             

==   Date : 2016-04-07                             

==   Time : 17:12:02                               

==   latitude  : north latitude :30.296                                    

==   longitude : east longitude:114.236                                    

==   Speed     : 0.320                                         

================================================================

$GPGGA:Global Positioning System Fix Data(GGA)GPS定位信息

$GPGSA:GPS DOP and Active Satellites(GSA)当前卫星信息

$GPGSV:GPS Satellites in View(GSV)可见卫星信息

$GPRMC:Recommended Minimum Specific GPS/TRANSIT Data(RMC)推荐定位信息

$GPVTG:Track Made Good and Ground Speed(VTG)地面速度信息

$GPGLL:Geographic Position(GLL)定位地理信息

程序主要通过GPS设备获得经度、纬度和高度,只需对该语句$GPGGA进行解析

该语句所具有的语法为:

$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*hh

<1> UTC时间,hhmmss(时分秒)格式

<2> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输)

<3> 纬度半球N(北半球)或S(南半球)

<4> 经度dddmm.mmmm(度分)格式(前面的0也将被传输)

<5> 经度半球E(东经)或W(西经)

<6> GPS状态:0=未定位,1=非差分定位,2=差分定位,6=正在估算

<7> 正在使用解算位置的卫星数量(00~12)(前面的0也将被传输)

<8> HDOP水平精度因子(0.5~99.9)

<9> 海拔高度(-9999.9~99999.9)

<10> 地球椭球面相对大地水准面的高度

<11> 差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空

<12> 差分站ID号0000~1023(前面的0也将被传输,如果不是差分定位将为空)

只需对上面语句中的<2>,<3>,<4>,<5>,<6>,<9>六项即可满足要求。

解析内容: 

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. 日期:这个日期是准确的,不需要转换

gps