大家好!
我用简单的 C++ 编写了一个小型 gps 应用程序,包括切换协议(protocol)、向 gps 芯片发送命令等。 对 GPS 端口的写入工作正常。 但是当我尝试读取端口(检查接受的命令)时,我收到了很多愚蠢的字符。通常 NMEA 输出消息是这样的:
$GPGLL,4916.45,N,12311.12,W,225444,A
我收到了类似的:
1C0CFC14
不知道怎么回事... 我的这部分代码是下一个:
LPCVOID buffer[100];
ReadFile(hSerial, buffer, 100, 0, 0);
或者另一个用于记录一些数据:
LPCVOID buffer[100];
ReadFile(hSerial, buffer, 100, 0, 0);
ofstream log ("log.txt");
log << buffer;
log.close();
当然,Hserial 是之前声明的,并且它可以很好地写入。 当我声明 HANDLE 时,我也打开了 hSerial 文件进行读写。 目标平台是 Windows Mobile 5.0 和 6.0。 怎么了? 非常感谢您的帮助!
最佳答案
从 GPS 端口读取数据或从端口读取任何其他数据并不是一件简单的事情。
在尝试读取之前,您需要确保有一些数据在等待,并且 COM 端口没有任何先前的错误。然后,如果读取成功,则需要确保数据正确终止并包含完整的 NMEA 语句。有时您可能会读到下一个 NMEA 句子的开头,或者甚至在一次阅读中读到几个背靠背的句子,所以您必须处理这个问题。
让我们把所有这些留到改天,专注于阅读本身。
ReadFile 的第 4 个参数应该是一个指向 DWORD 的指针,它将存储实际读取的字节数。您应该使用它,以确保您获得了一些真实数据。您还应该检查返回值是否有错误。
在检查确实有一些数据等待读取之后,我是这样做的。
/**
Read data from port
@param[in] buffer pointer to location to store data
@param[in] limit maximum number of bytes to read
@return 0 if error
*/
int cSerial::ReadData( void *buffer, int limit )
{
if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
BOOL bReadStatus;
DWORD dwBytesRead, dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
if( !ComStat.cbInQue ) return( 0 );
dwBytesRead = (DWORD) ComStat.cbInQue;
if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;
bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
if( !bReadStatus ){
if( ::GetLastError() == ERROR_IO_PENDING ){
WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
return( (int) dwBytesRead );
}
return( 0 );
}
return( (int) dwBytesRead );
}
看似很复杂,但是上面的代码证明一切都是必要的。没有它,您的应用程序可能会运行一段时间,但有时它会挂起或出现乱码。您可以忽略其中一些检查,但您将不得不花费大量时间来尝试调试您的应用出现的问题 - 就像我在开发此代码时所做的那样。
关于c++ - 从 COM PORT C++ 接收 NMEA0183 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10020112/