轉自:http://www.cnblogs.com/emouse/archive/2013/05/29/3105745.html
GPS模塊簡介
SiRF芯片在2004年發布的最新的第三代芯片SiRFstar III(GSW 3.0/3.1),使得民用GPS芯片在性能方面登上了一個頂峰,靈敏度比以前的產品大為提升。這一芯片通過采用20萬次/頻率的相關器提高了靈敏度,冷開機/暖開機/熱開機的時間分別達到42s/38s/8s,可以同時追蹤20個衛星信道。是目前市場上應用最為廣泛,同時性價比也非常高的一款芯片,因此在本設計中同樣采用以此芯片為核心的GPS模塊。
GPS模塊的數據格式
對GPS模塊的數據處理本質上還是串口通信程序設計,只是GPS模塊的輸出遵循固定的格式,通過字符串檢索查找即可從模塊發送的數據中找出需要的數據,常用的GPS模塊大多采用NMEA-0183 協議。NMEA-0183 是美國國家海洋電子協會(National Marine Electronics Association)所指定的標准規格,這一標准制訂所有航海電子儀器間的通訊標准,其中包含傳輸資料的格式以及傳輸資料的通訊協議。
以下是一組正常的GPS 數據
$GPGGA,082006.000,3852.9276,N,11527.4283,E,1,08,1.0,20.6,M,,,,0000*35
$GPRMC,082006.000,A,3852.9276,N,11527.4283,E,0.00,0.0,261009,,*38
$GPVTG,0.0,T,,M,0.00,N,0.0,K*50
下面分別對每組數據的含義進行分析。
GPS 固定數據輸出語句($GPGGA),這是一幀GPS 定位的主要數據,也是使用最廣的數據。為了便於理解,下面舉例說明$GPGGA語句各部分的含義。
例:$GPGGA,082006.000,3852.9276,N,11527.4283,E,1,08,1.0,20.6,M,,,,0000*35
其標准格式為:
$GPGGA,(1),(2),(3),(4),(5),(6),(7),(8),(9),M,(10),M,(11),(12)*hh(CR)(LF)
各部分所對應的含義為:
(1) 定位UTC 時間:08 時20 分06 秒
(2) 緯度(格式ddmm.mmmm:即dd 度,mm.mmmm 分);
(3) N/S(北緯或南緯):北緯38 度52.9276 分;
(4) 經度(格式dddmm.mmmm:即ddd 度,mm.mmmm 分);
(5) E/W(東經或西經):東經115 度27.4283 分;
(6) 質量因子(0=沒有定位,1=實時GPS,2=差分GPS):1=實時GPS;
(7) 可使用的衛星數(0~8):可使用的衛星數=08;
(8) 水平精度因子(1.0~99.9);水平精度因子=1.0;
(9) 天線高程(海平面,-9999.9~99999.9,單位:m);天線高程=20.6m);
(10) 大地橢球面相對海平面的高度(-999.9~9999.9,單位:m):無;
(11) 差分GPS 數據年齡,實時GPS 時無:無;
(12) 差分基准站號(0000~1023),實時GPS 時無:無;
*總和校驗域;hh 總和校驗數:35(CR)(LF)回車,換行。
GPRMC(建議使用最小GPS 數據格式)
$GPRMC,082006.000,A,3852.9276,N,11527.4283,E,0.00,0.0,261009,,*38
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11><CR><LF>
(1) 標准定位時間(UTC time)格式:時時分分秒秒.秒秒秒(hhmmss.sss)。
(2) 定位狀態,A = 數據可用,V = 數據不可用。
(3) 緯度,格式:度度分分.分分分分(ddmm.mmmm)。
(4) 緯度區分,北半球(N)或南半球(S)。
(5) 經度,格式:度度分分.分分分分。
(6) 經度區分,東(E)半球或西(W)半球。
(7) 相對位移速度, 0.0 至1851.8 knots
(8) 相對位移方向,000.0 至359.9 度。實際值。
(9) 日期,格式:日日月月年年(ddmmyy)。
(10) 磁極變量,000.0 至180.0。
(11) 度數。
(12) Checksum.(檢查位)
$GPVTG 地面速度信息
例:$GPVTG,0.0,T,,M,0.00,N,0.0,K*50
字段0:$GPVTG,語句ID,表明該語句為Track Made Good and Ground Speed(VTG)地
面速度信息
字段1:運動角度,000 - 359,(前導位數不足則補0)
字段2:T=真北參照系
字段3:運動角度,000 - 359,(前導位數不足則補0)
字段4:M=磁北參照系
字段5:水平運動速度(0.00)(前導位數不足則補0)
字段6:N=節,Knots
字段7:水平運動速度(0.00)(前導位數不足則補0)
字段8:K=公里/時,km/h
字段9:校驗值
表 1 GPS模塊主要參數
GPS模塊主要參數 |
|||
GPS 芯片組 |
SiRF Star III |
工作頻率 |
L1, 1575.42 MHz |
粗捕獲碼 |
1.023 MHz chip rate |
同時跟蹤通道數 |
20 |
靈敏度 |
-159 dBm |
定位精度 |
5m(2維均方根, 允許廣域差分系統) |
最小速度 |
0.1 m/s |
時間精度 |
1μS(與GPS時間同步) |
默認 坐標系 |
1984年世界大地坐標系(WGS-84) |
重獲時間 |
0.1S(平均值) |
熱啟動 |
1S(平均值) |
溫啟動 |
38S(平均值) |
冷啟動 |
42S(平均值) |
最高工作海拔 |
18km(60000feet) |
最大 移動速率 |
515m/S(1000knots) |
最大加速度 |
4g |
最大 急沖度 |
20m/S3 |
電源電壓 |
5V±0.5V |
整機電流 |
約60mA,不超過100mA |
整板外形 |
61mm×49mm×17mm |
GPS 芯片外形 |
27.9mm×20mm×2.9mm |
波特率 |
9600bps |
數據輸出格式 |
SiRF二進制格式或NMEA 0183 GGA, GSA, GSV, RMC,VTG,GLL |
數據輸出電平 |
同時具備TTL電平和RS232電平 |
數據 輸出接口 |
20pin插針(TTL電平)和DB9母座 |
天線類型 |
外置有源GPS天線(3.3V/5V電壓可選, |
后備電池 |
CR1220鋰電池,3V,不可充電 |
工作溫度 |
-40ºC至+85ºC |
GPS模塊的應用程序設計
GPS模塊的應用程序設計主要分為兩部分,第一部分為串口的設置於數據讀取,第二部分為數據的分析和需要數據的提取。
與其他的關於設備編程的方法一樣,在Linux下,操作、控制串口也是通過操作起設備文件進行的。在Linux下,串口的設備文件是/dev/ttyS0或/dev/ttyS1等。因此要讀寫串口,我們首先要打開串口,然后根據GPS模塊的配置參數對串口的波特率、校驗、流控制等進行設置,這些參數設置均通過對termios結構中c_cflag的配置實現,串口配置部分函數如下:
int gps::set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop) { struct termios newtio,oldtio; if ( tcgetattr( fd,&oldtio) != 0) { perror("SetupSerial 1"); return -1; } bzero( &newtio, sizeof( newtio ) ); newtio.c_cflag |= CLOCAL | CREAD; newtio.c_cflag &= ~CSIZE; switch( nBits ) { case 7: newtio.c_cflag |= CS7; break; case 8: newtio.c_cflag |= CS8; break; } switch( nEvent ) { case 'O': //奇校驗 newtio.c_cflag |= PARENB; newtio.c_cflag |= PARODD; newtio.c_iflag |= (INPCK | ISTRIP); break; case 'E': //偶校驗 newtio.c_iflag |= (INPCK | ISTRIP); newtio.c_cflag |= PARENB; newtio.c_cflag &= ~PARODD; break; case 'N': //無校驗 newtio.c_cflag &= ~PARENB; break; } switch( nSpeed ) { case 2400: cfsetispeed(&newtio, B2400); cfsetospeed(&newtio, B2400); break; case 4800: cfsetispeed(&newtio, B4800); cfsetospeed(&newtio, B4800); break; case 9600: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; case 115200: cfsetispeed(&newtio, B115200); cfsetospeed(&newtio, B115200); break; default: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; } if( nStop == 1 ) { newtio.c_cflag &= ~CSTOPB; } else if ( nStop == 2 ) { newtio.c_cflag |= CSTOPB; } newtio.c_cc[VTIME] = 0; newtio.c_cc[VMIN] = 0; tcflush(fd,TCIFLUSH); if((tcsetattr(fd,TCSANOW,&newtio))!=0) { qDebug()<<"com set error"<<endl; return -1; } qDebug()<<"set done!"<<endl; return 0; }
在GPS數據的處理上首先將窗口數據存入一個字符串,接着通過對字符串數據的判斷來提取數據內容,判斷分為兩步,首先判斷是什么類型的數據,在本程序的設計中需要讀取$GPRMC和$GPGGA兩組數據,因此首先判斷字符串GPS_BUF[5]是C還是A,由於數據是通過符號“,”進行隔開,因此通過查找“,”來確定數據位置。在實現上將得到逗號位置函數單獨封裝調用,程序如下:
//得到指定序號的逗號位置 int gps::GetComma(int num,char *str) { int i,j=0; int len=strlen(str); for(i=0;i<len;i++) { if(str[i]==',') { j++; } if(j==num) return i+1; } return 0; }
接下來根據數據格式,通過逗號位置,提取數據信息,程序如下:
void gps::gps_parse() { int tmp; char c; c = GPS_BUF[5]; if(c=='C') { //"GPRMC" GPS->D.hour =(GPS_BUF[ 7]-'0')*10+(GPS_BUF[ 8]-'0'); GPS->D.minute =(GPS_BUF[ 9]-'0')*10+(GPS_BUF[10]-'0'); GPS->D.second =(GPS_BUF[11]-'0')*10+(GPS_BUF[12]-'0'); tmp = GetComma(9,GPS_BUF); GPS->D.day =(GPS_BUF[tmp+0]-'0')*10+(GPS_BUF[tmp+1]-'0'); GPS->D.month =(GPS_BUF[tmp+2]-'0')*10+(GPS_BUF[tmp+3]-'0'); GPS->D.year =(GPS_BUF[tmp+4]-'0')*10+(GPS_BUF[tmp+5]-'0')+2000; GPS->status = GPS_BUF[GetComma(2,GPS_BUF)]; GPS->latitude = get_locate(get_double_number(&GPS_BUF[GetComma(3,GPS_BUF)])); GPS->NS = GPS_BUF[GetComma(4,GPS_BUF)]; GPS->longitude= get_locate(get_double_number(&GPS_BUF[GetComma(5,GPS_BUF)])); GPS->EW = GPS_BUF[GetComma(6,GPS_BUF)]; GPS->speed = get_double_number(&GPS_BUF[GetComma(7,GPS_BUF)]); UTC2BTC(&GPS->D); } if(c=='A') { //"$GPGGA" GPS->high = get_double_number(&GPS_BUF[GetComma(9,GPS_BUF)]); } } //將獲取文本信息轉換為double型 double gps::get_double_number(char *s) { char buf[128]; int i; double rev; i=GetComma(1,s); strncpy(buf,s,i); buf[i]=0; rev=atof(buf); return rev; } double gps::get_locate(double temp) { int m; double n; m=(int)temp/100; n=(temp-m*100)/60; n=n+m; return n; }