用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、向串口写数据的时候最好用字节来写。