首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 實作 GPS 定位資料解析:從串口接收到座標提取完整流程

     編輯:VC 教學

背景:衛星導航技術的普及與應用

衛星導航已取代傳統無線電、天文導航,廣泛應用於民用勘探、軍事導彈制導、戰場指揮等領域。中國「北斗」系統雖已啟動,但目前國內主流仍為美國 GPS。本文介紹 VC++ 環境下透過 RS-232 串口接收 GPS 接收機輸出的 NMEA-0183 句子,並解析關鍵定位參數。

串口通訊初始化與非同步讀取

Windows 將硬體端口視為檔案,使用 Win32 API 進行異步操作:

// 開啟 COM1 (異步模式)
m_hCom = CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 0, NULL,
                    OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
SetCommMask(m_hCom, EV_RXCHAR);          // 設定接收字元事件
SetupComm(m_hCom, READBUFLEN, WRITEBUFLEN); // 緩衝區大小
PurgeComm(m_hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);

// 逾時設定 (立即返回)
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
SetCommTimeouts(m_hCom, &CommTimeOuts);

// 通訊參數: 4800, 8, 奇校驗, 1 停止位
GetCommState(m_hCom, &dcb);
dcb.BaudRate = CBR_4800; dcb.ByteSize = 8;
dcb.Parity = ODDPARITY; dcb.StopBits = ONESTOPBIT;
SetCommState(m_hCom, &dcb);

採用事件觸發模式高效接收:

while (true) {
    WaitCommEvent(m_hCom, &dwEvtMask, NULL);
    if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR && ComStat.cbInQue > 0)
        ReadFile(m_hCom, m_readbuf, ComStat.cbInQue, &nLength, &olRead);
}

NMEA-0183 幀結構與 $GPRMC 解析

GPS 持續輸出多種幀,以 $GPGGA、$GPGSA、$GPGSV、$GPRMC 為常見幀頭,以 \r\n 結尾。$GPRMC 含最常用的經緯度、速度、時間:

$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>*hh
<1> UTC 時間 hhmmss
<2> 狀態 A=有效 V=無效(衛星<3)
<3> 緯度 ddmm.mmmm
<4> 半球 N/S
<5> 經度 dddmm.mmmm
<6> 半球 E/W
<7> 速度 0.0-999.9 節
<8> 方位角 000.0-359.9°
<9> 日期 ddmmyy
<10> 磁偏角 000.0-180.0°
<11> 磁偏方向 E/W

解析演算法:逗號計數法


for (int i=0; i

資料型別轉換與座標系統校正

擷取的字串需轉為數值進一步運算:

  • 時區轉換: UTC + 8 小時 = 北京時間。
  • 座標轉換: GPS 採 WGS-84,國內常用 GCJ-02/BD-09,需套用偏移演算法。
  • 經緯度格式: 度分秒 (ddmm.mmmm) 轉十進制度:度 + 分/60 + 秒/3600。

// 經度範例 (可能 2 或 3 位數度)
strcpy(buf, m_sPositionX);
if (m_sPositionX.GetLength() == 10) { // >90°
    str.Format("%c%c%c", buf[0],buf[1],buf[2]); // 度
    PositionValue = atoi(str);
    str.Format("%c%c%c%c%c%c%c", buf[3]...buf[9]); // 分.秒
    GPSParam[m_nNumber].m_dPositionX = PositionValue*60 + atof(str);
}

小結

本文提供完整 VC++ 串口程式設計範例,涵蓋非同步讀取、NMEA 幀解析、關鍵參數提取與後處理轉換,可直接整合至 GIS、RS 等上層決策系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved