📄 rs232.cpp
字号:
//---------------------------------------------------------------------------
#pragma hdrstop
#include "windows.h"
#include <tchar.h>
#include <stdio.h>
#include "RS232.h"
#include "TimeUtil.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#define IN_BUFFER_SIZE 8192
#define OUT_BUFFER_SIZE IN_BUFFER_SIZE
#define RCV_RING_SIZE IN_BUFFER_SIZE
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CRS232::CRS232(const BOOL bXonXoff)
{
m_hComPort = INVALID_HANDLE_VALUE;
m_byPort = 1; //COM1
m_dwBaudRate = 19200; //default value
m_bXonXoff = bXonXoff;
m_iManualIntervalTimeout = 10;
m_iManualTotalTimeout = 200;
}
CRS232::~CRS232()
{
CloseSerialPort();
}
void CRS232::SetRTS(int val)
{
if(val)
EscapeCommFunction(m_hComPort, SETRTS);
else
EscapeCommFunction(m_hComPort, CLRRTS);
}
void CRS232::SetDTR(int val)
{
if(val)
EscapeCommFunction(m_hComPort, SETDTR);
else
EscapeCommFunction(m_hComPort, CLRDTR);
}
int CRS232::WriteBytes(const void *buf, int num)
{
if(m_hComPort == INVALID_HANDLE_VALUE)
return 0;
DWORD nWrite = 0;
BOOL bSuccess = WriteFile(m_hComPort, buf, num, &nWrite, 0);
if(bSuccess && (nWrite == (DWORD)num))
return num;
else
return 0;
}
int CRS232::ReadBytes(BYTE *byRcv, const DWORD dwMaxBytes, BOOL bAuto, BOOL bInterval)
{
DWORD dwRdBytes = dwMaxBytes;
if((m_hComPort == INVALID_HANDLE_VALUE) || (dwRdBytes > RCV_RING_SIZE))
return 0;
// bAuto = TRUE;
if (!bAuto)
{
dwRdBytes = 0;
// DWORD dwInBufferBytes = 0;
DWORD dwStartTime = ::GetTickCount();
while(TRUE)
{
DWORD dwNowTime = ::GetTickCount();
if(dwNowTime - dwStartTime > m_iManualTotalTimeout)
break;
DWORD dwErrorMask;
COMSTAT comstat;
ClearCommError(m_hComPort, &dwErrorMask, &comstat);
if(comstat.cbInQue == 0)
{
// Sleep(5);
delay(5);
continue;
}
else
{
if(dwRdBytes != comstat.cbInQue)
{
dwRdBytes = comstat.cbInQue;
// Sleep(m_iManualIntervalTimeout);
delay(m_iManualIntervalTimeout);
}
else
{
if (bInterval) //20080306
break;
}
}
}
}
if (dwRdBytes==0)
return 0;
DWORD dwNumRead = 0;
BOOL bSuccess = ReadFile(m_hComPort, byRcv, dwRdBytes, &dwNumRead, NULL);
if(bSuccess)
return (int)dwNumRead;
else
return 0;
}
BOOL CRS232::OpenSerialPort(const BYTE byPort, const DWORD dwBaudRate)
{
if (m_hComPort!=INVALID_HANDLE_VALUE && byPort==m_byPort && m_dwBaudRate==dwBaudRate)
return TRUE;
CloseSerialPort();
m_byPort = byPort;
m_dwBaudRate = dwBaudRate;
TCHAR szCOMPort[MAX_PATH];
_stprintf(szCOMPort, TEXT("\\\\.\\COM%d"), m_byPort);
m_hComPort = CreateFile(szCOMPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(m_hComPort == INVALID_HANDLE_VALUE)
return FALSE;
DCB dcb;
dcb.DCBlength = sizeof(dcb);
if(!GetCommState(m_hComPort, &dcb))
{
CloseSerialPort();
return FALSE;
}
memcpy(&m_dcbPrev, &dcb, sizeof(DCB));
//basic settings
dcb.BaudRate = m_dwBaudRate;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
//common
dcb.fBinary = TRUE; //MUST
dcb.fParity = FALSE;
//hardware control
dcb.fDtrControl = DTR_CONTROL_ENABLE;//DTR_CONTROL_DISABLE;
dcb.fOutxCtsFlow = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
//software control
if(TRUE == m_bXonXoff)
{
dcb.fInX = TRUE;
dcb.fOutX = TRUE;
dcb.XonChar = (char)0x11; //DC1
dcb.XoffChar = (char)0x13; //DC3
dcb.EvtChar = (char)0x0A;
}
else
{
dcb.fInX = FALSE;
dcb.fOutX = FALSE;
dcb.XonChar = (char)0xFF;
dcb.XoffChar = (char)0xFF;
dcb.EvtChar = (char)0xFF;//0x00;
}
dcb.XoffLim = 100;
dcb.XonLim = 100;
///////////
dcb.fAbortOnError = FALSE;
dcb.fBinary = TRUE; //Windows must be TRUE
dcb.fNull = FALSE; //MUST
dcb.ErrorChar = 0x00;
dcb.EofChar = 0x00;
dcb.fErrorChar = FALSE;
///////////
// Set the new comm port settings
if(!SetCommState(m_hComPort, &dcb))
{
CloseSerialPort();
return FALSE;
}
//3. Set timeout
COMMTIMEOUTS tos;
// Set the timeouts so that ReadFile will return after certain time
tos.ReadIntervalTimeout = 0;
tos.ReadTotalTimeoutMultiplier = 0;
tos.ReadTotalTimeoutConstant = 250;
tos.WriteTotalTimeoutMultiplier = 10;
tos.WriteTotalTimeoutConstant = 0;
if(!SetCommTimeouts(m_hComPort, &tos))
{
CloseSerialPort();
return FALSE;
}
//4. Init serial port
if(!SetupComm(m_hComPort, IN_BUFFER_SIZE, OUT_BUFFER_SIZE))
{
CloseSerialPort();
return FALSE;
}
//5. Clear IN/OUT buffer
if(!PurgeComm(m_hComPort, PURGE_TXCLEAR | PURGE_RXCLEAR))
{
CloseSerialPort();
return FALSE;
}
#if 0
//6. Clear the Data Terminal Ready (DTR) line and Request to Send (RTS) line
EscapeCommFunction(m_hComPort, CLRDTR);
EscapeCommFunction(m_hComPort, CLRRTS);
#endif
return TRUE;
}
void CRS232::CloseSerialPort()
{
if(m_hComPort != INVALID_HANDLE_VALUE)
{
SetCommState(m_hComPort, &m_dcbPrev);
SetCommTimeouts(m_hComPort, &m_timeoutPrev);
PurgeComm(m_hComPort, PURGE_RXCLEAR | PURGE_TXCLEAR);
CloseHandle(m_hComPort);
m_hComPort = INVALID_HANDLE_VALUE;
}
}
//Wait for dwTimeout ms.
//Check how many byte(s) received.
UINT CRS232::CheckInbuffer(const DWORD dwTimeout)
{
if(m_hComPort == INVALID_HANDLE_VALUE)
return 0;
DWORD dwInBufferBytes = 0;
DWORD dwStartTime = ::GetTickCount();
BYTE byNoMoreCnt = 0;
while(TRUE)
{
//check if timeout
DWORD dwNowTime = ::GetTickCount();
if(dwNowTime - dwStartTime > dwTimeout)
break;
//how many bytes in RX buffer?
DWORD dwErrorMask;
COMSTAT comstat;
ClearCommError(m_hComPort, &dwErrorMask, &comstat);
DWORD dwLastCheckLength = dwInBufferBytes; //keep last time check va
dwInBufferBytes = comstat.cbInQue;
if(dwInBufferBytes == 0) //no byte received yet
{
delay(5);
continue; //can be timeout after dwTimeout ms
}
else
{
if(dwInBufferBytes == dwLastCheckLength) //no more bytes received this round, assume there is no more bytes from FW
{
if(++byNoMoreCnt >= 1 && (dwNowTime - dwStartTime > dwTimeout)) //no more byte(s) received.
break;
}
else //may be more
byNoMoreCnt = 0;
}
delay(12);
}
return (UINT)dwInBufferBytes;
}
void CRS232::ClearAllBuffer()
{
if(m_hComPort != INVALID_HANDLE_VALUE)
{
PurgeComm(m_hComPort, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_RXABORT);
}
}
void CRS232::SetReadTimeOut(int ims)
{
COMMTIMEOUTS tos;
GetCommTimeouts(m_hComPort, &tos);
tos.ReadTotalTimeoutMultiplier = 0;
tos.ReadTotalTimeoutConstant = ims;
SetCommTimeouts(m_hComPort, &tos);
}
void CRS232::SetWriteTimeOut(int ims)
{
COMMTIMEOUTS tos;
GetCommTimeouts(m_hComPort, &tos);
tos.WriteTotalTimeoutMultiplier = 0;
tos.WriteTotalTimeoutConstant = ims;
SetCommTimeouts(m_hComPort, &tos);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -