这段代码演示了如何使用 Windows API 中的串口通信功能进行简单的数据发送和接收。它使用了串口的基本操作和设置,并通过 sendSizeCategory
函数实现了一个简单的串口通信示例,发送一个十六进制数据,并读取串口返回的数据。
_CRT_SECURE_NO_WARNINGS
:这是针对使用 strcpy
等不安全的 C 标准库函数的警告定义,表示不生成相关的警告信息。
SerialPort
类封装了串口的打开、关闭、读取和写入操作。HANDLE hComm
:串口句柄,用于标识打开的串口。DCB dcbSerialParams
和COMMTIMEOUTS timeouts
:分别用于设置串口的参数和超时时间。- 构造函数初始化了
hComm
为INVALID_HANDLE_VALUE
,并使用SecureZeroMemory
清空了dcbSerialParams
和timeouts
的内存。 - 析构函数在对象销毁时调用
close()
方法关闭串口。 bool open(const std::string& portName, int baudRate)
:打开指定端口名和波特率的串口,设置串口参数和超时时间。bool close()
:关闭串口。bool read(char* buffer, int bufferSize, int& bytesRead)
:从串口读取数据到指定的缓冲区。bool write(const char* buffer, int bufferSize, int& bytesWritten)
:向串口写入指定的数据。sendSizeCategory
函数通过串口发送和接收数据:- 首先创建一个
SerialPort
对象并打开串口"COM5"
,波特率为19200
。 - 将传入的
size_category
字符串按十六进制转换为整数,然后将其作为一个字节写入串口。 - 读取串口返回的数据到
readBuffer
,并将读取的第一个字节返回作为整数。
#define _CRT_SECURE_NO_WARNINGS
#include <cstring>
#include <iostream>
#include <string>
#include <windows.h>
#include <cstring>
#include <sstream>
#include <iomanip>
class SerialPort {
private:
HANDLE hComm;
DCB dcbSerialParams;
COMMTIMEOUTS timeouts;
public:
SerialPort();
~SerialPort();
bool open(const std::string& portName, int baudRate);
bool close();
bool read(char* buffer, int bufferSize, int& bytesRead);
bool write(const char* buffer, int bufferSize, int& bytesWritten);
};
SerialPort::SerialPort() {
hComm = INVALID_HANDLE_VALUE;
SecureZeroMemory(&dcbSerialParams, sizeof(DCB));
SecureZeroMemory(&timeouts, sizeof(COMMTIMEOUTS));
}
SerialPort::~SerialPort() {
close();
}
bool SerialPort::open(const std::string& portName, int baudRate) {
hComm = CreateFileA(portName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hComm == INVALID_HANDLE_VALUE) {
std::cout << "无法打开串口!" << std::endl;
return false;
}
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hComm, &dcbSerialParams)) {
std::cout << "获取串口状态失败!" << std::endl;
close();
return false;
}
dcbSerialParams.BaudRate = baudRate;//设置的波特率、数据位、停止位和校验方式。dcbSerialParams
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hComm, &dcbSerialParams)) {
std::cout << "设置串口状态失败!" << std::endl;
close();
return false;
}
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(hComm, &timeouts)) {
std::cout << "设置串口超时失败!" << std::endl;
close();
return false;
}
return true;
}
bool SerialPort::close() {
if (hComm != INVALID_HANDLE_VALUE) {
CloseHandle(hComm);
hComm = INVALID_HANDLE_VALUE;
}
return true;
}
bool SerialPort::read(char* buffer, int bufferSize, int& bytesRead) {
return ReadFile(hComm, buffer, bufferSize, (LPDWORD)&bytesRead, NULL);
}
bool SerialPort::write(const char* buffer, int bufferSize, int& bytesWritten) {
return WriteFile(hComm, buffer, bufferSize, (LPDWORD)&bytesWritten, NULL);
}
int sendSizeCategory(std::string size_category) {
SerialPort serialPort;
char readBuffer[256];
if (serialPort.open("COM5", 19200)) {
std::cout << "串口打开成功!" << std::endl;
std::stringstream ss;
ss << std::hex << size_category;
int size_category_hex;
ss >> size_category_hex;
char writeBuffer[256];
writeBuffer[0] = static_cast<char>(size_category_hex);
int bytesWritten;
serialPort.write(writeBuffer, 1, bytesWritten);
std::cout << "已发送数据: 0x" << std::hex << static_cast<int>(writeBuffer[0]) << std::endl;
int bytesRead;
serialPort.read(readBuffer, sizeof(readBuffer), bytesRead);
std::cout << "接收到数据: 0x" << std::hex << static_cast<int>(readBuffer[0]) << std::endl;
serialPort.close();
}
return static_cast<int>(readBuffer[0]);
}