目前GPS(全球定位系統)定位應用市場(chǎng)日趨成熟,正在進(jìn)入應用的高速發(fā)展時(shí)期??吹秸搲锊粩嘤腥颂釂?wèn)關(guān)于GPS的問(wèn)題?,F將個(gè)人對GPS的了解寫(xiě)出來(lái)跟大家一塊探討。
1、 GPS應用簡(jiǎn)介
近年來(lái)GPS系統,已經(jīng)在大地測繪、海上漁用、車(chē)輛定位監控、建筑、農業(yè)等各個(gè)領(lǐng)域得到廣泛應用。從九十年代我國引進(jìn)GPS定位技術(shù)開(kāi)始,經(jīng)過(guò)十多年的市場(chǎng)培育,GPS定位應用進(jìn)入了發(fā)展的最好時(shí)機,未來(lái)十年基于GPS的應用將會(huì )改變我們的生活和工作方式。
目前市場(chǎng)上的大部分GPS接受模塊都是通過(guò)RS232串口與MCU進(jìn)行數據傳輸的。這些數據包括經(jīng)度、緯度、海拔高度、時(shí)間、衛星使用情況等基本信息。開(kāi)發(fā)人員再依據這些基本數據,進(jìn)行數據處理來(lái)完成整套的定位系統軟件。
2、 數據格式
在進(jìn)行數據接受編程之前,先介紹一下該模塊的數據格式。它支持NMEA-0183輸出格式。信息如下:
GGA位置測定系統定位資料(Global Positioning System Fix Data)
GSV 導航衛星資料(GNSS Satellites in View)
RMC導航衛星特定精簡(jiǎn)資料(Recommended Minimum Specific GNSS Data)
VTG 方向及速度等相關(guān)資料(Course Over Ground and Ground Speed)
由于文章篇幅問(wèn)題,筆者在這里只以接收GGA數據為例,格式如下:
$GPGGA,hhmmss,dddmm.mmmm,a,dddmm.mmmm,a,x,xx,x.x,x.x,M,,M,x.x,xxxx*CS
例:$GPGGA,033744,2446.5241,N,12100.1536,E,1,10,0.8,133.4,M,,,,*1F
說(shuō)明見(jiàn)表:
區域
名稱(chēng)
例
單位
說(shuō)明
1
信息ID
$GPGGA
GGA協(xié)議開(kāi)始
2
UTC時(shí)間
033744
hhmmss
3
緯度
2446.5241
dddmm.mmmm
4
南/北半球指示
N
N=north;S=south
5
經(jīng)度
12100.1536
dddmm.mmmm
6
東/西半球指示
E
E=east;W=west
7
定位指示
1
0 =未定位
1=定位SPS模式
2=定位DGPS, SPS模式
8
應位衛星數
10
00-12
9
HDOP
0.8
米
10
海拔高度
133.4
米
11
海拔高度單位
M
米
12
WGS84水準面劃分
13
WGS-84水準面劃分單位
14
累計GPS數據微分
15
參考工作站ID
16
校驗位
*1F
上面例子中,我們可讀出位置信息:北緯24度46.5241分,西經(jīng)121度00.1536分
格林威治時(shí)間:3點(diǎn)37分44秒
3 部分程序代碼(c++)
//初始化串口
//入口:strComm(串口名)
//返回:TRUE(成功);FALSE(失敗)
BOOLCGPSDlg::InitComm(CString strComm)
{
inti;
DCB dcb;
COMMTIMEOUTS TimeOuts;
for(i=0; i<3; i++)//串口最多初始化3次
{
m_hComm = CreateFile(strComm, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if(m_hComm != INVALID_HANDLE_VALUE)
break;
}
if(i == 3)//串口初始化失敗
{
AfxMessageBox('串口初始化失敗...');
returnFALSE;
}
SetupComm(m_hComm, MAXLENGTH, MAXLENGTH);//設置發(fā)送接收緩沖區大小
TimeOuts.ReadIntervalTimeout = 0;//設定5個(gè)超時(shí)參數
TimeOuts.ReadTotalTimeoutMultiplier = 0;
TimeOuts.ReadTotalTimeoutConstant = 500;
TimeOuts.WriteTotalTimeoutMultiplier = 0;
TimeOuts.WriteTotalTimeoutConstant = 500;
SetCommTimeouts(m_hComm, &TimeOuts);//設置超時(shí)參數
GetCommState(m_hComm, &dcb);//獲得通信狀態(tài)
dcb.fAbortOnError = FALSE;//有錯誤不停止
dcb.BaudRate = CBR_4800;//波特率4800
dcb.ByteSize = 8;//8位
dcb.Parity = NOPARITY;//奇校驗
dcb.StopBits = ONESTOPBIT;//1位停止位
SetCommState(m_hComm, &dcb);//設置通信狀態(tài)
PurgeComm(m_hComm, PURGE_TXCLEAR|PURGE_RXCLEAR);//清空發(fā)送和接收緩沖區
returnTRUE;
}
//獲得GPS參數
//注意:從GPS接收到的字符串已經(jīng)在m_strRecv中,由于是定時(shí)接收,所以在這個(gè)字符串的頭和尾都可能存在
// 不完整的NMEA輸出字符串,在處理時(shí)要特別注意
//返回:TRUE(格式正確);FALSE(格式錯誤)
BOOLCGPSDlg::GetGPSParam()
{
inti,j;
CString str,strNEMA;
//先判斷是否接收到數據
if(m_strRecv.IsEmpty())
returnFALSE;
//若字符串不是以'$'開(kāi)頭的,必須刪掉這部分不完整的
if(m_strRecv[0] !='$')
{
i = m_strRecv.Find('/n', 0);
if(i == -1)
returnFALSE;//尾部未接收完整,必須等接收完后才能刪除
m_strRecv.Delete(0, i+1);//尾部已接收完整(尾部為/r/n結束),刪除不完整的部分
}
//截取完整的NMEA-0183輸出語(yǔ)句(m_strRecv中可能有多條語(yǔ)句,每條間以/r/n分隔)
for(;;)
{
i = m_strRecv.Find('/n', 0);
if(i == -1)
break;//所有的完整輸出語(yǔ)句都已經(jīng)處理完畢,退出循環(huán)
//截取完整的NMEA-0183輸出語(yǔ)句
strNEMA = m_strRecv.Left(i+1);
m_strRecv.Delete(0, i+1);
//下面對各種輸出語(yǔ)句進(jìn)行分別處理
if(strNEMA.Find('$GPRMC',0) == 0)
{
//該輸出語(yǔ)句中的各項以','分隔
for(i=j=0; strNEMA[i]!='/r'; i++)//j為逗號的計數器
{
if(strNEMA[i] ==',')
{
j++;
str ='';
for(i++; strNEMA[i]!=','&&strNEMA[i]!='/r'; i++)
str += strNEMA[i];//str為某項的值
i--;
//對各項數據分別處理
switch(j)
{
case1://時(shí)間(UTC)
m_strTime = str.Left(6);
m_strTime.Insert(2,':');
m_strTime.Insert(5,':');
break;
case2://狀態(tài)(A-數據有效;V-數據無(wú)效,還未定位)
if(str =='A')
m_strStatus ='有效數據';
elseif(str =='V')
m_strStatus ='正在定位...';
else
m_strStatus ='非法數據格式';
break;
case3://緯度(ddmm.mmmm)
str.Insert(2,'度');
str +='分';
m_strLatitude = str;
break;
case4://緯度指示(N-北緯;S-南緯)
if(str =='N')
m_strLatitude.Insert(0,'北緯');
else
m_strLatitude.Insert(0,'南緯');
break;
case5://經(jīng)度(dddmm.mmmm)
str.Insert(3,'度');
str +='分';
m_strLongitude = str;
break;
case6://經(jīng)度指示(E-東經(jīng);W-西經(jīng))
if(str =='E')
m_strLongitude.Insert(0,'東經(jīng)');
else
m_strLongitude.Insert(0,'西經(jīng)');
break;
case7://速度(單位:節)
m_strSpeed = str;
break;
case8://航向(單位:度)
m_strCourse = str;
break;
case9://日期(UTC)
m_strDate ='';
m_strDate +='20';
m_strDate += str[4];
m_strDate += str[5];
m_strDate +='-';
m_strDate += str[2];
m_strDate += str[3];
m_strDate +='-';
m_strDate += str[0];
m_strDate += str[1];
break;
default:
break;
}
}
}
}
elseif(strNEMA.Find('$GPGGA',0) == 0)
{
}
elseif(strNEMA.Find('$GPGSA',0) == 0)
{
}
elseif(strNEMA.Find('$GPGSV',0) == 0)
{
}
elseif(strNEMA.Find('$GPGLL',0) == 0)
{
}
elseif(strNEMA.Find('$GPVTG',0) == 0)
{
}
else
returnFALSE;//格式錯誤
}
returnTRUE;
}
聯(lián)系客服