经常需求使用 GPS 串口 NMEA 解析的功能,写了一段代码来完成引功能。

分享一下,大家一起学习。

头文件:#ifndef _GPS_MONITER_HH_

#define _GPS_MONITER_HH_

BOOL InitSerailPort(CString csSerialPort,LPVOID pParent = NULL);

DWORD WINAPI ReadNMEAThread(LPVOID lpParameter);

void SetSystemTimeFormUTC(CString csDate,CString csUTCTime);

void DeinitSerialPort(void);

#endif

源文件:#include "stdafx.h"

#include "GPSMoniter.h"

#define SATTATOLNUMBER32

// 用于在 GPS 监控界面显示 NMEA 信息

char gcBuff[4096];

CString gcsTime;

CString gcsDate;

int gdSignalNumber[SATTATOLNUMBER];

CString csLat;

CString csLatdir;

CString csLon;

CString csLondir;

CString csAltitude;

CString csSpeed;

CString csOrientation;

int nNumDisplayed;

int giGSVSatNumber;

HANDLE ghCommHandle;

HANDLE nmeathread_hand;// Global handle to the NMEA reading thread

CString gcsGPSState;//定位: A; 导航: V

CString gcsTimeOp;

CString gcsLatField;

CString gcsLonField;

int giResult;

int giSalNumber;

int giGSVCurrentPackage;

int giHourDiff;

BOOL InitSerailPort(CString csSerialPort,LPVOID pParent)

{

DCB commDCB;

COMMTIMEOUTS timeouts;

ghCommHandle = CreateFile(csSerialPort, GENERIC_READ | GENERIC_WRITE, 0, NULL,

OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);

if(INVALID_HANDLE_VALUE == ghCommHandle)

{

RETAILMSG(1, (TEXT("Opening GPS %s failed: %d!rn"),csSerialPort,(int)GetLastError()));

return FALSE;

}

commDCB.DCBlength = sizeof (DCB);

if(!GetCommState(ghCommHandle,&commDCB))

{

CloseHandle(ghCommHandle);

ghCommHandle = INVALID_HANDLE_VALUE;

RETAILMSG(1,(L"Failed in getting GPS %s DCB settings: %d!rn",csSerialPort,(int)GetLastError()));

return FALSE;

}

commDCB.DCBlength = sizeof(DCB);

commDCB.BaudRate = 9600;             // Current baud

commDCB.ByteSize = 8;                 // Number of bits/bytes, 4-8

commDCB.Parity = NOPARITY;            // 0-4=no,odd,even,mark,space

commDCB.StopBits = ONESTOPBIT;        // 0,1,2 = 1, 1.5, 2

// Setting serial port to Centrality speicifcations

if(!SetCommState(ghCommHandle,&commDCB))

{

CloseHandle(ghCommHandle);

ghCommHandle = INVALID_HANDLE_VALUE;

RETAILMSG(1,(L"Error in trying to set GPS %s DCB settings: %d!rn",csSerialPort,(int)GetLastError()));

return FALSE;

}

// Get the default timeout settings for port

if(!GetCommTimeouts(ghCommHandle, &timeouts))

{

CloseHandle(ghCommHandle);

ghCommHandle = INVALID_HANDLE_VALUE;

RETAILMSG(1,(L"Failed in getting GPS %s timeout settings: %d!rn",csSerialPort,(int)GetLastError()));

return FALSE;

}

// RETAILMSG(1,(L"%s DCB set successfully!rn",csSerialPort));

// Change the timeouts structure settings to Centrality settings

timeouts.ReadIntervalTimeout = 500;

timeouts.ReadTotalTimeoutMultiplier = 0;

timeouts.ReadTotalTimeoutConstant = 0;

// Set the time-out parameters for all read and write operations on the port.

if(!SetCommTimeouts(ghCommHandle,&timeouts))

{

CloseHandle(ghCommHandle);

ghCommHandle = INVALID_HANDLE_VALUE;

RETAILMSG(1,(L"Error in trying to set GPS %s timeout settings: %d!rn",csSerialPort,(int)GetLastError()));

return FALSE;

}

if(0 != SetCommMask(ghCommHandle,EV_RXCHAR))

{

RETAILMSG(1,(L"==Set %s mask OK!rn",csSerialPort));

}

else

{

RETAILMSG(1,(TEXT("==Set %s mask failure:%d!rn"),csSerialPort,GetLastError()));

}

nmeathread_hand = CreateThread(NULL,0,ReadNMEAThread,pParent,0,NULL);

//nmeathread_hand = CreateThread(NULL, 0, ReadNMEAThread, this, CREATE_SUSPENDED, NULL);

if(!nmeathread_hand)

{

RETAILMSG(1, (L"Could not create NMEA read thread.rn"));

return FALSE;

}

else

{

//SetThreadPriority(nmeathread_hand, THREAD_PRIORITY_BELOW_NORMAL);

//ResumeThread(nmeathread_hand);

}

SYSTEMTIME stUTC;

SYSTEMTIME stLocal;

GetLocalTime(&stLocal);

GetSystemTime(&stUTC);

giHourDiff = stLocal.wHour - stUTC.wHour;

return TRUE;

}

