📄 serial.cpp
字号:
// Serial.cpp
#include "stdafx.h"
#include "Serial.h"
CSerial::CSerial()
{
// memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
// memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
//configure serial port 1:9600bps
m_hIDComDev = NULL;
m_bOpened = FALSE;
ComPort = 1;
BaudRate = 115200;
}
CSerial::~CSerial()
{
Close();
}
BOOL CSerial::Open()
{
if( m_bOpened ) return( TRUE );
DCB dcb;
m_hIDComDev = CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
//异步I/0操作
if( m_hIDComDev == NULL ) return( FALSE );
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) ); //configure read OVERLAPPED strucure
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) ); //configure write OVERLAPPED strucure
COMMTIMEOUTS CommTimeOuts; //Timeout operation
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 5; //5ms write every byte
CommTimeOuts.WriteTotalTimeoutConstant = 500;
SetCommTimeouts( m_hIDComDev, &CommTimeOuts );
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); //create null read event
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); //create null write event
dcb.DCBlength = sizeof( DCB );
GetCommState( m_hIDComDev, &dcb );
dcb.BaudRate = BaudRate;
dcb.ByteSize = 8;
// unsigned char ucSet;
// ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );
// ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );
// ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );
BuildCommDCB( "115200,N,8,1", &dcb );
if( ! SetCommState( m_hIDComDev, &dcb ) ||
! SetupComm( m_hIDComDev, 10*1024, 1024 ) ||
m_OverlappedRead.hEvent == NULL ||
m_OverlappedWrite.hEvent == NULL )
{
// DWORD dwError = GetLastError();
MessageBox( NULL, "Port open failure!", "Port Error", MB_OK );
if( m_OverlappedRead.hEvent != NULL )
CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL )
CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hIDComDev );
return( FALSE );
}
m_bOpened = TRUE;
return( m_bOpened );
}
BOOL CSerial::Close( void )
{
if( !m_bOpened || m_hIDComDev == NULL ) return( TRUE );
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hIDComDev );
m_bOpened = FALSE;
m_hIDComDev = NULL;
return( TRUE );
}
BOOL CSerial::WriteCommByte( unsigned char ucByte )
{
BOOL bWriteStat;
DWORD dwBytesWritten;
bWriteStat = WriteFile( m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite );
if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) )
{
if( WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 ) ) dwBytesWritten = 0;
else
{
GetOverlappedResult( m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE );
m_OverlappedWrite.Offset += dwBytesWritten;
}
}
return( TRUE );
}
int CSerial::SendData( const char * buffer )
{
if( !m_bOpened || m_hIDComDev == NULL )
{
MessageBox( NULL, "Please open the port first!", "PORT ERROR", MB_OK );
return( 0 );
}
DWORD dwBytesWritten = 0;
WriteFile(m_hIDComDev, buffer, strlen(buffer), &dwBytesWritten, &m_OverlappedWrite);
if( WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 ) ) dwBytesWritten = 0; //timeout exit
else
{ //send some bytes
GetOverlappedResult( m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE );
m_OverlappedWrite.Offset += dwBytesWritten;
}
return( (int) dwBytesWritten );
}
int CSerial::ReadDataWaiting( void )
{
if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
return( (int) ComStat.cbInQue );
}
int CSerial::ReadData( unsigned char * buffer, int limit )
{
if( !m_bOpened || m_hIDComDev == NULL )
{
MessageBox( NULL, "Please open the port first!", "PORT ERROR", MB_OK );
return( 0 );
}
BOOL bReadStatus;
DWORD dwBytesRead, dwErrorFlags;
COMSTAT ComStat;
// unsigned char * inbuffer;
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
if( !ComStat.cbInQue )
return( 0 );
//receive some bytes
dwBytesRead = (DWORD) ComStat.cbInQue;
if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;
// inbuffer = ( unsigned char * )malloc( dwBytesRead );
// bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
if( !bReadStatus )
{ //read failure
if( GetLastError() == ERROR_IO_PENDING ) //failure:ERROR_IO_PENDING
{ //be waiting for Event or timeout
WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
// buffer = inbuffer;
// free( inbuffer );
return( (int) dwBytesRead );
}
//failure:other bad messages
// buffer = inbuffer;
// free( inbuffer );
return( 0 ); //be failure to receive bytes
}
//read success : return dwBytesRead
// buffer = inbuffer;
// free( inbuffer );
return( (int) dwBytesRead );
}
/*
//发送初始化命令
void CSerial::SendInitCommand()
{//填充数据
UCHAR tempstr[16];
memset(tempstr,0x00,16);
tempstr[0] = 0x55;
tempstr[1] = 0xAA;
tempstr[2] = 0x0B;
tempstr[7] = 0x0B;
ReadData(tempstr,MAX_BUFFER_SIZE);
Sleep(10);
SendData((PCHAR)tempstr,8);//如果数据包长度为8(包括包头等数据)
}
void CSerial::EncapsulateData(BYTE ParamCount, BYTE ParamData[MAX_SENDOUT_PARAM_LEN],
BYTE ReturnData[MAX_SENDOUT_PARAM_LEN + 3])// 55 AA 校验
{
BYTE loop;
BYTE tempdata;
if(ParamCount == 0)
{
}
tempdata = ParamData[0];
for(loop = 1; loop < ParamCount; loop++)
{
tempdata ^= ParamData[loop];
}//最后得到校验码
ReturnData[0] = 0x55;
ReturnData[1] = 0xAA;
memcpy(&ReturnData[2],ParamData,MAX_SENDOUT_PARAM_LEN);
ReturnData[ 2 + MAX_SENDOUT_PARAM_LEN] = tempdata;
}
//发送所有其他数据命令
int CSerial::SendDataCommand(BYTE ParamCount, BYTE ParamData[MAX_SENDOUT_PARAM_LEN])
{
PCHAR tempstr[MAX_BUFFER_SIZE];
BYTE SendCommandData[MAX_SENDOUT_PARAM_LEN + 3]; // 55 AA 校验
EncapsulateData(ParamCount, ParamData,SendCommandData);//打包数据
ReadData(tempstr,MAX_BUFFER_SIZE);
Sleep(10);
int a = SendData((PCHAR)SendCommandData, MAX_SENDOUT_PARAM_LEN + 3);
return a;
}
*/
long CSerial::GetInBufferCount()
{
COMSTAT cs;
DWORD dwError;
ClearCommError(m_hIDComDev, &dwError, &cs);
return cs.cbInQue;
}
BOOL CSerial::WaitEvent(LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped)
{
return WaitCommEvent(m_hIDComDev, lpEvtMask, lpOverlapped);
}
void CSerial::SetRcvEvent(BOOL bevn)
{
if(!m_bOpened) return;
if(bevn)
SetCommMask(m_hIDComDev, EV_RXCHAR);
else
SetCommMask(m_hIDComDev, 0);
}
void CSerial::SetComPort(int port)
{
ComPort = port;
}
int CSerial::GetComPort(void)
{
return ComPort;
}
void CSerial::SetCommBaudRate(int speed)
{
BaudRate = speed;
}
void CSerial::SetRTSEnable(BOOL enb)
{
if(!m_bOpened) return;
if(enb)
EscapeCommFunction(m_hIDComDev, SETRTS);
else
EscapeCommFunction(m_hIDComDev, CLRRTS);
}
void CSerial::SetBuffCount(long inbufnum, long outbufnum)
{
if(m_bOpened)
SetupComm(m_hIDComDev, inbufnum, outbufnum);
}
BOOL CSerial::GetCDHolding()
{
DWORD ModemStat;
if(!m_bOpened) return FALSE;
GetCommModemStatus(m_hIDComDev, &ModemStat);
DWORD i = ModemStat&MS_RING_ON;
if((ModemStat|MS_RING_ON) == 0x00f0)
return TRUE;
else
return FALSE;
}
void CSerial::ClearInBuffer()
{
if(!m_bOpened) return;
PurgeComm(m_hIDComDev, PURGE_RXCLEAR);
}
void CSerial::StopReadBuf()
{
if(!m_bOpened) return;
PurgeComm(m_hIDComDev, PURGE_RXABORT);
}
BOOL CSerial::WaitReadEvent(BOOL Isover)
{
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -