非同步讀寫的簡單串口類

來源:互聯網
上載者:User
 

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

}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.