📄 scomm.cpp
字号:
// Serial.cpp: implementation of the CSerial class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SCOMM.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
extern BYTE ucStandardCAN;
extern CString szIniFileName;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSerial::CSerial()
{
m_bOpened=FALSE;
m_hComDev=INVALID_HANDLE_VALUE;
// m_pcView=NULL;
m_bShow=TRUE;
m_bGoAhead=FALSE;
m_bUseOverlapped=FALSE;
m_bShowData=TRUE;
iAuto=0;
}
CSerial::~CSerial()
{
if(m_hComDev!=INVALID_HANDLE_VALUE)
{
CloseHandle(m_hComDev);
m_hComDev=INVALID_HANDLE_VALUE;
}
// if(m_pcView!=NULL)
// {
// free (m_pcView);
// m_pcView=NULL;
// }
// if(m_pData!=NULL)
// {
// free(m_pData);
// m_pData=NULL;
// }
}
BOOL CSerial::Open(int nPort)
{
// if( m_bOpened ) return( TRUE );
int status=true;
char szPort[15];
wsprintf(szPort, "COM%d", nPort );
if(m_bUseOverlapped)
{
m_hComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL );
if( m_hComDev == INVALID_HANDLE_VALUE ) return( FALSE );
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
memset(&m_OverlappedStatus,0,sizeof(OVERLAPPED));
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if(m_OverlappedRead.hEvent==NULL) return FALSE;
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if(m_OverlappedWrite.hEvent==NULL) return FALSE;
m_OverlappedStatus.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(m_OverlappedStatus.hEvent==NULL) return FALSE;
}
else
{
m_hComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL, NULL );
}
if((m_hComDev == (unsigned int *)NULL) || (m_hComDev == (unsigned int *)0xffffffff))
{
status = 0;
}
else
{
GetDefaultTimeOuts();
SetCommTimeouts(m_hComDev,&m_CommTimeOuts);
GetCommState(m_hComDev,&m_dcb);
m_dcb.XoffChar=NULL;
GetDefaultDcb();
SetCommState(m_hComDev,&m_dcb);
//The SetCommState function fails if the XonChar member of the DCB structure is equal to the XoffChar member.
//char b=m_dcb.XonChar;
//BOOL bFlag=
SetupComm( m_hComDev, 1024, 1024 );
SetCommMask(m_hComDev,EV_RXCHAR|EV_TXEMPTY);
//DWORD dwError = GetLastError();
//Windows 95 and Windows 98: Because SetLastError is a 32-bit function only, Win32 functions that are actually implemented in 16-bit code do not set the last-error code. You should ignore the last-error code when you call these functions. They include window management functions, GDI functions, and Multimedia functions
// if(/* !SetCommState(m_hComDev,&m_dcb)||!SetupComm( m_hComDev, 1024, 1024 ) ||*/
/* m_OverlappedRead.hEvent == NULL ||//!SetCommMask(m_hComDev,EV_RXCHAR)|| //add 2004.2.6
m_OverlappedWrite.hEvent == NULL )
{
//DWORD dwError = GetLastError();
if( m_OverlappedRead.hEvent != NULL )
{
CloseHandle( m_OverlappedRead.hEvent );
m_OverlappedRead.hEvent = NULL;
}
if( m_OverlappedWrite.hEvent != NULL )
{
CloseHandle( m_OverlappedWrite.hEvent );
m_OverlappedWrite.hEvent = NULL;
}
*/
// CloseHandle( m_hComDev );
// m_hComDev=NULL;
// return FALSE;
// }
//if(!SetDefaultDcb()) return FALSE;
m_bOpened = TRUE;
status = 1;
}
// return m_bOpened;
return status;
}
DWORD CSerial::ReadData( unsigned char *buffer, DWORD dwBytesToRead)
{
if( !m_bOpened || m_hComDev == INVALID_HANDLE_VALUE ) return 0;
BOOL bReadStatus;
DWORD dwErrorFlags;
DWORD dwEventFlags;
DWORD dwBytesRead;
// DWORD dwEventMask;
COMSTAT ComStat;
// WaitCommEvent(m_hComDev,&dwEventMask,&m_OverlappedStatus);
ClearCommError( m_hComDev, &dwErrorFlags, &ComStat );
//if(dwErrorFlags) ::AfxMessageBox("Read Datas Error!");
if( !ComStat.cbInQue ) return 0;
if(m_bUseOverlapped)
{
bReadStatus = ReadFile( m_hComDev, buffer, dwBytesToRead, &dwBytesRead, &m_OverlappedRead );
if( !bReadStatus )
{
if(GetLastError() == ERROR_IO_PENDING )//ERROR_IO_INCOMPLETE
{
dwEventFlags=WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
if(dwEventFlags==WAIT_OBJECT_0||dwEventFlags==WAIT_TIMEOUT)
{
GetOverlappedResult(m_hComDev,&m_OverlappedRead,&dwBytesRead,FALSE);
return dwBytesRead;
}
return 0;
}
return 0;
}
}
else
{
bReadStatus = ReadFile( m_hComDev, buffer, dwBytesToRead, &dwBytesRead, NULL );
if(!bReadStatus) return 0;
}
return dwBytesRead;
//PurgeComm(m_hComDev,PURGE_TXCLEAR | PURGE_RXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
//ClearCommError( m_hComDev, &dwErrorFlags, &ComStat );
}
DWORD CSerial::ReadData( unsigned char *buffer, DWORD dwBytesToRead,DWORD *dwBytesRealRead)
{
if( !m_bOpened || m_hComDev == INVALID_HANDLE_VALUE ) return 0;
BOOL bReadStatus;
DWORD dwErrorFlags;
DWORD dwEventFlags;
//DWORD dwBytesRead;
// DWORD dwEventMask;
COMSTAT ComStat;
// WaitCommEvent(m_hComDev,&dwEventMask,&m_OverlappedStatus);
*dwBytesRealRead = 0;
ClearCommError( m_hComDev, &dwErrorFlags, &ComStat );
//if(dwErrorFlags) ::AfxMessageBox("Read Datas Error!");
if( !ComStat.cbInQue ) return 0;
if(m_bUseOverlapped)
{
bReadStatus = ReadFile( m_hComDev, buffer, dwBytesToRead, dwBytesRealRead, &m_OverlappedRead );
if( !bReadStatus )
{
if(GetLastError() == ERROR_IO_PENDING )//ERROR_IO_INCOMPLETE
{
dwEventFlags=WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
if(dwEventFlags==WAIT_OBJECT_0||dwEventFlags==WAIT_TIMEOUT)
{
GetOverlappedResult(m_hComDev,&m_OverlappedRead,dwBytesRealRead,FALSE);
return *dwBytesRealRead;
}
return 0;
}
return 0;
}
}
else
{
bReadStatus = ReadFile( m_hComDev, buffer, dwBytesToRead, dwBytesRealRead, NULL );
if(!bReadStatus) return 0;
}
//*dwBytesRealRead = dwBytesRead;
return *dwBytesRealRead;
//PurgeComm(m_hComDev,PURGE_TXCLEAR | PURGE_RXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
//ClearCommError( m_hComDev, &dwErrorFlags, &ComStat );
}
DWORD CSerial::SendData( unsigned char *buffer, DWORD dwBytesToWritte)
{
if( !m_bOpened || m_hComDev == INVALID_HANDLE_VALUE ) return( 0 );
BOOL bWriteStat;
DWORD dwBytesWritten;
DWORD dwEventFlags;
if(m_bUseOverlapped)
{
bWriteStat = WriteFile( m_hComDev, buffer, dwBytesToWritte, &dwBytesWritten, &m_OverlappedWrite );
if( !bWriteStat)
{
if ( GetLastError() == ERROR_IO_PENDING )
{
dwEventFlags=WaitForSingleObject( m_OverlappedWrite.hEvent, 2000 );
if(dwEventFlags==WAIT_OBJECT_0||dwEventFlags==WAIT_TIMEOUT)
{
GetOverlappedResult(m_hComDev,&m_OverlappedWrite,&dwBytesWritten,FALSE);
return dwBytesWritten;
}
return 0;
}
return 0;
}
}
else
{
bWriteStat =WriteFile( m_hComDev, buffer, dwBytesToWritte, &dwBytesWritten, NULL );
}
return dwBytesWritten;
}
int CSerial::GetBufferCount()
{
if( !m_bOpened || m_hComDev == INVALID_HANDLE_VALUE ) return( 0 );
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hComDev, &dwErrorFlags, &ComStat );
return (int)ComStat.cbInQue;
}
COMMTIMEOUTS CSerial::GetTimeOuts()
{
COMMTIMEOUTS timeouts;
if(m_hComDev!=INVALID_HANDLE_VALUE)
{
GetCommTimeouts(m_hComDev,&timeouts);
return timeouts;
}
return m_CommTimeOuts;
}
DCB CSerial::GetDcb()
{
DCB dcb;
if(m_hComDev!=INVALID_HANDLE_VALUE)
{
GetCommState(m_hComDev,&dcb);
return dcb;
}
return m_dcb;
}
BOOL CSerial::SetDefaultDcb()
{
char buffer[80];
// char buffer[80];
_ultoa(m_dcb.DCBlength,buffer,10);
WritePrivateProfileString("DCB","length",buffer,szIniFileName);
_ultoa(m_dcb.BaudRate,buffer,10);
WritePrivateProfileString("DCB","baud rate",buffer,szIniFileName);
_ultoa((DWORD)m_dcb.ByteSize,buffer,10);
WritePrivateProfileString("DCB","byte size",buffer,szIniFileName);
_ultoa((DWORD)m_dcb.StopBits,buffer,10);
WritePrivateProfileString("DCB","stop bits",buffer,szIniFileName);
_ultoa((DWORD)m_dcb.Parity,buffer,10);
WritePrivateProfileString("DCB","parity",buffer,szIniFileName);
return TRUE;
}
BOOL CSerial::SetDefaultTimeOuts()
{
char buffer[80];
// char buffer[80];
_ultoa(m_CommTimeOuts.ReadIntervalTimeout,buffer,10);
WritePrivateProfileString("CommTimeOuts","ReadIntervalTimeout",buffer,szIniFileName);
_ultoa(m_CommTimeOuts.ReadTotalTimeoutConstant,buffer,10);
WritePrivateProfileString("CommTimeOuts","ReadTotalTimeoutConstant",buffer,szIniFileName);
_ultoa(m_CommTimeOuts.ReadTotalTimeoutMultiplier,buffer,10);
WritePrivateProfileString("CommTimeOuts","ReadTotalTimeoutMultiplier",buffer,szIniFileName);
_ultoa(m_CommTimeOuts.WriteTotalTimeoutConstant,buffer,10);
WritePrivateProfileString("CommTimeOuts","WriteTotalTimeoutConstant",buffer,szIniFileName);
_ultoa(m_CommTimeOuts.WriteTotalTimeoutMultiplier,buffer,10);
WritePrivateProfileString("CommTimeOuts","WriteTotalTimeoutMultiplier",buffer,szIniFileName);
/* m_CommTimeOuts.ReadIntervalTimeout=MAXDWORD;
m_CommTimeOuts.ReadTotalTimeoutConstant =40;
m_CommTimeOuts.ReadTotalTimeoutMultiplier=11*1000/m_dcb.BaudRate+1;
m_CommTimeOuts.WriteTotalTimeoutConstant =40;
m_CommTimeOuts.WriteTotalTimeoutMultiplier =11*1000/m_dcb.BaudRate+1;
if(m_hComDev!=NULL) SetCommTimeouts(m_hComDev,&m_CommTimeOuts);
//if(!SetCommTimeouts(m_hComDev,&m_CommTimeOuts)) return FALSE;
//Because Win95 & Win98
*/
return TRUE;
}
BOOL CSerial::SetDcb(const DCB dcb)
{
m_dcb.BaudRate=dcb.BaudRate;
m_dcb.ByteSize=dcb.ByteSize;
m_dcb.StopBits=dcb.StopBits;
m_dcb.Parity=dcb.Parity;
if(m_hComDev!=INVALID_HANDLE_VALUE) SetCommState( m_hComDev, &m_dcb );
//Windows 95 and Windows 98: Because SetLastError is a 32-bit function only, Win32 functions that are actually implemented in 16-bit code do not set the last-error code. You should ignore the last-error code when you call these functions. They include window management functions, GDI functions, and Multimedia functions
//if(!SetCommState( m_hComDev, &m_dcb )) return FALSE;
return TRUE;
}
BOOL CSerial::SetTimeOuts(const COMMTIMEOUTS timeouts)
{
m_CommTimeOuts.ReadIntervalTimeout=timeouts.ReadIntervalTimeout;
m_CommTimeOuts.ReadTotalTimeoutConstant=timeouts.ReadTotalTimeoutConstant;
m_CommTimeOuts.ReadTotalTimeoutMultiplier=timeouts.ReadTotalTimeoutMultiplier;
m_CommTimeOuts.WriteTotalTimeoutConstant=timeouts.WriteTotalTimeoutConstant;
m_CommTimeOuts.WriteTotalTimeoutMultiplier=timeouts.WriteTotalTimeoutMultiplier;
if(m_hComDev!=INVALID_HANDLE_VALUE) SetCommTimeouts( m_hComDev, &m_CommTimeOuts );
//if(!SetCommTimeouts( m_hComDev, &m_CommTimeOuts )) return FALSE;
//Because Win95 & Win98
return TRUE;
}
BOOL CSerial::Close()
{
//Windows 95 and Windows 98: Because SetLastError is a 32-bit function only, Win32 functions that are actually implemented in 16-bit code do not set the last-error code. You should ignore the last-error code when you call these functions. They include window management functions, GDI functions, and Multimedia functions
BOOL bTemp=FALSE;
if( !m_bOpened || m_hComDev == INVALID_HANDLE_VALUE ) return( TRUE );
PurgeComm(m_hComDev,PURGE_TXCLEAR | PURGE_RXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
// SetCommMask(m_hComDev,NULL);
if(m_bUseOverlapped)
{
bTemp=SetEvent(m_OverlappedWrite.hEvent);
bTemp=SetEvent(m_OverlappedStatus.hEvent);
bTemp=SetEvent(m_OverlappedRead.hEvent);
}
SetCommMask(m_hComDev,NULL);
// Sleep(200);
bTemp=CloseHandle( m_hComDev );
if(m_bUseOverlapped)
{
if( m_OverlappedRead.hEvent != NULL )
{
bTemp=CloseHandle( m_OverlappedRead.hEvent );
m_OverlappedRead.hEvent=NULL;
}
if( m_OverlappedWrite.hEvent != NULL )
{
bTemp=CloseHandle( m_OverlappedWrite.hEvent );
m_OverlappedWrite.hEvent=NULL;
}
if( m_OverlappedStatus.hEvent != NULL )
{
bTemp=CloseHandle( m_OverlappedStatus.hEvent );
m_OverlappedStatus.hEvent=NULL;
}
}
m_bOpened = FALSE;
m_hComDev = INVALID_HANDLE_VALUE;
return( TRUE );
}
BOOL CSerial::IsOpen()
{
return m_bOpened;
}
BOOL CSerial::IsDataCome()
{
DWORD dwEventMask;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -