来自串行 GNSS 设备的不可读输入 - 但不是 PuTTY
Unreadable input from serial GNSS device - but not with PuTTY
我正在编写一个 C++ 程序来从通过串行端口连接的设备获取和解析 GNSS 数据。建立连接后,我得到的只是一些乱码,而不是预期的 NMEA 句子。有谁知道我的错误在哪里?
当我使用 PuTTY 输出数据时,有一部分是乱码,一部分是好的 NMEA 句子。
我的主要代码:
#include <iostream>
#include "Serial.h"
int main()
{
Serial serial;
unsigned char buffer[256];
std::string port = "COM19";
const char *portaddress=port.data();
std::cout<<serial.Open(portaddress,9600);
//unsigned char *buffer;
int read;
int readlast;
read=serial.Read(buffer, 255);
unsigned char line[256];//=new int[];
int counter=0;
while(1)
{
while(read==0)
{
read=serial.Read(buffer, 255);
}
counter=0;
line[counter]=read;
counter++;
while(read!=0)
{
//std::cout<<read;
readlast=read;
read=serial.Read(buffer, 255);
line[counter]=read;
counter++;
}
for(int i=0;i<sizeof(line)/sizeof(*line);i++)
{
std::cout<<line[i];
}
break;
}
return 0;
}
serial.Read():
int Serial::Read(unsigned char* buffer, int length) {
WaitForSingleObject(m_Mutex, INFINITE);
DWORD bytesRead = 0;
ReadFile(m_SerialHandle, buffer, length, NULL, &m_Overlapped);
GetOverlappedResult(m_SerialHandle, &m_Overlapped, &bytesRead, 1);
ReleaseMutex(m_Mutex);
return (int)bytesRead;
}
输出:
0 <@ `▀F ÉòG $òG Ç@ $ ¶â.X■i >uñv Iuñvÿ1V fm~wç }w $ ( ¶â.ÿ■i >uñv Iuñv├ÿ1V fm~wç }w $ ä■i þÆAö■i «kªv, Ç@ ÓêA ¼■i àtªv©?½vý■i óiª ssÑvjsÑvÀÿ1VÇ@ Ç@ ÓêA
当我离开 break
时,它并没有变得更好。我的 GNSS 板的规格说明输出应为 ASCII 格式,协议为 NMEA 0813 v4.0
.
编辑:
这是我使用 HTerm.exe 时的输出。有很多垃圾字节,但在它们之间你可以找到 NMEA 语句。设置为 1 个停止位、8 个数据位、无奇偶校验、9600 波特(正如我在 u-blox 的 u-center 软件中使用的那样,它在那里工作得很好)。
?b<5><1><2><[=13=]><6><[=13=]><14>7?b<5><1><2><[=13=]><6><[=13=]>
<14>7?b<5><1><2><[=13=]><6><1><15>8?b<5><1><2><[=13=]><6><1>
<15>8?b<5><1><2><[=13=]><6><1><15>8?b<5><1><2><[=13=]><6><1>
<15>8?b<5><1><2><[=13=]><6><1><15>8?b<5><1><2><[=13=]><6><1>
<15>8?b<5><1><2><[=13=]><6><1><15>8?b<5><1><2><[=13=]><6><1>
<15>8?b<5><1><2><[=13=]><6><1><15>8?b<2><20>,<[=13=]><1><[=13=]>
<[=13=]><[=13=]><4>)<[=13=]><[=13=]><4>)<[=13=]><[=13=]><4>)<[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>??????<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?8
$GNTXT,01,01,02,u-blox AG - www.u-blox.com*4E<\r><\n>
$GNTXT,01,01,02,HW UBX-M8030 00080000*60<\r><\n>
$GNTXT,01,01,02,EXT CORE 3.01 (b8bc67)*66<\r><\n>
$GNTXT,01,01,02,ROM BASE 2.01 (75331)*19<\r><\n>
$GNTXT,01,01,02,FWVER=HPG 1.11*5E<\r><\n>
$GNTXT,01,01,02,PROTVER=20.01*1B<\r><\n>
$GNTXT,01,01,02,MOD=NEO-M8P-2*7B<\r><\n>
$GNTXT,01,01,02,FIS=0xEF4015 (100111)*58<\r><\n>
$GNTXT,01,01,02,GPS;GLO;BDS*06<\r><\n>
$GNTXT,01,01,02,GNSS OTP=GPS;GLO*37<\r><\n>
$GNTXT,01,01,02,LLC=FFFFFFFF-FFFFFFED-FFFFFFFF-FFFFF79E-FFFFFF69*2E<\r><\n>
$GNTXT,01,01,02,ANTSUPERV=AC SD PDoS SR*3E<\r><\n>
$GNTXT,01,01,02,ANTSTATUS=OK*25<\r><\n>
$GNTXT,01,01,02,PF=300*4B<\r><\n>?b
<\n><6>x<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<11><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?<2>?b<\n><\b><28><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><\n>
<[=13=]><6><[=13=]><[=13=]><[=13=]><20><[=13=]><6><[=13=]><[=13=]><11><20><[=13=]>
<[=13=]>w??b<\n><7><24><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]>)E?b<\n><2>x<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?<17><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><1><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]>?<[=13=]><[=13=]><[=13=]>?<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><1><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>???b<\n><9><<[=13=]><[=13=]>?<1><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>@<1><[=13=]>??<1><[=13=]>d<[=13=]>?<3><2><1>
<[=13=]>???<1><[=13=]><\n><11><\f><\r><14><15><1><[=13=]><2>
<3>?<16>?<18>D65E?^<[=13=]><[=13=]><[=13=]><[=13=]>??<1><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]>%??b<\n><11><28><[=13=]>/?w?f<[=13=]><[=13=]><[=13=]>????????????<[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>]Y?b<2><20>,<[=13=]><1>
<[=13=]><[=13=]><[=13=]>?*<[=13=]><[=13=]>?*<[=13=]><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>??????<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>???b<2><21><16>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>$@<[=13=]><[=13=]><17><[=13=]><[=13=]>
<1>?+M<29>?b<1><6>4<[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]>@?C<4>&<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>???&<[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?<7><[=13=]>
<[=13=]><15>'<2><[=13=]>?xq<3><18>A?b<1><7>\<[=13=]>?*<[=13=]><[=13=]>?<7><\n>
<18><[=13=]><[=13=]><11>?????<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><4><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>????????<[=13=]>
v??<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]> N<[=13=]><[=13=]>??<18><1><15>'<[=13=]>
<[=13=]>?x!7<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>(??b<1>0<\b>
<[=13=]>?*<[=13=]><[=13=]><[=13=]><4><[=13=]><[=13=]>_^?b<1>4<\b><[=13=]>?*<[=13=]>
<[=13=]><1><[=13=]><[=13=]><[=13=]>`??b<1>5<\b><[=13=]>?*<[=13=]><[=13=]><1><[=13=]>
<[=13=]><[=13=]>a??b<1><3><16><[=13=]>?*<[=13=]><[=13=]><[=13=]>@<[=13=]><\b><[=13=]>
<[=13=]><[=13=]><[=13=]><\f>+<[=13=]><[=13=]>?<28>?b<1><1><20><[=13=]>?*<[=13=]>
<[=13=]>?C<4>&<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>???&???b<1>
<2><28><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]>????????<[=13=]>v??i??b<1><4><18><[=13=]>?*<[=13=]>
<[=13=]><15>'<15>'<15>'<15>'<15>'<15>'<15>'???b<1><17><20>
<[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]>?<7><[=13=]><[=13=]><31>*?b<1><18>$<[=13=]>?*<[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?<7><[=13=]><[=13=]>??<18>
<1>k??b<1> <16><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<17><[=13=]>????`??b<1>#<20><[=13=]>?*<[=13=]><[=13=]><11><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]>k<5><5><[=13=]>???????b<1>$<20><[=13=]>?*<[=13=]>
<[=13=]><11><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>K<7><3><[=13=]>???????b<1>!<20>
<[=13=]>?*<[=13=]><[=13=]>????<[=13=]><[=13=]><[=13=]><[=13=]>?<7><\n><18><[=13=]>
<[=13=]><11>?Q??b<1>&<24><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><7>
<17><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]>y<3>?b<1>"<20><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>????|69<[=13=]>@F?b<1><9><20><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?*<[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]>@??b<1>;(<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]>?C?b<1><(<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]>?n?b<1>9<\b><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>d?
$GNDTM,W84,,0.0,N,0.0,E,0.0,W84*71<\r><\n>
$GNRMC,,V,,,,,,,,,,N*4D<\r><\n>
$GNVTG,,,,,,,,,N*2E<\r><\n>
$GNGNS,,,,,,NN,00,99.99,,,,*7D<\r><\n>
$GNGGA,,,,,,0,00,99.99,,,,,,*56<\r><\n>
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E<\r><\n>
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E<\r><\n>
$GPGSV,1,1,00*79<\r><\n>$GLGSV,1,1,00*65<\r><\n>
$GNGLL,,,,,,V,N*7A<\r><\n>
$GNGRS,,1,,,,,,,,,,,,*7E<\r><\n>
$GNGRS,,1,,,,,,,,,,,,*7E<\r><\n>
$GNGST,,0.0000,,,,3750000,3750000,3750000*66<\r><\n>
$GNZDA,,,,,00,00*56<\r><\n>
$GNGBS,,,,,,,,*5F<\r><\n>
$GNVLW,,,,,,,,*44<\r><\n>
$PUBX,00,000011.00,0000.00000,N,00000.00000,E,0.000,NF,5303301,3750000,0.000,0.00,0.000,,99.99,99.99,99.99,0,0,0*2A<\r><\n>
$PUBX,03,00*1C<\r><\n>
$PUBX,04,000011.00,181015,11.00,1867,17D,0,0.000,21*6C<\r><\n>?b<2> `<2>?
可能设置有误?虽然我试图添加:
serialParams.DCBlength=sizeof(serialParams);
serialParams.fParity=FALSE;
serialParams.fDtrControl=0;
serialParams.fRtsControl=0;
serialParams.fOutX=TRUE;
serialParams.fInX=TRUE;
serialParams.fBinary=FALSE;
serialParams.fOutxCtsFlow=FALSE;
serialParams.fOutxDsrFlow=FALSE;
serialParams.fDsrSensitivity=FALSE;
serialParams.fErrorChar=FALSE;
serialParams.fNull=FALSE;
serialParams.fAbortOnError=FALSE;
到 Serial::Open()
并且它仍然产生相同的输出。也许缓冲区有问题?我仍然没有真正理解缓冲区的概念以及它们应该有多长,所以我很可能在那里犯了一个错误。
编辑 2:
如愿(忘记了)Serial::Open()
int Serial::Open(const char* port, int baudrate) {
// if connected: close current connection before opening a new one
if(m_SerialHandle != INVALID_HANDLE_VALUE) {
Close();
}
TCHAR vibroTacPort[15];
sprintf(vibroTacPort, "\\.\%s", port);
// Open serial port
m_SerialHandle = CreateFile(vibroTacPort, // port // "\\.\COM13"
GENERIC_READ | GENERIC_WRITE,
0,//FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING | FILE_ATTRIBUTE_TEMPORARY, // | FILE_ATTRIBUTE_NORMAL,
NULL);
// FILE_FLAG_OVERLAPPED is necessary for event-driven communication, Handle hast to be flagged for overlapped IO, otherwise Serial::Request() blocks if no event occurs (e.g. if the VibroTac device does not respond to the request)
// FILE_ATTRIBUTE_TEMPORARY, FILE_FLAG_WRITE_THROUGH and FILE_FLAG_NO_BUFFERING increase the system performance
// Note: FILE_FLAG_WRITE_THROUGH is not be supported by all hard disks
// (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx#caching_behavior)
if(m_SerialHandle == INVALID_HANDLE_VALUE)
{
DWORD errorCode = GetLastError();
// Handle the error.
switch(errorCode) {
case ERROR_FILE_NOT_FOUND:
case ERROR_ACCESS_DENIED:
// 121 The semaphore timeout period has expired.
// 1167 The device is not connected.
// fall through and do nothing for now
;
}
return (errorCode);
}
// Do some basic settings
DCB serialParams = { 0 };
serialParams.DCBlength = sizeof(serialParams);
if (!GetCommState(m_SerialHandle, &serialParams)) {
Close();
return ERROR_OPEN_FAILED;
};
serialParams.BaudRate = CBR_9600;//baudrate;
serialParams.ByteSize = 8;
serialParams.StopBits = ONESTOPBIT;
serialParams.Parity = NOPARITY;
/*serialParams.DCBlength=sizeof(serialParams);
serialParams.fParity=FALSE;
serialParams.fDtrControl=0;
serialParams.fRtsControl=0;
serialParams.fOutX=TRUE;
serialParams.fInX=TRUE;
serialParams.fBinary=FALSE;
serialParams.fOutxCtsFlow=FALSE;
serialParams.fOutxDsrFlow=FALSE;
serialParams.fDsrSensitivity=FALSE;
serialParams.fErrorChar=FALSE;
serialParams.fNull=FALSE;
serialParams.fAbortOnError=FALSE;*/
if (!SetCommState(m_SerialHandle, &serialParams)) {
Close();
return ERROR_OPEN_FAILED;
}
// Set timeouts
COMMTIMEOUTS timeout = { 1 };
timeout.ReadIntervalTimeout = 100; //100 // 0 = "not used", the maximum time allowed to elapse before the arrival of the next byte on the communications line, in milliseconds.
timeout.ReadTotalTimeoutConstant = 0; // A constant used to calculate the total time-out period for read operations, in milliseconds. For each read operation, this value is added to the product of the ReadTotalTimeoutMultiplier member and the requested number of bytes.
timeout.ReadTotalTimeoutMultiplier = 80;//20 // The multiplier used to calculate the total time-out period for read operations, in milliseconds. For each read operation, this value is multiplied by the requested number of bytes to be read.
timeout.WriteTotalTimeoutConstant = 1;
timeout.WriteTotalTimeoutMultiplier = 1;
if (!SetCommTimeouts(m_SerialHandle, &timeout)) {
Close();
return ERROR_OPEN_FAILED;
}
// Set event mask
// Events:
// EV_RXCHAR 0x0001 A character was received and placed in the input buffer.
// EV_ERR 0x0080 A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
DWORD dwEvtMask = EV_RXCHAR | EV_ERR;
if(!SetCommMask(m_SerialHandle, dwEvtMask)) {
Close();
return ERROR_OPEN_FAILED;
};
// initialize m_Overlapped with 0
memset(&m_Overlapped, 0, sizeof(m_Overlapped));
// Create an event object for use by WaitCommEvent.
m_Overlapped.hEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual-reset event
FALSE, // not signaled
NULL // no name
);
m_Overlapped.Internal = 0;
m_Overlapped.InternalHigh = 0;
m_Overlapped.Offset = 0;
m_Overlapped.OffsetHigh = 0;
return 0;
}
编辑 3:
我想也许最好一次只读取一个字节,直到我到达 $
字符,然后是 \n
字符以确定哪些部分对我有用。有人可以解释我如何使用 Serial::Open()
中创建的处理程序读取单个字节吗?如果我使用前一种方式并限制 length
aka "NumberOfBytesToRead"
,我如何测试我是否到达了相关部分?
好吧,经过大量的试验和错误以及数小时的吸烟头,我找到了一个至少对我的情况有效的答案:
我把main.cpp
改成了这样:
#include <iostream>
#include "Serial.h"
#include "GPSInfo.h"
#include "NMEAParser.h"
int main()
{
Serial serial;
unsigned char buffer[256];
std::string port = "COM19";
const char *portaddress=port.data();
serial.Open(portaddress,9600);
std::string read;
read=serial.Read(buffer);
while(1)
{
read=serial.Read(buffer);
std::cout<<read;
}
return 0;
}
和Serial::Read()
像这样:
std::string Serial::Read(unsigned char* buffer) {
WaitForSingleObject(m_Mutex, INFINITE);
DWORD bytesRead = 0;
DWORD nNumberOfBytesToRead=1; // new
char a=0;
char *ptr=&a;
char last=0;
std::string output="";
ReadFile(m_SerialHandle, ptr, nNumberOfBytesToRead, NULL, &m_Overlapped);
GetOverlappedResult(m_SerialHandle, &m_Overlapped, &bytesRead, 1);
if(a=='$')
{
last=a;
ReadFile(m_SerialHandle, ptr, nNumberOfBytesToRead, NULL, &m_Overlapped);
if(a=='G'||a=='P'||a=='S')
{
output+=last;
output+=a;
while (a!='\n')
{
ReadFile(m_SerialHandle, ptr, nNumberOfBytesToRead, NULL, &m_Overlapped);
output+=a;
}
}
}
ReleaseMutex(m_Mutex);
return output;
}
现在我有以下输出:
$GNDTM,W84,,0.0,N,0.0,E,0.0,W84*71
$GNRMC,095639.00,A,4804.88405,N,01116.55021,E,0.415,,181016,,,A*6C
$GNVTG,,T,,M,0.415,N,0.769,K,A*35
$GPGSV,4,1,14,01,12,263,,07,00,284,,08,57,301,18,10,66,091,24*7B
$GPGSV,4,2,14,11,23,280,16,14,00,152,,15,04,026,,16,26,194,*7E
$GPGSV,4,3,14,18,37,056,13,21,11,079,,26,03,179,18,27,78,145,18*78
$GPGSV,4,4,14,30,03,310,,32,16,131,*7B
$GLGSV,3,1,09,70,43,047,15,71,57,137,33,72,17,181,17,76,09,244,*6F
$GLGSV,3,2,09,77,22,293,,78,12,347,,85,29,101,25,86,71,030,*63
$GLGSV,3,3,09,87,29,306,13*5F
$GNGLL,4804.88405,N,01116.55021,E,095639.00,A,A*7A
$GNGRS,095639.00,1,-2.7,7.0,,,,,,,,,,*7F
$GNTXT,01,01,00,txbuf alloc*61
$GNTXT,01,01,02,u-blox AG - www.u-blox.com*4E
$GNTXT,01,01,02,HW UBX-M8030 00080000*60
$GNTXT,01,01,02,EXT CORE 3.01 (b8bc67)*66
$GNTXT,01,01,02,ROM BASE 2.01 (75331)*19
$GNTXT,01,01,02,FWVER=HPG 1.11*5E
$GNTXT,01,01,02,PROTVER=20.01*1B
这正是我想要的。 (有时还是有垃圾,但我觉得这不会影响我的解析。)
感谢您的所有评论和回答,帮助很大。
我正在编写一个 C++ 程序来从通过串行端口连接的设备获取和解析 GNSS 数据。建立连接后,我得到的只是一些乱码,而不是预期的 NMEA 句子。有谁知道我的错误在哪里? 当我使用 PuTTY 输出数据时,有一部分是乱码,一部分是好的 NMEA 句子。
我的主要代码:
#include <iostream>
#include "Serial.h"
int main()
{
Serial serial;
unsigned char buffer[256];
std::string port = "COM19";
const char *portaddress=port.data();
std::cout<<serial.Open(portaddress,9600);
//unsigned char *buffer;
int read;
int readlast;
read=serial.Read(buffer, 255);
unsigned char line[256];//=new int[];
int counter=0;
while(1)
{
while(read==0)
{
read=serial.Read(buffer, 255);
}
counter=0;
line[counter]=read;
counter++;
while(read!=0)
{
//std::cout<<read;
readlast=read;
read=serial.Read(buffer, 255);
line[counter]=read;
counter++;
}
for(int i=0;i<sizeof(line)/sizeof(*line);i++)
{
std::cout<<line[i];
}
break;
}
return 0;
}
serial.Read():
int Serial::Read(unsigned char* buffer, int length) {
WaitForSingleObject(m_Mutex, INFINITE);
DWORD bytesRead = 0;
ReadFile(m_SerialHandle, buffer, length, NULL, &m_Overlapped);
GetOverlappedResult(m_SerialHandle, &m_Overlapped, &bytesRead, 1);
ReleaseMutex(m_Mutex);
return (int)bytesRead;
}
输出:
0 <@ `▀F ÉòG $òG Ç@ $ ¶â.X■i >uñv Iuñvÿ1V fm~wç }w $ ( ¶â.ÿ■i >uñv Iuñv├ÿ1V fm~wç }w $ ä■i þÆAö■i «kªv, Ç@ ÓêA ¼■i àtªv©?½vý■i óiª ssÑvjsÑvÀÿ1VÇ@ Ç@ ÓêA
当我离开 break
时,它并没有变得更好。我的 GNSS 板的规格说明输出应为 ASCII 格式,协议为 NMEA 0813 v4.0
.
编辑: 这是我使用 HTerm.exe 时的输出。有很多垃圾字节,但在它们之间你可以找到 NMEA 语句。设置为 1 个停止位、8 个数据位、无奇偶校验、9600 波特(正如我在 u-blox 的 u-center 软件中使用的那样,它在那里工作得很好)。
?b<5><1><2><[=13=]><6><[=13=]><14>7?b<5><1><2><[=13=]><6><[=13=]>
<14>7?b<5><1><2><[=13=]><6><1><15>8?b<5><1><2><[=13=]><6><1>
<15>8?b<5><1><2><[=13=]><6><1><15>8?b<5><1><2><[=13=]><6><1>
<15>8?b<5><1><2><[=13=]><6><1><15>8?b<5><1><2><[=13=]><6><1>
<15>8?b<5><1><2><[=13=]><6><1><15>8?b<5><1><2><[=13=]><6><1>
<15>8?b<5><1><2><[=13=]><6><1><15>8?b<2><20>,<[=13=]><1><[=13=]>
<[=13=]><[=13=]><4>)<[=13=]><[=13=]><4>)<[=13=]><[=13=]><4>)<[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>??????<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?8
$GNTXT,01,01,02,u-blox AG - www.u-blox.com*4E<\r><\n>
$GNTXT,01,01,02,HW UBX-M8030 00080000*60<\r><\n>
$GNTXT,01,01,02,EXT CORE 3.01 (b8bc67)*66<\r><\n>
$GNTXT,01,01,02,ROM BASE 2.01 (75331)*19<\r><\n>
$GNTXT,01,01,02,FWVER=HPG 1.11*5E<\r><\n>
$GNTXT,01,01,02,PROTVER=20.01*1B<\r><\n>
$GNTXT,01,01,02,MOD=NEO-M8P-2*7B<\r><\n>
$GNTXT,01,01,02,FIS=0xEF4015 (100111)*58<\r><\n>
$GNTXT,01,01,02,GPS;GLO;BDS*06<\r><\n>
$GNTXT,01,01,02,GNSS OTP=GPS;GLO*37<\r><\n>
$GNTXT,01,01,02,LLC=FFFFFFFF-FFFFFFED-FFFFFFFF-FFFFF79E-FFFFFF69*2E<\r><\n>
$GNTXT,01,01,02,ANTSUPERV=AC SD PDoS SR*3E<\r><\n>
$GNTXT,01,01,02,ANTSTATUS=OK*25<\r><\n>
$GNTXT,01,01,02,PF=300*4B<\r><\n>?b
<\n><6>x<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<11><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?<2>?b<\n><\b><28><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><\n>
<[=13=]><6><[=13=]><[=13=]><[=13=]><20><[=13=]><6><[=13=]><[=13=]><11><20><[=13=]>
<[=13=]>w??b<\n><7><24><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]>)E?b<\n><2>x<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?<17><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><1><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]>?<[=13=]><[=13=]><[=13=]>?<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><1><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>???b<\n><9><<[=13=]><[=13=]>?<1><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>@<1><[=13=]>??<1><[=13=]>d<[=13=]>?<3><2><1>
<[=13=]>???<1><[=13=]><\n><11><\f><\r><14><15><1><[=13=]><2>
<3>?<16>?<18>D65E?^<[=13=]><[=13=]><[=13=]><[=13=]>??<1><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]>%??b<\n><11><28><[=13=]>/?w?f<[=13=]><[=13=]><[=13=]>????????????<[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>]Y?b<2><20>,<[=13=]><1>
<[=13=]><[=13=]><[=13=]>?*<[=13=]><[=13=]>?*<[=13=]><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>??????<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>???b<2><21><16>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>$@<[=13=]><[=13=]><17><[=13=]><[=13=]>
<1>?+M<29>?b<1><6>4<[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]>@?C<4>&<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>???&<[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?<7><[=13=]>
<[=13=]><15>'<2><[=13=]>?xq<3><18>A?b<1><7>\<[=13=]>?*<[=13=]><[=13=]>?<7><\n>
<18><[=13=]><[=13=]><11>?????<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><4><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>????????<[=13=]>
v??<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]> N<[=13=]><[=13=]>??<18><1><15>'<[=13=]>
<[=13=]>?x!7<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>(??b<1>0<\b>
<[=13=]>?*<[=13=]><[=13=]><[=13=]><4><[=13=]><[=13=]>_^?b<1>4<\b><[=13=]>?*<[=13=]>
<[=13=]><1><[=13=]><[=13=]><[=13=]>`??b<1>5<\b><[=13=]>?*<[=13=]><[=13=]><1><[=13=]>
<[=13=]><[=13=]>a??b<1><3><16><[=13=]>?*<[=13=]><[=13=]><[=13=]>@<[=13=]><\b><[=13=]>
<[=13=]><[=13=]><[=13=]><\f>+<[=13=]><[=13=]>?<28>?b<1><1><20><[=13=]>?*<[=13=]>
<[=13=]>?C<4>&<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>???&???b<1>
<2><28><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]>????????<[=13=]>v??i??b<1><4><18><[=13=]>?*<[=13=]>
<[=13=]><15>'<15>'<15>'<15>'<15>'<15>'<15>'???b<1><17><20>
<[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]>?<7><[=13=]><[=13=]><31>*?b<1><18>$<[=13=]>?*<[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?<7><[=13=]><[=13=]>??<18>
<1>k??b<1> <16><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<17><[=13=]>????`??b<1>#<20><[=13=]>?*<[=13=]><[=13=]><11><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]>k<5><5><[=13=]>???????b<1>$<20><[=13=]>?*<[=13=]>
<[=13=]><11><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>K<7><3><[=13=]>???????b<1>!<20>
<[=13=]>?*<[=13=]><[=13=]>????<[=13=]><[=13=]><[=13=]><[=13=]>?<7><\n><18><[=13=]>
<[=13=]><11>?Q??b<1>&<24><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><7>
<17><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]>y<3>?b<1>"<20><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>????|69<[=13=]>@F?b<1><9><20><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?*<[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]>@??b<1>;(<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]>?C?b<1><(<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>
<[=13=]>?n?b<1>9<\b><[=13=]>?*<[=13=]><[=13=]><[=13=]><[=13=]><[=13=]><[=13=]>d?
$GNDTM,W84,,0.0,N,0.0,E,0.0,W84*71<\r><\n>
$GNRMC,,V,,,,,,,,,,N*4D<\r><\n>
$GNVTG,,,,,,,,,N*2E<\r><\n>
$GNGNS,,,,,,NN,00,99.99,,,,*7D<\r><\n>
$GNGGA,,,,,,0,00,99.99,,,,,,*56<\r><\n>
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E<\r><\n>
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*2E<\r><\n>
$GPGSV,1,1,00*79<\r><\n>$GLGSV,1,1,00*65<\r><\n>
$GNGLL,,,,,,V,N*7A<\r><\n>
$GNGRS,,1,,,,,,,,,,,,*7E<\r><\n>
$GNGRS,,1,,,,,,,,,,,,*7E<\r><\n>
$GNGST,,0.0000,,,,3750000,3750000,3750000*66<\r><\n>
$GNZDA,,,,,00,00*56<\r><\n>
$GNGBS,,,,,,,,*5F<\r><\n>
$GNVLW,,,,,,,,*44<\r><\n>
$PUBX,00,000011.00,0000.00000,N,00000.00000,E,0.000,NF,5303301,3750000,0.000,0.00,0.000,,99.99,99.99,99.99,0,0,0*2A<\r><\n>
$PUBX,03,00*1C<\r><\n>
$PUBX,04,000011.00,181015,11.00,1867,17D,0,0.000,21*6C<\r><\n>?b<2> `<2>?
可能设置有误?虽然我试图添加:
serialParams.DCBlength=sizeof(serialParams);
serialParams.fParity=FALSE;
serialParams.fDtrControl=0;
serialParams.fRtsControl=0;
serialParams.fOutX=TRUE;
serialParams.fInX=TRUE;
serialParams.fBinary=FALSE;
serialParams.fOutxCtsFlow=FALSE;
serialParams.fOutxDsrFlow=FALSE;
serialParams.fDsrSensitivity=FALSE;
serialParams.fErrorChar=FALSE;
serialParams.fNull=FALSE;
serialParams.fAbortOnError=FALSE;
到 Serial::Open()
并且它仍然产生相同的输出。也许缓冲区有问题?我仍然没有真正理解缓冲区的概念以及它们应该有多长,所以我很可能在那里犯了一个错误。
编辑 2:
如愿(忘记了)Serial::Open()
int Serial::Open(const char* port, int baudrate) {
// if connected: close current connection before opening a new one
if(m_SerialHandle != INVALID_HANDLE_VALUE) {
Close();
}
TCHAR vibroTacPort[15];
sprintf(vibroTacPort, "\\.\%s", port);
// Open serial port
m_SerialHandle = CreateFile(vibroTacPort, // port // "\\.\COM13"
GENERIC_READ | GENERIC_WRITE,
0,//FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING | FILE_ATTRIBUTE_TEMPORARY, // | FILE_ATTRIBUTE_NORMAL,
NULL);
// FILE_FLAG_OVERLAPPED is necessary for event-driven communication, Handle hast to be flagged for overlapped IO, otherwise Serial::Request() blocks if no event occurs (e.g. if the VibroTac device does not respond to the request)
// FILE_ATTRIBUTE_TEMPORARY, FILE_FLAG_WRITE_THROUGH and FILE_FLAG_NO_BUFFERING increase the system performance
// Note: FILE_FLAG_WRITE_THROUGH is not be supported by all hard disks
// (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx#caching_behavior)
if(m_SerialHandle == INVALID_HANDLE_VALUE)
{
DWORD errorCode = GetLastError();
// Handle the error.
switch(errorCode) {
case ERROR_FILE_NOT_FOUND:
case ERROR_ACCESS_DENIED:
// 121 The semaphore timeout period has expired.
// 1167 The device is not connected.
// fall through and do nothing for now
;
}
return (errorCode);
}
// Do some basic settings
DCB serialParams = { 0 };
serialParams.DCBlength = sizeof(serialParams);
if (!GetCommState(m_SerialHandle, &serialParams)) {
Close();
return ERROR_OPEN_FAILED;
};
serialParams.BaudRate = CBR_9600;//baudrate;
serialParams.ByteSize = 8;
serialParams.StopBits = ONESTOPBIT;
serialParams.Parity = NOPARITY;
/*serialParams.DCBlength=sizeof(serialParams);
serialParams.fParity=FALSE;
serialParams.fDtrControl=0;
serialParams.fRtsControl=0;
serialParams.fOutX=TRUE;
serialParams.fInX=TRUE;
serialParams.fBinary=FALSE;
serialParams.fOutxCtsFlow=FALSE;
serialParams.fOutxDsrFlow=FALSE;
serialParams.fDsrSensitivity=FALSE;
serialParams.fErrorChar=FALSE;
serialParams.fNull=FALSE;
serialParams.fAbortOnError=FALSE;*/
if (!SetCommState(m_SerialHandle, &serialParams)) {
Close();
return ERROR_OPEN_FAILED;
}
// Set timeouts
COMMTIMEOUTS timeout = { 1 };
timeout.ReadIntervalTimeout = 100; //100 // 0 = "not used", the maximum time allowed to elapse before the arrival of the next byte on the communications line, in milliseconds.
timeout.ReadTotalTimeoutConstant = 0; // A constant used to calculate the total time-out period for read operations, in milliseconds. For each read operation, this value is added to the product of the ReadTotalTimeoutMultiplier member and the requested number of bytes.
timeout.ReadTotalTimeoutMultiplier = 80;//20 // The multiplier used to calculate the total time-out period for read operations, in milliseconds. For each read operation, this value is multiplied by the requested number of bytes to be read.
timeout.WriteTotalTimeoutConstant = 1;
timeout.WriteTotalTimeoutMultiplier = 1;
if (!SetCommTimeouts(m_SerialHandle, &timeout)) {
Close();
return ERROR_OPEN_FAILED;
}
// Set event mask
// Events:
// EV_RXCHAR 0x0001 A character was received and placed in the input buffer.
// EV_ERR 0x0080 A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
DWORD dwEvtMask = EV_RXCHAR | EV_ERR;
if(!SetCommMask(m_SerialHandle, dwEvtMask)) {
Close();
return ERROR_OPEN_FAILED;
};
// initialize m_Overlapped with 0
memset(&m_Overlapped, 0, sizeof(m_Overlapped));
// Create an event object for use by WaitCommEvent.
m_Overlapped.hEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual-reset event
FALSE, // not signaled
NULL // no name
);
m_Overlapped.Internal = 0;
m_Overlapped.InternalHigh = 0;
m_Overlapped.Offset = 0;
m_Overlapped.OffsetHigh = 0;
return 0;
}
编辑 3:
我想也许最好一次只读取一个字节,直到我到达 $
字符,然后是 \n
字符以确定哪些部分对我有用。有人可以解释我如何使用 Serial::Open()
中创建的处理程序读取单个字节吗?如果我使用前一种方式并限制 length
aka "NumberOfBytesToRead"
,我如何测试我是否到达了相关部分?
好吧,经过大量的试验和错误以及数小时的吸烟头,我找到了一个至少对我的情况有效的答案:
我把main.cpp
改成了这样:
#include <iostream>
#include "Serial.h"
#include "GPSInfo.h"
#include "NMEAParser.h"
int main()
{
Serial serial;
unsigned char buffer[256];
std::string port = "COM19";
const char *portaddress=port.data();
serial.Open(portaddress,9600);
std::string read;
read=serial.Read(buffer);
while(1)
{
read=serial.Read(buffer);
std::cout<<read;
}
return 0;
}
和Serial::Read()
像这样:
std::string Serial::Read(unsigned char* buffer) {
WaitForSingleObject(m_Mutex, INFINITE);
DWORD bytesRead = 0;
DWORD nNumberOfBytesToRead=1; // new
char a=0;
char *ptr=&a;
char last=0;
std::string output="";
ReadFile(m_SerialHandle, ptr, nNumberOfBytesToRead, NULL, &m_Overlapped);
GetOverlappedResult(m_SerialHandle, &m_Overlapped, &bytesRead, 1);
if(a=='$')
{
last=a;
ReadFile(m_SerialHandle, ptr, nNumberOfBytesToRead, NULL, &m_Overlapped);
if(a=='G'||a=='P'||a=='S')
{
output+=last;
output+=a;
while (a!='\n')
{
ReadFile(m_SerialHandle, ptr, nNumberOfBytesToRead, NULL, &m_Overlapped);
output+=a;
}
}
}
ReleaseMutex(m_Mutex);
return output;
}
现在我有以下输出:
$GNDTM,W84,,0.0,N,0.0,E,0.0,W84*71
$GNRMC,095639.00,A,4804.88405,N,01116.55021,E,0.415,,181016,,,A*6C
$GNVTG,,T,,M,0.415,N,0.769,K,A*35
$GPGSV,4,1,14,01,12,263,,07,00,284,,08,57,301,18,10,66,091,24*7B
$GPGSV,4,2,14,11,23,280,16,14,00,152,,15,04,026,,16,26,194,*7E
$GPGSV,4,3,14,18,37,056,13,21,11,079,,26,03,179,18,27,78,145,18*78
$GPGSV,4,4,14,30,03,310,,32,16,131,*7B
$GLGSV,3,1,09,70,43,047,15,71,57,137,33,72,17,181,17,76,09,244,*6F
$GLGSV,3,2,09,77,22,293,,78,12,347,,85,29,101,25,86,71,030,*63
$GLGSV,3,3,09,87,29,306,13*5F
$GNGLL,4804.88405,N,01116.55021,E,095639.00,A,A*7A
$GNGRS,095639.00,1,-2.7,7.0,,,,,,,,,,*7F
$GNTXT,01,01,00,txbuf alloc*61
$GNTXT,01,01,02,u-blox AG - www.u-blox.com*4E
$GNTXT,01,01,02,HW UBX-M8030 00080000*60
$GNTXT,01,01,02,EXT CORE 3.01 (b8bc67)*66
$GNTXT,01,01,02,ROM BASE 2.01 (75331)*19
$GNTXT,01,01,02,FWVER=HPG 1.11*5E
$GNTXT,01,01,02,PROTVER=20.01*1B
这正是我想要的。 (有时还是有垃圾,但我觉得这不会影响我的解析。)
感谢您的所有评论和回答,帮助很大。