异步读写的简单串口类

 

// Serial.h

#ifndef __SERIAL_H__

#define __SERIAL_H__

#define FC_DTRDSR       0x01

#define FC_RTSCTS       0x02

#define FC_XONXOFF      0x04

#define ASCII_BEL       0x07

#define ASCII_BS        0x08

#define ASCII_LF        0x0A

#define ASCII_CR        0x0D

#define ASCII_XON       0x11

#define ASCII_XOFF      0x13

class CSerial

{

public:

 CSerial();

 ~CSerial();

 BOOL Open( int nPort = 2, int nBaud = 9600 );

 BOOL Close( void );

 int ReadData( void *, int );

 int SendData( const char *, int );

 int ReadDataWaiting( void );

 BOOL IsOpened( void ){ return( m_bOpened ); }

protected:

 BOOL WriteCommByte( unsigned char );

 HANDLE m_hIDComDev;

 OVERLAPPED m_OverlappedRead, m_OverlappedWrite;

 BOOL m_bOpened;

};

#endif

// Serial.cpp

#include "stdafx.h"

#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 )

{

 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, OPEN_EXISTING, 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.BaudRate = nBaud;

 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 );

 if( !SetCommState( m_hIDComDev, &dcb ) ||

  !SetupComm( m_hIDComDev, 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_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, 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 );

}

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( void *buffer, int limit )

{

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

 BOOL bReadStatus;

 DWORD dwBytesRead, dwErrorFlags;

 COMSTAT ComStat;

 ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );

 if( !ComStat.cbInQue ) return( 0 );

 dwBytesRead = (DWORD) ComStat.cbInQue;

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

 bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );

 if( !bReadStatus ){

  if( GetLastError() == ERROR_IO_PENDING ){

   WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );

   return( (int) dwBytesRead );

   }

  return( 0 );

  }

 return( (int) dwBytesRead );

}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值