十万个为什么 [串口] Windows 串口读写
#include <Windows.h>
#include <stdint.h>
#include <stdio.h>
// ---------------------------------------------------------------------------
class serial_t
{
public:
~serial_t() { close(); }
bool is_open() { return m_handle != INVALID_HANDLE_VALUE; }
public:
void open(uint8_t index, uint32_t baud);
void close();
void change_baud(uint32_t baud);
int read(uint8_t* buffer, int buffer_size);
int write(uint8_t* buffer, int tx_size);
private:
// 句柄
HANDLE m_handle{INVALID_HANDLE_VALUE};
// 上次打开的序号
uint8_t m_last_index{0xFF};
// 上次的波特率
uint32_t m_last_baud{0};
};
// ---------------------------------------------------------------------------
void serial_t::open(uint8_t index, uint32_t baud)
{
// 已经打开
if (is_open() && m_last_index == index)
{
// 更换了波特率, 设置波特率
if (baud != 0 && m_last_baud != baud)
{
change_baud(baud);
}
return;
}
// 关闭之前
if (is_open())
{
close();
}
// 路径
char path[MAX_PATH];
snprintf(path, MAX_PATH, "\\\\.\\\\COM%d", index);
// 打开新的
m_handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (is_open() == false)
{
return;
}
// 记录打开
m_last_index = index;
// 设置(PS:不知道设置的是什么)
SetCommMask(m_handle, EV_RXCHAR | EV_TXEMPTY | EV_ERR);
PurgeComm(m_handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
// 读写阻塞的时间
COMMTIMEOUTS time_out = {0};
time_out.ReadIntervalTimeout = 100; // 100ms
SetCommTimeouts(m_handle, &time_out);
// 设置波特率
change_baud(baud);
}
// ---------------------------------------------------------------------------
void serial_t::close()
{
if (m_handle != INVALID_HANDLE_VALUE)
{
PurgeComm(m_handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
CloseHandle(m_handle);
m_handle = INVALID_HANDLE_VALUE;
m_last_index = 0xFF;
m_last_baud = 0;
}
}
// ---------------------------------------------------------------------------
void serial_t::change_baud(uint32_t baud)
{
if (!is_open() || baud == 0 || m_last_baud == baud)
{
return;
}
m_last_baud = baud;
DCB dcb = {0};
dcb.DCBlength = sizeof(DCB);
GetCommState(m_handle, &dcb);
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
dcb.BaudRate = baud;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fOutxCtsFlow = 0;
dcb.fOutxDsrFlow = 0;
SetCommState(m_handle, &dcb);
}
// ---------------------------------------------------------------------------
int serial_t::read(uint8_t* buffer, int buffer_size)
{
if (is_open())
{
}
return 0;
}
// ---------------------------------------------------------------------------
int serial_t::write(uint8_t* buffer, int tx_size)
{
if (is_open())
{
}
return 0;
}
// ---------------------------------------------------------------------------
int main()
{
}