// nmeathread_hand = CreateThread(NULL, 0, ReadNMEAThread, this, 0, NULL);

DWORD WINAPI ReadNMEAThread(LPVOID lpParameter)

{

//DECLARE_USER_MESSAGE(UWM_NEW_NMEA);

int start, endline, onestart, oneend, linelen, degdig, iPos;

ULONG bytesRead;

DWORD EventMask = EV_RXCHAR;

CString field;

TCHAR *stopstring;

static int iCount = 0;

CWnd *mpNmea;

mpNmea = (CWnd*)lpParameter;

// Wait on the event

while(WaitCommEvent(ghCommHandle, &EventMask, NULL))

{

// RETAILMSG(1,(TEXT("---------------------------------------------ReadNMEAThread:%d,Tick: %drn"),iCount++,GetTickCount()));

// Clear the buffer before you start reading

memset(gcBuff, 0, 4096);

// Read from serial port (4b)

if (ReadFile(ghCommHandle, gcBuff, 4096, &bytesRead, NULL))

{

if(bytesRead == 0)

continue;

CString dacstr(gcBuff);/*Leo:从串口读GPS卫星数据*/

start = 0;

endline = 0;

// Parse/Process the output (4c)

while(1)

{

int i = 0;

start = dacstr.Find(L"$G", start);

if(start

break;

endline = dacstr.Find(L"rn", start);

if(endline

break;

linelen = endline - start;

//DebugOutput(MSG_DEBUG, "GPSViewer msg: start = %d endline = %d length = %d", start, endline, linelen);

// Extract one line

CString oneline;

oneline = dacstr.Mid(start, linelen);

#if _DEBUG

// RETAILMSG(1,(TEXT("*******************************GPSViewer msg: Oneline = %srn"),oneline));

#endif

onestart = 0;

oneend = 0;

i = 0;

//

//$GPRMC,075017.31,V,2232.6057,N,11356.3074,E,,,190708,,W,N*15

//$GPRMC,080525.82,A,2232.5196,N,11356.3719,E,,,190708,,W,A*08

if(oneline.Left(6) == L"$GPRMC")

{

while((iPos = oneline.Find(L",")) >= 0)

{

field = oneline.Left(iPos);

i ++;

oneline = oneline.Mid(iPos + 1);

if(3 == i)

{

gcsGPSState = field;

}

else if(10 == i)//当前UTC日期ddmmyy 格式 - 例如: 030222

{

gcsDate = field;

}

}

}

//

//$GPGGA,080514.82,2232.5203,N,11356.3719,E,1,6,1.327,239.386,M,,M,,*4D

else if(oneline.Left(6) == L"$GPGGA")

{

while((iPos = oneline.Find(L",")) >= 0)

{

static int iOrientation = 0;

field = oneline.Left(iPos);

i ++;

oneline = oneline.Mid(iPos + 1);

if (i == 2)

{

//

if(iOrientation != giResult)

{

RETAILMSG(1,(L"[GPS]Status of GPS is changed: %d(Old: %d)rn",giResult,iOrientation));

iOrientation = giResult;

}

//

gcsTimeOp = field;

// 将格式从: --:--:--.-- 修改为: --:--:-- ,即不显示秒后的数据 ---Leo 2009-03-26

CString csTmp = gcsTimeOp.Right(5);

CString csHour = gcsTimeOp.Left(2);

int iHour = _wtoi(csHour);

if(iHour + giHourDiff

{

csHour.Format(L"%d",iHour + giHourDiff);

}

else

{

csHour.Format(L"%d",((iHour + giHourDiff) - 24));

}

// gcsTime = csHour + L":" + time.Mid(2,2) + L":" + csTmp.Left(2);

gcsTime = csHour + gcsTimeOp.Mid(2,2) + csTmp.Left(2);

}

else if (i == 3)

{//Get Latitude from GGA - Value may not be valid.  Check flag to be sure.

gcsLatField = field;

degdig = gcsLatField.GetLength() - 2;

csLat = gcsLatField.Left(2) + CString(" ") + gcsLatField.Right(degdig);

}

else if (i == 4)

{//Get Latitude Direction (N,S) from GGA - Value may not be valid.  Check flag to be sure.

csLatdir = field;

}

else if (i == 5)

{//Get Longitude from GGA - Value may not be valid.  Check flag to be sure.

gcsLonField = field;

degdig = gcsLonField.GetLength() - 3;

csLon = gcsLonField.Left(3) + CString(" ") + gcsLonField.Right(degdig);

}

else if (i == 6)

{//Get Longitude Direction (E,W) from GGA - Value may not be valid.  Check flag to be sure.

csLondir = field;

}

else if (i == 7)//GPS状态批示0-未定位 1-无差分定位信息 2-带差分定位信息

{//Get Flag from GGA indicating position fix.  Position output from GGA is valid.

giResult = atoi((const char*)((LPCTSTR)field));

if(0 == giResult)

{

// RETAILMSG(1,(TEXT("===No orientationrn")));

}

else if(1 == giResult)

{

// RETAILMSG(1,(TEXT("===Orientation with no differencern")));

}

else if(2 == giResult)

{

// RETAILMSG(1,(TEXT("===Orientation with differencern")));

}

}

else if (i == 10)

{

csAltitude = field;

}

}

}

//$GPGSV,3,3,11,29,21,93,36,30,33,40,36,31,49,324,*46

else if (oneline.Left(6) == L"$GPGSV")

{

while((iPos = oneline.Find(L",")) >= 0)

{

field = oneline.Left(iPos);

i ++;

oneline = oneline.Mid(iPos + 1);

if(3 == i)

{

if(_ttoi(field) > 0)

{

giGSVCurrentPackage = _ttoi(field);

if (giGSVCurrentPackage == 1) // new GSV sentence

{

nNumDisplayed = 0;

for(int j = 0;j

{

gdSignalNumber[j] = -1;

}

}

}

}

else if(4 == i)

{

if(_tcstod(field, &stopstring) > 0)

{

giGSVSatNumber = (int)_tcstod(field, &stopstring);

}

}

else if(0 == (i - 5) % 4) //卫星的PRV号星号

{

if (_ttoi(field) > 0)

{

giSalNumber = _ttoi(field);

}

}

else if(3 == (i - 5) % 4) // SNR

{

if (_ttoi(field) > 0)

{

gdSignalNumber[giSalNumber-1] = _ttoi(field);

nNumDisplayed++;

}

}

}

if ((iPos = oneline.Find(L"*")) >= 0) // last sat

{

field = oneline.Left(iPos);

i ++;

if(3 == (i - 5) % 4) // SNR

{

if (_ttoi(field) > 0)

{

gdSignalNumber[giSalNumber-1] = _ttoi(field);

nNumDisplayed++;

}

}

}

}

//$GPVTG,,T,,M,,N,,K,*hh

//对地航向(单位:度)

//磁偏角(单位:度)

//对地航速(单位:哩/小时)

//地面速率(0000.0~1851.8公里/小时,前面的0也将被传输)

//如: $GPVTG,359.95,T,,M,15.15,N,28.0,K,A*04

else if(oneline.Left(6) == L"$GPVTG")

{

while((iPos = oneline.Find(L",")) >= 0)

{

field = oneline.Left(iPos);

i ++;

oneline = oneline.Mid(iPos + 1);

if(2 == i)

{

csOrientation = field;

}

else if(8 == i)

{

csSpeed = field;

}

}

}

start = endline + 2;

} // end of buffer processing

}

//Sleep(1000);// end of ReadFile

} // end of WaitCommEvent

{

// RETAILMSG(1,(TEXT("Exit GPS thread:%d"),GetLastError()));

}

return 0;

}// end of ReadNMEAThread

//csDate: 01-01-03

//csUTCTime: 04:07:44.08

void SetSystemTimeFormUTC(CString csDate,CString csUTCTime)

{

SYSTEMTIME st;

int iHour = 0;

int iMinute = 0;

int iSecond = 0;

int iYear = 0;

int iMonth = 0;

int iDay = 0;

CString csSubString;

TCHAR *stopstring;

// RETAILMSG(1,(TEXT("====Set system time from UTC.Date: %s, Time: %s"),csDate,csUTCTime));

GetSystemTime(&st);

csSubString = csDate.Left(2);

iDay = (int)_tcstod(csSubString, &stopstring);

csSubString = csDate.Mid(3,2);

iMonth = (int)_tcstod(csSubString, &stopstring);

csSubString = csDate.Right(2);

iYear = 2000 + (int)_tcstod(csSubString, &stopstring);

st.wYear = iYear;

st.wMonth = iMonth;

st.wDay = iDay;

csSubString = csUTCTime.Left(2);

iHour = (int)_tcstod(csSubString, &stopstring);

csSubString = csUTCTime.Mid(3,2);

iMinute = (int)_tcstod(csSubString, &stopstring);

csSubString = csUTCTime.Mid(6,2);

iSecond = (int)_tcstod(csSubString, &stopstring);

st.wHour = iHour;

st.wMinute = iMinute;

st.wSecond = iSecond;

SetSystemTime(&st);

}

void DeinitSerialPort(void)

{

SetCommMask(ghCommHandle,0);

if(nmeathread_hand)

{

TerminateThread(nmeathread_hand,1);

CloseHandle(nmeathread_hand);

}

if(INVALID_HANDLE_VALUE != ghCommHandle)

{

EscapeCommFunction(ghCommHandle,CLRDTR);

EscapeCommFunction(ghCommHandle,CLRRTS);

//清除驱动程序内部的发送和接收队列

PurgeComm(ghCommHandle,PURGE_TXCLEAR|PURGE_RXCLEAR);

CloseHandle(ghCommHandle);

ghCommHandle = INVALID_HANDLE_VALUE;

}

}

android提取串口返回nmea,实现GPS 串口 NMEA 解析的代码相关推荐

  1. linux串口返回条件,c – Linux – 串口读取返回EAGAIN

    我在从以下方式打开的串口读取一些数据时遇到了一些麻烦.我已经多次使用这个代码实例并且一切正常,但现在,由于某些原因我无法弄清楚,我完全无法从串口读取任何内容. 我能够在另一端写入并正确接收所有内容,但 ...

  2. 串口通信学习(GPS模块)2021.5.10

    GPS串口通信学习实践 2021.5.10 1.串口通信简介 1.1 波特率 1.2 数据位 1.3 停止位 1.4 奇偶校验位 2.GPS模块串口通信配置 2.1 驱动安装 2.2 插入GPS模块 ...

  3. S3C2440 GPS串口配置以及数据读写

    S3C2440 GPS串口配置以及数据读写 参考文章:http://www.cnblogs.com/jason-lu/articles/3173988.html       http://www.cn ...

  4. 【Android】SerialPortFinder学习笔记,显示串口列表

    显示串口列表这个操作还不涉及底层的东西,因为Android与Linux相似,有串口设备就会在/dev目录下生成一个文件,比如/dev/ttyS0之类的,在谷歌的ndroid-serialport-ap ...

  5. Android非阻塞读串口,Android 使用非阻塞的方式读写串口

    上一篇博客简单介绍了Android 串口使用demo,项目开发中由于app 同学要求 例如 getMcuversion() 返回值是 当前单片机版本号,由于我们串口是阻塞的 ,所以我们接收到串口返回值 ...

  6. ROS实现串口GPS数据的解析与通信(这篇文章所用的代码和我买的带有ROS功能包的GPS模块的功能包的代码一样)

    我发现这篇文章所用的代码和我买的带有ROS功能包的GPS模块的功能包的代码一样!!! https://gitee.com/maxibooksiyi/gps_driver 转载自:https://blo ...

  7. 串口返回调试c语言代码,用CC2530做串口实验,用调试助手输入自己的名字,电脑返回结果...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 在这基础上修改代码,使得波特率设置为38400 在电脑上串口调试助手中发送自己姓名中某个字的拼音字符串到模块,则模块通过串口返回答辩同学自己姓名中全部字的 ...

  8. android怎么知道连接的是哪个串口,android下连接串口

    1.模拟器可以使用PC的串口 启动模拟器并加载PC串口 命令如下: 运行 emulator @模拟器名称 -qemu -serial COM1 2.查看串口是否被加载 启动后使用 adb shell ...

  9. android 串口调试工具_树莓派通用串口通信实验

    一.介绍 对于树莓派 3B+来说,他的UART功能有三种:1.内部蓝牙使用:2.控制终端使用:3.与其他设备进行串口通信. 在树莓派USB TO TTL模块实验中学习了通过串口对树莓派进行控制台控制, ...

最新文章

  1. 函数项目一个超感人的故事:关于swfupload在某些环境下面session丢失的完美解决方案(看完我哭了)...
  2. python 数据分析学什么-python数据分析师要学什么
  3. UA MATH567 高维统计专题1 稀疏信号及其恢复4 Basis Pursuit的算法 Projected Gradient Descent
  4. db2诊断系列之---定位锁等待问题
  5. 如何为你的博客园添加到百度统计
  6. 倒计时 时间校准android,android倒计时器时间
  7. 2021浙江高考宁波四中成绩查询,2021浙江高考成绩查询时间公布 几号能查分
  8. ASP.NET Core 基于SignalR实时通讯的前后端分离技术
  9. php 逗号千分位,数字格式化每三位添加逗号千分位 - 文章教程
  10. phpstudy中php页面不识别php代码解决方法
  11. 1.5万字详述 | 全开源:python写小游戏+AI强化学习与传统DFS/BFS控制分别实现
  12. 分页 Paginator
  13. 服装收银系统2022年排行榜新鲜出炉!
  14. maven使用modules、parent标签时遇到的问题
  15. 虚拟机下 linux 大小写切换失效 Bug(vmware 15.5.5 导致)
  16. 电脑连不上WiFi,右下角出现红叉怎么解决
  17. 云计算具有什么平台_云计算?通俗易懂点讲云计算是什么意思?
  18. infortrend GSe Pro 208 NAS开箱初体验
  19. list control双击事件编辑列表框
  20. Spring Security系列教程18--会话管理之防御固定会话攻击

热门文章

  1. 【Latex】伪代码及字体大小
  2. 网众无盘服务器 快车挂盘失败 显示 当前磁盘已经为超级工作站模式,快吧无盘精简版结合网众...
  3. 多功能关机助手(定时/倒计时/计划关机/锁屏/注销/挂机等)
  4. 从红孩子到贝备网 母婴网购市场的转变
  5. 分享几个免费学习IT的网站
  6. 10bit显示器测试软件,LAPAELO  32寸 4k 10bit面板 显示器 简单测试
  7. python控制摄像头拍照_microbit使用蓝牙控制树莓派摄像头拍照
  8. 笔记:Java中Map集合的基本功能及遍历方式
  9. 恒大ems时间插件java0_ems 员工管理系统。包括 ,部门,职位的增删改查;考勤记录,薪资结算,日志和意见箱等 Java Develop 249万源代码下载- www.pudn.com...
  10. 热导方程的Matlab数值解方法