Appearance
cpp
//
// Created by knight on 2023/11/10.
//
#include <windows.h>
#include <iostream>
#include <vector>
// 设置开始标识位
const char PACKET_START[] = {0x4d, 0x45, 0x50};
const char PACKET_START_LENGTH = sizeof(PACKET_START);
// 设置结束标识位
const char PACKET_END[] = {0x53, 0x4C, 0x44};
const char PACKET_END_LENGTH = sizeof(PACKET_END);
const int PACKET_LENGTH = 1207;
int main(int argc, char *argv[]) {
// 创建串口句柄
HANDLE serialHandle = CreateFile("COM4", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
NULL);
if (serialHandle == INVALID_HANDLE_VALUE) {
std::cout << "Failed to open serial port." << std::endl;
return -1;
}
DCB dcbSerialParams = {0};
// 设置结构体长度
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
// 使用GetCommState函数获取当前串口的配置参数,并将其存储到dcbSerialParams中
GetCommState(serialHandle, &dcbSerialParams);
// 设置串口的波特率为921600,即设置通信速率为921600 bps
dcbSerialParams.BaudRate = 921600;
// 将数据位设置为8位
dcbSerialParams.ByteSize = 8;
// 设置停止位为1.5个位
dcbSerialParams.StopBits = ONE5STOPBITS;
// 设置奇偶校验位为无校验。
dcbSerialParams.Parity = NOPARITY;
// 将配置好的参数应用到串口
SetCommState(serialHandle, &dcbSerialParams);
DWORD bytesRead;
std::vector<char> receivedData;
int dataSize = 0;
std::vector<char> buffer(PACKET_LENGTH);
while (ReadFile(serialHandle, buffer.data(), PACKET_LENGTH, &bytesRead, NULL)) {
// 追加接收到的数据到 receivedData
receivedData.insert(receivedData.end(), buffer.begin(), buffer.begin() + bytesRead);
dataSize += static_cast<int>(bytesRead);
// 查找完整的包
int headerIndex; // 头部索引,用于记录找到的包的起始位置
int packetSize; // 包大小,用于记录找到的包的长度
// 如果数据大小比包长度小则继续接收
if (dataSize < PACKET_LENGTH) {
continue;
}
// 查找完整的包
for (int i = 0; i < dataSize - PACKET_LENGTH; ++i) {
if (receivedData[i] != PACKET_START[0] || receivedData[i + 1] != PACKET_START[1] ||
receivedData[i + 2] != PACKET_START[2]) {
continue;
}
// 包起始位置
headerIndex = i;
packetSize = i + PACKET_LENGTH;
// 在剩余数据中查找结束标记
for (int j = packetSize; j <= dataSize - PACKET_LENGTH; ++j) {
if (receivedData[j] == PACKET_END[0] && receivedData[j + 1] == PACKET_END[1] &&
receivedData[j + 2] == PACKET_END[2]) {
// 包结束标记
packetSize = j + PACKET_LENGTH;
break;
}
}
if (packetSize - headerIndex == PACKET_LENGTH) {
// 获取去除头尾的数据包
std::vector<char> packet(receivedData.begin() + headerIndex + PACKET_START_LENGTH,
receivedData.begin() + packetSize - PACKET_END_LENGTH);
// todo 处理数据包
dataSize = static_cast<int>(receivedData.size());
if (dataSize < PACKET_LENGTH) {
break;
}
}
// 移除处理过的当前包
receivedData.erase(receivedData.begin(), receivedData.begin() + packetSize);
// 重新检查剩余数据中是否存在完整的包
i = -1;
}
}
}