用API操作串口

步骤:

  1、CreateFile,打开串口

  示例:g_hCOM = CreateFile(L"COM3", GENERIC_READ| GENERIC_WRITE, 0, NULL,  OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);  

  //必须用0,表示以独占的模式来占用串口

  //打开除文件之外的设备时,用 OPEN_EXISTING

  2、SetupComm,用来设置缓存大小

  3、SetCommTimeouts,设置读写的超时时间

  4、SetCommState,用来设置一些串口参数,如波特率,读取的字节数,是否奇偶检验。

  5、WriteFile,向串口发送数据

  6、ReadFile,从串口读数据

  7、采用异步的方式来获取数据,如IO完成端口

代码:

#include <iostream>
#include <afx.h>
#include <process.h>
#include <stdio.h>
using namespace std;

HANDLE g_hCompletionPort, g_hCOM, g_hEvent;

byte buff[1000];
byte writeBuf = 0x1a;//这个数据是针对我这块板子的

DWORD dwErr;

UINT WINAPI WriteData(PVOID pParameter)
{
	OVERLAPPED overLap;
	overLap.hEvent = 0;
	overLap.Offset = 0;
	overLap.OffsetHigh = 0;

	DWORD dwWrite;
	WriteFile(g_hCOM, &writeBuf, sizeof(writeBuf), &dwWrite, &overLap);

	DWORD dwTransLen = 0;
	DWORD dwKey = 0;
	LPOVERLAPPED  poverLap;
	BOOL IsOk = GetQueuedCompletionStatus(g_hCompletionPort, &dwTransLen, &dwKey, &poverLap, INFINITE);
	if(IsOk)
	{
		cout << "Translate Num: " <<poverLap->InternalHigh << endl;
		cout << "Write Success" << endl;
		SetEvent(g_hEvent);
	}
	else
	{
		dwErr = GetLastError();
		cout << "Write Failed. Code = " << dwErr << endl;
	}

	return 0;
}

UINT WINAPI ReadData(PVOID pParame)
{
	//SetCommMask(g_hCOM, EV_RXCHAR | EV_TXEMPTY);

	OVERLAPPED overLap;
	overLap.hEvent = 0;
	overLap.Offset = 0;
	overLap.OffsetHigh = 0;
	ReadFile(g_hCOM, buff, 1000, 0, &overLap);

	DWORD dwTransLen = 0;
	DWORD dwKey = 0;
	LPOVERLAPPED  poverLap = {0};
	BOOL IsOk = GetQueuedCompletionStatus(g_hCompletionPort, &dwTransLen, &dwKey, &poverLap, INFINITE);

	if(IsOk)
	{
		cout << "Read Success." << endl;
		cout << "The Length is : " << poverLap->InternalHigh << endl;
		for (int i = 0; i < 10; i++)
		{
			printf("%02X  ", buff[i]);
		}
		cout << endl << endl;
	}
	else
	{
		dwErr = GetLastError();
		cout << "Read failed. Code = : " << dwErr << endl;
	}

	SetEvent(g_hEvent);

	return 0;
}

void main()
{
	g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	//创建IO完成端口
	g_hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0);
	//打开文件
	g_hCOM = CreateFile(L"COM3", GENERIC_READ| GENERIC_WRITE, 0, NULL, 
		OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

	//将该设备(文件)与IO完成端口相关联,以获得通知
	HANDLE h = CreateIoCompletionPort(g_hCOM, g_hCompletionPort, NULL, 0);
	if(h == g_hCompletionPort)
		cout << "关联成功" << endl;
	else
	{
		dwErr = GetLastError();
		cout << "关联失败 : " << dwErr << endl;
	}

//	SetCommMask(g_hCOM, EV_RXCHAR | EV_TXEMPTY);
	SetupComm(g_hCOM, 1024, 512);
	PurgeComm(g_hCOM, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);


	COMMTIMEOUTS CommTimeout;
	CommTimeout.ReadIntervalTimeout = 5;
	CommTimeout.ReadTotalTimeoutConstant = 1000;
	CommTimeout.ReadTotalTimeoutMultiplier = 5;
	CommTimeout.WriteTotalTimeoutConstant = 1000;
	CommTimeout.WriteTotalTimeoutMultiplier = 5;

	SetCommTimeouts(g_hCOM, &CommTimeout);

	DCB dcb;
	GetCommState(g_hCOM, &dcb);
	dcb.BaudRate = 4800;
	dcb.ByteSize = 8;
	dcb.Parity = NOPARITY;
	dcb.StopBits = ONESTOPBIT;
	dcb.fBinary = TRUE;
	dcb.fParity = FALSE;

	SetCommState(g_hCOM, &dcb);

	HANDLE hThread[20];
	hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WriteData, NULL, 0, NULL);

	for (int i = 1; i < 20; i++)
	{
		WaitForSingleObject(g_hEvent, INFINITE);
		hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReadData, NULL, 0, NULL);
		ResetEvent(g_hEvent);
	}

	WaitForMultipleObjects(20, hThread, TRUE, INFINITE);

	CloseHandle(g_hCOM);
	CloseHandle(g_hCompletionPort);
	CloseHandle(g_hEvent);
}

遇到的问题:

1、向串口写数据的时候最好用字节来写。

原文地址:https://www.cnblogs.com/wang-can/p/3338020.html