📄 从网上的c#串口通信源码例子转换成的c++串口通信代码——commport.hpp
字号:
///<summary>
///设置串口状态
///</summary>
///<param name="hFile">通信设备句柄</param>
///<param name="lpDCB">设备控制块</param>
//[DllImport(DLLPATH)]
//**********private: static extern bool SetCommState(int hFile, my_ref DCB lpDCB);
///<summary>
///读取串口超时时间
///</summary>
///<param name="hFile">通信设备句柄</param>
///<param name="lpCommTimeouts">超时时间</param>
//[DllImport(DLLPATH)]
//**********private: static extern bool GetCommTimeouts(int hFile, my_ref COMMTIMEOUTS lpCommTimeouts);
///<summary>
///设置串口超时时间
///</summary>
///<param name="hFile">通信设备句柄</param>
///<param name="lpCommTimeouts">超时时间</param>
//[DllImport(DLLPATH)]
//**********private: static extern bool SetCommTimeouts(int hFile, my_ref COMMTIMEOUTS lpCommTimeouts);
///<summary>
///读取串口数据
///</summary>
///<param name="hFile">通信设备句柄</param>
///<param name="lpBuffer">数据缓冲区</param>
///<param name="nNumberOfBytesToRead">多少字节等待读取</param>
///<param name="lpNumberOfBytesRead">读取多少字节</param>
///<param name="lpOverlapped">溢出缓冲区</param>
//[DllImport(DLLPATH)]
//**********private: static extern bool ReadFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToRead,
//**********my_ref int lpNumberOfBytesRead, my_ref OVERLAPPED lpOverlapped);
///<summary>
///写串口数据
///</summary>
///<param name="hFile">通信设备句柄</param>
///<param name="lpBuffer">数据缓冲区</param>
///<param name="nNumberOfBytesToWrite">多少字节等待写入</param>
///<param name="lpNumberOfBytesWritten">已经写入多少字节</param>
///<param name="lpOverlapped">溢出缓冲区</param>
//[DllImport(DLLPATH)]
//**********private: static extern bool WriteFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToWrite,
//**********my_ref int lpNumberOfBytesWritten, my_ref OVERLAPPED lpOverlapped);
//[DllImport(DLLPATH, SetLastError = true)]
//**********private: static extern bool FlushFileBuffers(int hFile);
//[DllImport(DLLPATH, SetLastError = true)]
//**********private: static extern bool PurgeComm(int hFile, uint dwFlags);
///<summary>
///关闭串口
///</summary>
///<param name="hObject">通信设备句柄</param>
//[DllImport(DLLPATH)]
//**********private: static extern bool CloseHandle(int hObject);
///<summary>
///得到串口最后一次返回的错误
///</summary>
//[DllImport(DLLPATH)]
//**********private: static extern uint GetLastError();
//#endregion
///<summary>
///设置DCB标志位
///</summary>
///<param name="whichFlag"></param>
///<param name="setting"></param>
///<param name="dcb"></param>
my_internal void SetDcbFlag(int whichFlag, int setting, DCB *dcb)
{
uint num;
setting = setting << whichFlag;
if ((whichFlag == 4) || (whichFlag == 12))
{
num = 3;
}
else if (whichFlag == 15)
{
num = 0x1ffff;
}
else
{
num = 1;
}
dcb->fBinary &= ~(num << whichFlag);
dcb->fBinary |= (uint)setting;
}
///<summary>
///建立与串口的连接
///</summary>
public: int Open()
{
DCB *dcb = new DCB();
COMMTIMEOUTS *ctoCommPort = new COMMTIMEOUTS();
// 打开串口
hComm = CreateFile(Port.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if (hComm == INVALID_HANDLE_VALUE)
{
return -1;
}
// 设置通信超时时间
GetCommTimeouts(hComm, my_ref ctoCommPort);
ctoCommPort->ReadTotalTimeoutConstant = ReadTimeout;
ctoCommPort->ReadTotalTimeoutMultiplier = 0;
ctoCommPort->WriteTotalTimeoutMultiplier = 0;
ctoCommPort->WriteTotalTimeoutConstant = 0;
SetCommTimeouts(hComm, my_ref ctoCommPort);
//设置串口参数
GetCommState(hComm, my_ref dcb);
dcb->DCBlength = sizeof(dcb);
dcb->BaudRate = BaudRate;
dcb->fBinary = 0;
dcb->ByteSize = (byte)ByteSize;
dcb->StopBits = StopBits;
dcb->Parity = (byte)Parity;
//------------------------------
SetDcbFlag(0, 1, dcb); //二进制方式
SetDcbFlag(1, (Parity == 0) ? 0 : 1, dcb);
SetDcbFlag(2, 0, dcb); //不用CTS检测发送流控制
SetDcbFlag(3, 0, dcb); //不用DSR检测发送流控制
SetDcbFlag(4, 0, dcb); //禁止DTR流量控制
SetDcbFlag(6, 0, dcb); //对DTR信号线不敏感
SetDcbFlag(9, 1, dcb); //检测接收缓冲区
SetDcbFlag(8, 0, dcb); //不做发送字符控制
SetDcbFlag(10, 0, dcb); //是否用指定字符替换校验错的字符
SetDcbFlag(11, 0, dcb); //保留NULL字符
SetDcbFlag(12, 0, dcb); //允许RTS流量控制
SetDcbFlag(14, 0, dcb); //发送错误后,继续进行下面的读写操作
//--------------------------------
dcb->wReserved = 0; //没有使用,必须为0
dcb->XonLim = 0; //指定在XOFF字符发送之前接收到缓冲区中可允许的最小字节数
dcb->XoffLim = 0; //指定在XOFF字符发送之前缓冲区中可允许的最小可用字节数
dcb->XonChar = 0; //发送和接收的XON字符
dcb->XoffChar = 0; //发送和接收的XOFF字符
dcb->ErrorChar = 0; //代替接收到奇偶校验错误的字符
dcb->EofChar = 0; //用来表示数据的结束
dcb->EvtChar = 0; //事件字符,接收到此字符时,会产生一个事件
dcb->wReserved1 = 0; //没有使用
if (!SetCommState(hComm, my_ref dcb))
{
return -2;
}
Opened = true;
return 0;
}
///<summary>
///关闭串口,结束通讯
///</summary>
public: void Close()
{
if (hComm != INVALID_HANDLE_VALUE)
{
CloseHandle(hComm);
}
}
///<summary>
///读取串口返回的数据
///</summary>
///<param name="NumBytes">数据长度</param>
public: int Read(my_ref byte bytData[], int NumBytes)
{
if (hComm != INVALID_HANDLE_VALUE)
{
OVERLAPPED *ovlCommPort = new OVERLAPPED();
unsigned long BytesRead = 0;
ReadFile(hComm, bytData, NumBytes, my_ref &BytesRead, my_ref ovlCommPort);
return BytesRead;
}
else
{
return -1;
}
}
///<summary>
///向串口写数据
///</summary>
///<param name="WriteBytes">数据数组</param>
public: int Write(byte WriteBytes[], int intSize)
{
if (hComm != INVALID_HANDLE_VALUE)
{
OVERLAPPED *ovlCommPort = new OVERLAPPED();
unsigned long BytesWritten = 0;
WriteFile(hComm, WriteBytes, intSize, my_ref &BytesWritten, my_ref ovlCommPort);
return BytesWritten;
}
else
{
return -1;
}
}
///<summary>
///清除接收缓冲区
///</summary>
///<returns></returns>
public: void ClearReceiveBuf()
{
if (hComm != INVALID_HANDLE_VALUE)
{
PurgeComm(hComm, PURGE_RXABORT | PURGE_RXCLEAR);
}
}
///<summary>
///清除发送缓冲区
///</summary>
public: void ClearSendBuf()
{
if (hComm != INVALID_HANDLE_VALUE)
{
PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR);
}
}
};
#endif // MY_INCLUDE__COMMPORT_H
// end of file "CommPort.h"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -