CSerial 串口通信类

CSerial是一个C++类,用于实现串口通信。它包括打开、关闭串口,设置波特率、停止位等功能,并提供了读写数据的方法。通过CreateFile创建串口设备,然后配置DCB结构体以设定通信参数,使用WriteFile和ReadFile进行数据传输。

 

#include "serial.h"

CSerial::CSerial()
{
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
m_hIDComDev = NULL;
m_bOpened = false;
}

CSerial::~CSerial()
{
Close();

}

BOOL CSerial::Open( int nPort, int nBaud,BYTE stopbit)
{

if(m_bOpened)
 return( true );

char szPort[15];
char szComParams[50];
DCB dcb;
wsprintf( szPort, "COM%d", nPort );
m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
if( m_hIDComDev == NULL )
return( false );
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );

COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 5000;
SetCommTimeouts( m_hIDComDev, &CommTimeOuts );

wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud );

m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

dcb.DCBlength = sizeof( DCB );
GetCommState( m_hIDComDev, &dcb );
 dcb.fParity=NOPARITY;
dcb.BaudRate = nBaud;
dcb.ByteSize = 8;
dcb.StopBits=stopbit;
dcb.fOutxCtsFlow=FALSE;
dcb.fOutxDsrFlow=FALSE;
dcb.fDtrControl=DTR_CONTROL_DISABLE;
dcb.fRtsControl=RTS_CONTROL_DISABLE;
//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 );

if( !SetCommState( m_hIDComDev, &dcb ) ||
!SetupComm( m_hIDComDev, 512, 512) ||
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_hIDComDev );
return(false );
}

m_bOpened = TRUE;

return( m_bOpened );

}

BOOL CSerial::Close( )
{

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( unsigned char *buffer, int size )
{

if( !m_bOpened || m_hIDComDev == NULL )
return( 0 );

DWORD dwBytesWritten = 0;
int i;
for( i=0;i<size;  i++   )
{
WriteCommByte( buffer[i] );
dwBytesWritten++;
}
return( (int) dwBytesWritten );

}

void CSerial::ReadDataWaiting( void )
{
/*
if( !m_bOpened || m_hIDComDev == NULL )
{
 return( 0 );
}

DWORD dwErrorFlags;
COMSTAT ComStat;

ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );

return( (int) ComStat.cbInQue );
*/

 PurgeComm(m_hIDComDev,PURGE_RXABORT|PURGE_RXCLEAR);
}

int CSerial::ReadData( void *buffer,int limit )
{
 

 
if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
BOOL bReadStatus;
DWORD dwBytesRead, dwErrorFlags;
COMSTAT ComStat;


ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
//PurgeComm(m_hIDComDev,PURGE_RXABORT|PURGE_RXCLEAR);
// CString str;
// str.Format("%d",ComStat.cbInQue);
if( !ComStat.cbInQue ) return( 0 );
/*CString str;
str.Format("%d",ComStat.cbInQue);
AfxMessageBox(str);
*/
  dwBytesRead = (DWORD) ComStat.cbInQue;
if (dwBytesRead<limit)
{
 return 0;
}

if( limit < (int) dwBytesRead )
 dwBytesRead = (DWORD) limit;

bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
PurgeComm(m_hIDComDev,PURGE_RXABORT|PURGE_RXCLEAR);

if( !bReadStatus )
{
 if( GetLastError() == ERROR_IO_PENDING )
 { 
  WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
  return( (int) dwBytesRead );
 }
 return( 0 );
}
if (dwBytesRead==limit)
{
 return limit;
}
else
{
 return 0;
}
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值