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. 日期:這個日期是準确的,不需要轉換