windows读写串口基本操作,以下用的vs2015 MFC编译:

serialport.h

#ifndef _SERIAL_20190304_H
#define _SERIAL_20190304_H

#include <string>
#include <Windows.h>
#include <stdint.h>

class CSerialPort
{
public:
CSerialPort();
~CSerialPort();

public:
void setConfig(const std::string& portNum, DWORD baudRate, BYTE byteSize, BYTE parityBit, BYTE stopBit);
bool openComm(); // 打开串口
void closeComm(); // 关闭串口
bool writeToComm(char* pdata); // 发送数据
bool readFromComm(char buffer[], DWORD dwLength); // 读取数据

public:
    bool m_bOpen; // 串口开关标志
private:

HANDLE m_hComm; // 通信设备
std::string m_portNum; // 串口号
DWORD m_dwBaudRate; // 波特率
BYTE m_byteSize; // 数据位
BYTE m_parityBit; // 校验位
BYTE m_stopBit; // 停止位

private:
    

enum BufferSize
{
MIN_BUFFER_SIZE = 256,
BUFFER_SIZE = 512,
MAX_BUFFER_SIZE = 1024
};

// 设置串口号
void setPortNum(const std::string& portNum)
{
this->m_portNum = portNum;
}
// 设置波特率
void setBaudRate(const uint32_t baudRate)
{
this->m_dwBaudRate = baudRate;
}
// 设置数据位
void setByteSize(const uint8_t byteSize)
{
this->m_byteSize = byteSize;
}
// 设置检验位
void setParityBit(const uint8_t parityBit)
{
this->m_parityBit = parityBit;
}
// 设置停止位
void setStopBit(const uint8_t stopBit)
{
this->m_stopBit = stopBit;
}

// 获取串口号
std::string getPortNum() { return m_portNum; }
// 获取波特率
uint32_t getBaudRate() { return m_dwBaudRate; }
// 获取数据位
uint8_t getByteSize() { return m_byteSize; }
// 获取检验位
uint8_t getParityBit() { return m_parityBit; }
// 获取停止位
uint8_t getStopBit() { return m_stopBit; }
};

#endif

serialport.cpp


#include "stdafx.h"
#include "serialport.h"
#include<windows.h>



CSerialPort::CSerialPort()
{
    m_bOpen = false;
}

CSerialPort::~CSerialPort()
{

}

void CSerialPort::setConfig(const std::string& portNum, DWORD baudRate, BYTE byteSize, BYTE parityBit, BYTE stopBit)
{
    m_portNum = (portNum);
    m_dwBaudRate = (baudRate);
    m_byteSize = (byteSize);
    m_parityBit = (parityBit);
    m_stopBit = (stopBit);
    m_bOpen = (false);
}

// 打开串口成功,返回 true

bool CSerialPort::openComm()
{
    if(m_bOpen)
        return true;

    m_hComm = CreateFileA(m_portNum.c_str(),
        GENERIC_READ | GENERIC_WRITE, //允许读和写
        0, //独占方式
        NULL, OPEN_EXISTING, //打开而不是创建
        0, //同步方式
        NULL
        );

    if (m_hComm == INVALID_HANDLE_VALUE)
    {
        char szBuf[1024] = { 0 };
        sprintf_s(szBuf, "打开串口 %s 失败,错误码: %d", m_portNum.c_str(), GetLastError());
        MessageBox(NULL, szBuf, "Warnning", MB_OK);

        return false;

    }
    else
    {
        DCB dcb;
        SetupComm(m_hComm, MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); // 设置读写缓冲区大小
        GetCommState(m_hComm, &dcb);
        dcb.BaudRate = m_dwBaudRate;
        dcb.ByteSize = m_byteSize;
        dcb.Parity = m_parityBit;
        dcb.StopBits = m_stopBit;

        if (!SetCommState(m_hComm, &dcb))
        {
            char szBuf[1024] = { 0 };
            wsprintf(szBuf, "串口设置失败,错误代码: %d", GetLastError());
            MessageBox(NULL, szBuf, "ERROR", MB_OK);

            return false;
        }

    }

    //在读写串口前,用 PurgeComm 函数清空缓冲区
    PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXABORT);

    m_bOpen = true;
    
    return true;

}

// 关闭串口

void CSerialPort::closeComm()
{
    m_bOpen = false;
    Sleep(200);
    CloseHandle(m_hComm);
}


// 向串口发送数据
bool CSerialPort::writeToComm(char* pData)
{
    DWORD dwLength = strlen(pData);
    DWORD dwError = 0;
    if (ClearCommError(m_hComm, &dwError, NULL) && dwError > 0)
    {
        PurgeComm(m_hComm, PURGE_TXABORT | PURGE_TXCLEAR);
    }

    DWORD dwTx = 0;
    BOOL ret = FALSE;
    ret = WriteFile(m_hComm, pData, dwLength, &dwTx, NULL);

    if (ret == FALSE)
    {
        char szBuf[1024] = { 0 };
        sprintf_s(szBuf, "读取数据失败, 错误代码: %d", GetLastError());
        MessageBox(NULL, szBuf, "Error", MB_OK);

        return false;
    }

    return true;


}

// 从串口中读取数据

bool CSerialPort::readFromComm(char buffer[], DWORD dwLength)
{
    COMSTAT comStat;
    DWORD dwError = 0;
    if (ClearCommError(m_hComm, &dwError, &comStat) && dwError > 0)
    {
        PurgeComm(m_hComm, PURGE_RXABORT | PURGE_RXCLEAR);
    }

    DWORD dwRx = 0; // 读入的字节数
    BOOL ret = FALSE;
    //BYTE* byReadData = new BYTE[dwLength];
    char szTmp[4] = { 0 };
    int sizeOfBytes = sizeof(szTmp);
    ret = ReadFile(m_hComm, buffer, dwLength, &dwRx, NULL); // 读入数据
    //char buf[1024] = {0};
    if (ret == TRUE)
    {
        
        //memcpy(buf, buffer, dwRx);
        //for (int i = 0; i < dwRx; ++i)
        //{
        //    sprintf_s(szTmp, "%02x", byReadData[i]);
        //    strcat_s(buffer, sizeOfBytes*dwLength, szTmp);
        //}

        //// 释放内存
        //delete byReadData;

    }
    else
    {
        char szBuf[1024] = { 0 };
        wsprintf(szBuf, "数据读取失败,错误代码: %d", GetLastError());
        MessageBox(NULL, szBuf, "Error", MB_OK);


        return false;
    }

    return true;
}

常规使用:

//thread1
bool bRet = false;
char recvBuf[1024] = { 0 };
if(m_serialport.m_bOpen)
  bRet = m_serialport.readFromComm(recvBuf, sizeof(recvBuf));
  
//thread2
char buf[1024] = {0};
if(m_serialport.m_bOpen)
  m_serialport.writeToComm(T2A(buf));    //注意加上T2A转换,可防止语句中与sed这种操作