衛星導航已取代傳統無線電、天文導航,廣泛應用於民用勘探、軍事導彈制導、戰場指揮等領域。中國「北斗」系統雖已啟動,但目前國內主流仍為美國 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);
}
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
擷取的字串需轉為數值進一步運算:
// 經度範例 (可能 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 等上層決策系統。