📄 cserial.cpp
字号:
#include "CSerial.h"
CSerial::CSerial(void){
m_bOpened = false;
}
CSerial::~CSerial(void){
}
BOOL CSerial::Open(int nPort,int nBaud )
{
if( m_bOpened ) return( TRUE );
char szPort[15];
DCB dcb;
wsprintf( szPort, "COM%d", nPort );
m_hComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
//CreateFile用指定的方式打开指定的串口
//m_hCom为文件句柄。
//GENERIC_READ | GENERIC_WRITE指定可以对串口进行读写操作。
//参数0表示串口为独占打开。
//OPEN_EXISTING当指定串口不存在时,返回失败。
//FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED表示文件属性。
//打开串口时,须指定 FILE_FLAG_OVERLAPPED,表示文件或设备不会维护访问指针,
//在读写时,须使用OVERLAPPED 结构指定访问的文件偏移量。
if( m_hComDev == NULL ) return( FALSE );
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
//COMMTIMEOUTS:串口超时参数设置
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
//ReadIntervalTimeout:两字符之间最大的延时,当读取串口数据时,
//一旦两个字符传输的时间差超过该时间,读取函数将返回现有的数据。
//设置为0表示该参数不起作用。
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;//读取每字符间的超时。
CommTimeOuts.ReadTotalTimeoutConstant = 0;//一次读取串口数据的固定超时。
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;//写入每字符间的超时。
CommTimeOuts.WriteTotalTimeoutConstant = 5000;//一次写入串口数据的固定超时。
SetCommTimeouts( m_hComDev, &CommTimeOuts );
//SetCommTimeouts函数设置某设备句柄的超时参数,要得到某设备句柄的超时参数可以用GetCommTimeouts函数
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
//DCB:串口参数设置
dcb.DCBlength = sizeof( DCB );
GetCommState( m_hComDev, &dcb );
dcb.BaudRate = nBaud;//串口的通讯速度。如为9600
dcb.ByteSize = 8;//字节位数
if( !SetCommState( m_hComDev, &dcb ) ||
!SetupComm( m_hComDev, 10000, 10000 ) ||//设置串口输入、输出缓冲区
m_OverlappedRead.hEvent == NULL ||
m_OverlappedWrite.hEvent == NULL ){
DWORD dwError = GetLastError();
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hComDev );
return FALSE;
}
m_bOpened = TRUE;
return m_bOpened;
}
int CSerial::InBufferCount( void )
{
if( !m_bOpened || m_hComDev == NULL ) return( 0 );
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
return (int)ComStat.cbInQue;
}
DWORD CSerial::ReadData( void *buffer, DWORD dwBytesRead)
{
if( !m_bOpened || m_hComDev == NULL ) return 0;
BOOL bReadStatus;
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hComDev, &dwErrorFlags, &ComStat );
if( !ComStat.cbInQue ) return 0;
dwBytesRead = min(dwBytesRead,(DWORD) ComStat.cbInQue);
//ReadFile:读取串口数据
bReadStatus = ReadFile( m_hComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
if( !bReadStatus ){
if( GetLastError() == ERROR_IO_PENDING ){
WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
return dwBytesRead;
}
return 0;
}
return dwBytesRead;
}
DWORD CSerial::SendData( const char *buffer, DWORD dwBytesWritten)
{
if( !m_bOpened || m_hComDev == NULL ) return( 0 );
BOOL bWriteStat;
//WriteFile:向串口写数据
bWriteStat = WriteFile( m_hComDev, buffer, dwBytesWritten, &dwBytesWritten, &m_OverlappedWrite );
if( !bWriteStat){
if ( GetLastError() == ERROR_IO_PENDING ) {
WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 );
return dwBytesWritten;
}
return 0;
}
return dwBytesWritten;
}
//CloseHandle:关闭串口
void CSerial::Close(){
if(m_hComDev!=NULL){
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hComDev );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -