Windowsはシリアルポートを開き、シリアルポートの読み取りと書き込みを行い、シリアルポートを自動的に認識します。
シリアルポートは、非同期モード、つまりシリアルポートの読み取りと書き込みのための非ブロッキングモードで読み取りと書き込みを行います
シリアルポートの名前は、「COM3」、「COM4」、「COM22」などです。
その中で、COM1からCOM9は正常に開くことができますが、COM10以降は何よりも開くことができず、特別な処理が必要です。
また、COM10より上のオープン方法は、 「\\\\。\\ COM10」、「\\\\。\\ COM11」、「\\\\。\\ COM22」などです。これは、COM10より上のシリアルポート名です。オープンメソッド
シリアルポートを開きます。
//Open the UART
BOOL OpenUartPort(char *UartPortName)
{
BOOL bResult = true;
hComm = CreateFile(
UartPortName,
GENERIC_WRITE | GENERIC_READ, //访问权限
0, //不共享
NULL, //返回的句柄不允许被子进程继承
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, //0:同步模式,FILE_FLAG_OVERLAPPED:异步模式
0 //不使用临时文件句柄
);
if(INVALID_HANDLE_VALUE == hComm)
{
PrintLogCom("Open Failed!!!\n");
bResult = false;
}
else
{
PrintLogCom("Open Successfully!!!\n");
if(InitUartPort(hComm, 9600, 8, NOPARITY, ONESTOPBIT))
{
PrintLogCom("Init Uart Port OK!!!\n");
}
else
{
//PrintLogCom("Init Uart Port Failed!!!\n");
bResult = false;
Close_UartPort();
}
}
return bResult;
}
シリアルポートを初期化します。
//Init UART
BOOL InitUartPort(HANDLE hComm, DWORD BaudRate, BYTE ByteSize, BYTE Parity, BYTE StopBits)
{
BOOL bResult = true;
char buffer[50]="";
//设置接收缓冲区和输出缓冲区的大小
DWORD dwInQueue = 1024;
DWORD dwOutQueue = 1024;
if(!SetupComm(hComm, dwInQueue, dwOutQueue))
{
//PrintLogCom("Set In and Out Buffer Failed!!!\n");
bResult = false;
}
else
{
//PrintLogCom("Set Input and Output Buffer OK!!!\n");
//设置读写的超时时间 以毫秒计算
COMMTIMEOUTS timeouts;
//for read ReadTotalTimeouts = ReadTotalTimeoutMultiplier * ToReadByteNumber + ReadTotalTimeoutConstant,
timeouts.ReadIntervalTimeout = MAXDWORD; //接收两个字符之间的最长超时时间
timeouts.ReadTotalTimeoutMultiplier = 0; //与读取要读字节数相乘的系数
timeouts.ReadTotalTimeoutConstant = 0; //读取总超时时间常量
//for write WriteTotalTimeouts = WriteTotalTimeoutMultiplier * ToWriteByteNumber + WriteTotalTimeoutConstant
//timeouts.WriteTotalTimeoutMultiplier = 0;
//timeouts.WriteTotalTimeoutConstant = 0;
if(!SetCommTimeouts(hComm, &timeouts))
{
//PrintLogCom("Set Read/Write Timeouts Failed!!!\n");
bResult = false;
}
else
{
//PrintLogCom("Set Read/Write Timeouts OK!!!\n");
//设置DCB(Device-Control-Block)
DCB dcb;
if(!GetCommState(hComm, &dcb))
{
//PrintLogCom("Get Com DCB Failed!!!\n");
bResult = false;
}
else
{
//PrintLogCom("Get Com DCB Successfully!!!\n");
/*
sprintf(buffer,"BaudRate = %ld",dcb.BaudRate);
PrintLogCom(buffer);
sprintf(buffer,"ByteSize = %u\n",dcb.ByteSize);
PrintLogCom(buffer);
sprintf(buffer,"Parity = %u\n",dcb.Parity);
PrintLogCom(buffer);
sprintf(buffer,"StopBits = %u\n",dcb.StopBits);
PrintLogCom(buffer);
sprintf(buffer,"XonChar = %d\n", dcb.XonChar);
PrintLogCom(buffer);
*/
memset(&dcb, 0, sizeof(dcb));
dcb.BaudRate = BaudRate;
dcb.ByteSize = ByteSize;
dcb.Parity = Parity;
dcb.StopBits = StopBits;
dcb.XonChar = 1;
if(!SetCommState(hComm, &dcb))
{
//PrintLogCom("Set Com Failed!!!\n");
bResult = false;
}
else
{
//PrintLogCom("Set Com Successfully!!!\n");
//清空接收缓存和输出缓存的buffer
if(!PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR))
{
//PrintLogCom("Clean up in buffer and out buffer Failed!!!\n");
bResult = false;
}
else
{
//PrintLogCom("Clean up in buffer and out buffer OK!!!\n");
}
}
}
}
}
return bResult;
}
读串口
BOOL RcvDataFromUartPort(HANDLE hComm, void *RcvBuf, DWORD ToRcvDataLen, DWORD *RcvedDataLen, LPOVERLAPPED lpOverlapped)
{
BOOL bResult = true;
DWORD dwTempRcvedDataLen = 0;
DWORD dwError;
if (ClearCommError(hComm,&dwError,NULL))
{
PurgeComm(hComm,PURGE_TXABORT | PURGE_TXCLEAR);
}
if(hComm != INVALID_HANDLE_VALUE)
{
if(!ReadFile(hComm, RcvBuf, ToRcvDataLen, &dwTempRcvedDataLen, lpOverlapped))
{
if (GetLastError() == ERROR_IO_PENDING)
{
while (!GetOverlappedResult(hComm,lpOverlapped,&dwTempRcvedDataLen,FALSE))
{
if (GetLastError() == ERROR_IO_INCOMPLETE)
{
continue;
}
else
{
ClearCommError(hComm,&dwError,NULL);
bResult = false;
break;
}
}
}
}
}
else
{
bResult = false;
}
*RcvedDataLen = dwTempRcvedDataLen;
return bResult;
}
シリアルポートの書き込み
BOOL SendDataToUartPort(HANDLE hComm, void *SndBuf, DWORD SendDataLen, DWORD *SentDataLen, LPOVERLAPPED lpOverlapped)
{
BOOL bResult = true;
DWORD dwTempSndDataLen;
DWORD dwError;
if (ClearCommError(hComm,&dwError,NULL))
{
PurgeComm(hComm,PURGE_TXABORT | PURGE_TXCLEAR);
}
if(hComm != INVALID_HANDLE_VALUE)
{
if(!WriteFile(hComm, SndBuf, SendDataLen, &dwTempSndDataLen, lpOverlapped))
{
if (GetLastError() == ERROR_IO_PENDING)
{
while (!GetOverlappedResult(hComm,lpOverlapped,&dwTempSndDataLen,FALSE))
{
if (GetLastError() == ERROR_IO_INCOMPLETE)
{
continue;
}
else
{
ClearCommError(hComm,&dwError,NULL);
bResult = false;
break;
}
}
}
}
}
else
{
bResult = false;
}
*SentDataLen = dwTempSndDataLen;
return bResult;
}