📄 serialport.cpp
字号:
/*
** FILENAME CSerialPort.h
**
** PURPOSE This class can read, write one serial port.
**
** CREATION DATE 04-22-2005
** LAST MODIFICATION 05-17-2005
**
** AUTHOR Yuangang Huang
**
**
*/
#include "stdafx.h"
#include "SerialPort.h"
#include <assert.h>
//
// Constructor
//
CSerialPort::CSerialPort()
{
m_hComm = NULL;
}
//
// delete serial handle
//
CSerialPort::~CSerialPort()
{
if (m_hComm != NULL)
{
CloseComPort(m_hComm);
m_hComm = NULL;
}
}
//
// Initialize the serial port.
//
BOOL CSerialPort::InitPort(CWnd* pPortOwner, // the owner (CWnd) of the port (receives message)
UINT portnr, // portnumber (1..4)
UINT baud, // baudrate
char parity, // parity
UINT databits, // databits
UINT stopbits // stopbits
)
{
ASSERT((portnr > 0) && (portnr < 5));
ASSERT(pPortOwner != NULL);
// set the serial port and save the owner window handle
m_pOwner = pPortOwner;
m_nPortNr = portnr;
BOOL bResult = FALSE;
char *szPort = new char[50];
char *szBaud = new char[50];
// if the port is already opened: close it
if (m_hComm != NULL)
{
CloseComPort(m_hComm);
m_hComm = NULL;
}
// prepare port strings
sprintf(szPort, "COM%d", portnr);
sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits);
// get a handle to the port
m_hComm = CreateFile(szPort, // communication port string (COMX)
GENERIC_READ | GENERIC_WRITE, // read/write types
0, // comm devices must be opened with exclusive access
NULL, // no security attributes
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
FILE_FLAG_OVERLAPPED, // Async I/O
0); // template must be 0 for comm devices
if (m_hComm == INVALID_HANDLE_VALUE)
{
// port not found
delete [] szPort;
delete [] szBaud;
return FALSE;
}
COMMTIMEOUTS CommTimeouts;
// set the timeout values
CommTimeouts.ReadIntervalTimeout = 1000;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant = 0;
// set timeout
if (SetCommTimeouts(m_hComm, &CommTimeouts))
{
if (GetCommState(m_hComm, &m_dcb)) //Get DCB
{
// m_dcb.fRtsControl = RTS_CONTROL_ENABLE; // set RTS bit high!
if (BuildCommDCB(szBaud, &m_dcb))
{
if (SetCommState(m_hComm, &m_dcb))
TRACE("Com Setup is finished\n"); // normal operation... continue
else
{
TRACE("SetCommState FAILED\n");
return FALSE;
} //end SetCommState()
}
else
{
TRACE("BuildCommDCB FAILED\n");
return FALSE;
} //end BuildCommDCB()
}
else
{
TRACE("GetCommState FAILED\n");
return FALSE;
} //end GetCommState()
}
else
{
TRACE("SetCommTimeouts FAILED\n");
return FALSE;
} //end SetCommTimeouts()
delete [] szPort;
delete [] szBaud;
// Set the Data Terminal Ready line
EscapeCommFunction(m_hComm, SETDTR);
// Set the Request to Send line
EscapeCommFunction(m_hComm, SETRTS);
// flush the port
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
return TRUE;
}
//
// Return the serial DCB structure
//
DCB CSerialPort::GetDCB()
{
return m_dcb;
}
//
//Write single byte or string to port
//
BOOL CSerialPort::WriteData(BYTE *mOutBuf, DWORD mNeedWrite, DWORD &mWriten)
{
BOOL success;
OVERLAPPED ov;
success = FALSE;
memset(&ov, 0, sizeof(ov));
ov.hEvent = CreateEvent(0, TRUE, FALSE, 0);
success = WriteFile(m_hComm, mOutBuf, mNeedWrite, &mWriten, &ov);
if(!success)
{
// ::AfxMessageBox("Fail to send ENQ"); //used when synchronization
// CloseComPort(m_hComm);
// return FALSE;
if (GetLastError() == ERROR_IO_PENDING)
{
BOOL pRet = GetOverlappedResult(m_hComm, &ov, &mWriten, TRUE);
if (!pRet)
{
TRACE("Error TO Written\n");
CloseHandle(ov.hEvent);
return false;
}
}
}
CloseHandle(ov.hEvent);
return TRUE;
}
//
//close serial port
//
void CSerialPort::CloseComPort(HANDLE comHandle)
{
// Clear the Data Terminal Ready line
EscapeCommFunction(comHandle, CLRDTR);
// Clear the Request to Send line
EscapeCommFunction(comHandle, CLRRTS);
CloseHandle(comHandle);
}
//
//Read data from serial port
//
BOOL CSerialPort::ReadData(BYTE *mInBuf, DWORD mNeedRead, DWORD &mRead)
{
BOOL success;
OVERLAPPED ov;
DWORD Event = 0;
BOOL Ret = FALSE;
success = FALSE;
memset(&ov, 0, sizeof(ov));
ov.hEvent = CreateEvent(0, TRUE, FALSE, 0);
// Ret = SetCommMask(m_hComm, EV_RXCHAR);
// Ret = WaitCommEvent(m_hComm, &Event, &ov);
// Sleep(50);
success = ReadFile(m_hComm, mInBuf, mNeedRead, &mRead, &ov);
if(!success) // || (mRead == 0))
{
if ( GetLastError () == ERROR_IO_PENDING)
{
while(!GetOverlappedResult(m_hComm, &ov, &mRead, TRUE ))
{
DWORD dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
continue;
}
}
//::AfxMessageBox("Error response from device for serial nember."); //used when synchronization
//CloseComPort(m_hComm);
//return FALSE;
}
CloseHandle(ov.hEvent);
return TRUE;
}
BOOL CSerialPort::GetData(BYTE *I_Buf, DWORD I_NeedWrite, BYTE *O_Buf)
{
DWORD ByteCount = 0;
DWORD ReceiveCount = 0;
//com communication
int Ret = WriteData(I_Buf, I_NeedWrite, ByteCount);
if (Ret)
{
//if writing successfully, then read data from com
Ret = ReadData(O_Buf, VERPACKETMAX, ReceiveCount);
}
else
{
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -