一、测试——打开一个串口
#include <iostream>
#include <cstdlib>
#include <Windows.h>
using namespace std;
bool OpenPort(); //打开串口
bool OpenPort()
{
HANDLE hComm;
hComm = CreateFile("COM1", //串口编号
GENERIC_READ | GENERIC_WRITE, //允许读写
0, //通讯设备必须以独占方式打开
NULL,
OPEN_EXISTING, //通讯设备已存在
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //重叠方式
NULL); //通讯设备不能用模板打开
if (hComm == INVALID_HANDLE_VALUE)
{
CloseHandle(hComm);
return FALSE;
}
else
return TRUE;
}
int main()
{
bool open;
open = OpenPort();
if (open)
cout << "Open serial port successfully!" << endl;
else
cout << "Open serial port unsuccessfully!" << endl;
return EXIT_SUCCESS;
}
二、测试——串口读写数据
#include <Windows.h>
#include <iostream>
#include <cstdlib>
HANDLE hComm;
OVERLAPPED OverLapped;
COMSTAT Comstat;
DWORD dwCommEvents;
bool OpenPort(unsigned int portNum); //打开串口 -- 选择需要打开的串口号
bool SetupDCB(int rate_arg); //设置DCB
bool SetupTimeout(DWORD ReadInterval, DWORD ReadTotalMultiplier, DWORD
ReadTotalConstant, DWORD WriteTotalMultiplier, DWORD WriteTotalConstant); //设置超时
void ReciveChar(); //接收字符
bool WriteChar(char* szWriteBuffer, DWORD dwSend); //发送字符
int main()
{
// 串口2
if (OpenPort(2))
std::cout << "Open port success" << std::endl;
// data control block
if (SetupDCB(9600))
std::cout << "Set DCB success" << std::endl;
// 设置通讯超时时间
if (SetupTimeout(0, 0, 0, 0, 0))
std::cout << "Set timeout success" << std::endl;
// 清除串口:
PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
char write_warning[] = "Please send data:";
WriteChar(write_warning, 20);
std::cout << "Received data:";
ReciveChar();
return EXIT_SUCCESS;
}
bool OpenPort(unsigned int portNum)
{
char comm[] = "COM";
char PortNum[5];
sprintf_s(PortNum, "COM%d", portNum);
hComm = CreateFile(PortNum,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (hComm == INVALID_HANDLE_VALUE)
return FALSE;
else
return true;
}
bool SetupDCB(int rate_arg)
{
DCB dcb;
memset(&dcb, 0, sizeof(dcb));
if (!GetCommState(hComm, &dcb))//获取当前DCB配置
{
return FALSE;
}
dcb.DCBlength = sizeof(dcb);
/* ---------- Serial Port Config ------- */
dcb.BaudRate = rate_arg;
dcb.Parity = NOPARITY;
dcb.fParity = 0;
dcb.StopBits = ONESTOPBIT;
dcb.ByteSize = 8;
dcb.fOutxCtsFlow = 0;
dcb.fOutxDsrFlow = 0;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = 0;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fOutX = 0;
dcb.fInX = 0;
dcb.fErrorChar = 0;
dcb.fBinary = 1;
dcb.fNull = 0;
dcb.fAbortOnError = 0;
dcb.wReserved = 0;
dcb.XonLim = 2;
dcb.XoffLim = 4;
dcb.XonChar = 0x13;
dcb.XoffChar = 0x19;
dcb.EvtChar = 0;
if (!SetCommState(hComm, &dcb))
{
return false;
}
else
return true;
}
bool SetupTimeout(DWORD ReadInterval, DWORD ReadTotalMultiplier, DWORD
ReadTotalConstant, DWORD WriteTotalMultiplier, DWORD WriteTotalConstant)
{
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = ReadInterval;
timeouts.ReadTotalTimeoutConstant = ReadTotalConstant;
timeouts.ReadTotalTimeoutMultiplier = ReadTotalMultiplier;
timeouts.WriteTotalTimeoutConstant = WriteTotalConstant;
timeouts.WriteTotalTimeoutMultiplier = WriteTotalMultiplier;
if (!SetCommTimeouts(hComm, &timeouts))
{
return false;
}
else
return true;
}
void ReciveChar()
{
bool bRead = TRUE;
bool bResult = TRUE;
DWORD dwError = 0;
DWORD BytesRead = 0;
char RXBuff;
for (;;)
{
bResult = ClearCommError(hComm, &dwError, &Comstat);
if (Comstat.cbInQue == 0)
continue;
if (bRead)
{
bResult = ReadFile(hComm, //通信设备(此处为串口)句柄,由CreateFile()返回值得到
&RXBuff, //指向接收缓冲区
1, //指明要从串口中读取的字节数
&BytesRead, //
&OverLapped); //OVERLAPPED结构
// *******************************************************************************************
// RXBuff 保存了从串口中接收的数据
std::cout << RXBuff;
if (RXBuff == ' ')
{
puts("");
}
if (!bResult)
{
switch (dwError == GetLastError())
{
case ERROR_IO_PENDING:
bRead = FALSE;
break;
default:
break;
}
}
}
else
{
bRead = TRUE;
}
}
if (!bRead)
{
bRead = TRUE;
bResult = GetOverlappedResult(hComm,
&OverLapped,
&BytesRead,
TRUE);
}
}
bool WriteChar(char* szWriteBuffer, DWORD dwSend)
{
bool bWrite = TRUE;
bool bResult = TRUE;
DWORD BytesSent = 0;
HANDLE hWriteEvent = NULL;
ResetEvent(hWriteEvent);
if (bWrite)
{
OverLapped.Offset = 0;
OverLapped.OffsetHigh = 0;
bResult = WriteFile(hComm, //通信设备句柄,CreateFile()返回值得到
szWriteBuffer, //指向写入数据缓冲区
dwSend, //设置要写的字节数
&BytesSent, //
&OverLapped); //指向异步I/O数据
if (!bResult)
{
DWORD dwError = GetLastError();
switch (dwError)
{
case ERROR_IO_PENDING:
BytesSent = 0;
bWrite = FALSE;
break;
default:
break;
}
}
}
if (!bWrite)
{
bWrite = TRUE;
bResult = GetOverlappedResult(hComm,
&OverLapped,
&BytesSent,
TRUE);
if (!bResult)
{
std::cout << "GetOverlappedResults() in WriteFile()" << std::endl;
}
}
if (BytesSent != dwSend)
{
std::cout << "WARNING: WriteFile() error.. Bytes Sent:" << BytesSent << "; Message Length: " << strlen((char*)szWriteBuffer) << std::endl;
}
return TRUE;
}
//
之后,运行之后,在串口助手中会看到内容:
演示如下:算了不演示了,自己试一下。演示不好,留言给我。
【注】 此串口操作是对网上某大神的改良,但是网页被我关闭了,如果侵犯到原作者权益,请联系博主及时删除。(不过这都是基础的串口通讯,应该不会吧。。。)