串口通讯

一、测试——打开一个串口

#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;

}

//
之后,运行之后,在串口助手中会看到内容:
演示如下:算了不演示了,自己试一下。演示不好,留言给我。

【注】 此串口操作是对网上某大神的改良,但是网页被我关闭了,如果侵犯到原作者权益,请联系博主及时删除。(不过这都是基础的串口通讯,应该不会吧。。。)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值