Win32 COM 端口数据加扰
Win32 COM port data scrambled
我试图让我的 Arduino Nano 通过 USB 通过 COM 端口将数据发送到我的 C++ 脚本,但我得到的数据似乎超出了接收器。我不知道是什么问题。
这是我的 Arduino 代码:
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
Serial.begin(9600);
Serial.println("Hello World!");
Serial.end();
}
这是我的 C++ 代码:
#include <iostream>
#include <windows.h>
int main()
{
char Byte;
DWORD dwBytesTransferred;
HANDLE hSerial;
while (true)
{
hSerial = CreateFile(L"COM7",
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if (hSerial == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
std::cout << "Serial Port Disconected\n";
//return 0;
}
}
else
{
ReadFile(hSerial, &Byte, 1, &dwBytesTransferred, 0);
std::cout << Byte;
}
CloseHandle(hSerial);
}
return 0;
}
这是我的 C++ 代码显示的内容:
roHdol!!HdWl
l e!ol
l e!ol
我的 Arduino 正在发送“Hello World!”,顺便说一句。
Arduino代码正确。
我在C++代码中发现的问题如下:
连续打开和关闭端口是个坏主意(while 循环的执行速度比您获取数据的速度快 - 这只会导致您获取垃圾数据)
由于您正在尝试读取单个字节的数据,因此 ReadFile
的参数 3 应该是 1,而不是 10。相反,如果您将大小为 10 的数组传递给参数2、您的代码有效。
您没有使用 return 值 dwBytesTransferred
来检查具有正确字节数的读取操作是否成功。在 ReadFile
之后,您可以检查参数 2 和 3 是否匹配。
根据我的经验,连接串行设备后,windows 会自动开始缓冲数据。根据您的情况,您可能希望使用 PurgeComm
函数清除 windows 中的接收缓冲区。
修改后的代码如下:
#include <iostream>
#include <windows.h>
int main()
{
char Byte;
DWORD dwBytesTransferred;
HANDLE hSerial;
hSerial = CreateFile("COM7", //Placed outside while loop also, check if 'L"COM7"' is correct.
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
PurgeComm(hSerial, PURGE_RXCLEAR); //Clear the RX buffer in windows
while (hSerial != INVALID_HANDLE_VALUE) //Executes if the serial handle is not invalid
{
ReadFile(hSerial, &Byte, 1, &dwBytesTransferred, 0);
if(dwBytesTransferred == 1)
std::cout << Byte;
}
if (hSerial == INVALID_HANDLE_VALUE) //Throw an error if the serial handle is invalid
{
std::cout << "Serial Port Not Available\n";
}
CloseHandle(hSerial); //Close the handle (handle is also automatically closed when the program is closed)
return 0;
}
我已经测试过了,它有效,我的输出是
Hello World!
Hello World!
我试图让我的 Arduino Nano 通过 USB 通过 COM 端口将数据发送到我的 C++ 脚本,但我得到的数据似乎超出了接收器。我不知道是什么问题。
这是我的 Arduino 代码:
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
Serial.begin(9600);
Serial.println("Hello World!");
Serial.end();
}
这是我的 C++ 代码:
#include <iostream>
#include <windows.h>
int main()
{
char Byte;
DWORD dwBytesTransferred;
HANDLE hSerial;
while (true)
{
hSerial = CreateFile(L"COM7",
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if (hSerial == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
std::cout << "Serial Port Disconected\n";
//return 0;
}
}
else
{
ReadFile(hSerial, &Byte, 1, &dwBytesTransferred, 0);
std::cout << Byte;
}
CloseHandle(hSerial);
}
return 0;
}
这是我的 C++ 代码显示的内容:
roHdol!!HdWl
l e!ol
l e!ol
我的 Arduino 正在发送“Hello World!”,顺便说一句。
Arduino代码正确。
我在C++代码中发现的问题如下:
连续打开和关闭端口是个坏主意(while 循环的执行速度比您获取数据的速度快 - 这只会导致您获取垃圾数据)
由于您正在尝试读取单个字节的数据,因此
ReadFile
的参数 3 应该是 1,而不是 10。相反,如果您将大小为 10 的数组传递给参数2、您的代码有效。您没有使用 return 值
dwBytesTransferred
来检查具有正确字节数的读取操作是否成功。在ReadFile
之后,您可以检查参数 2 和 3 是否匹配。根据我的经验,连接串行设备后,windows 会自动开始缓冲数据。根据您的情况,您可能希望使用
PurgeComm
函数清除 windows 中的接收缓冲区。
修改后的代码如下:
#include <iostream>
#include <windows.h>
int main()
{
char Byte;
DWORD dwBytesTransferred;
HANDLE hSerial;
hSerial = CreateFile("COM7", //Placed outside while loop also, check if 'L"COM7"' is correct.
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
PurgeComm(hSerial, PURGE_RXCLEAR); //Clear the RX buffer in windows
while (hSerial != INVALID_HANDLE_VALUE) //Executes if the serial handle is not invalid
{
ReadFile(hSerial, &Byte, 1, &dwBytesTransferred, 0);
if(dwBytesTransferred == 1)
std::cout << Byte;
}
if (hSerial == INVALID_HANDLE_VALUE) //Throw an error if the serial handle is invalid
{
std::cout << "Serial Port Not Available\n";
}
CloseHandle(hSerial); //Close the handle (handle is also automatically closed when the program is closed)
return 0;
}
我已经测试过了,它有效,我的输出是
Hello World!
Hello World!