目前位置: VCer资源中心 >>> VCer代码 >>> 硬件/系统调用

[本帖已阅读2546次 分值100 回复1次] 张贴资源 发回信箱 控制面板

异步读写的简单串口类

提供者:bruticus 张贴时间:2004-04-19 12:51:38.0 出处:http://www.vchelp.net/ 作者:不祥

异步读写的简单串口类(2004-04-19 12:51:38.0)


混天豹


 
级别: VCer小兵
头衔: VCer会员

经验: 84
作品: 1
分会: 华北分会
注册: 2004-04-19 12:41:41.0
登录: 2004-04-22 14:52:38.0

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

}

注:转载文章需注明来源:VCer.net 文章地址:http://vcer.net/1076417661345.html

  如果你觉得VCer.net不错,而且你愿意为VCer.net捐赠一元钱,那么点击后面的捐赠按钮吧:) vcer.net捐赠

[回复该贴] [加入个人书签]
[投票结果]

A: 评分 10 66% (2 票)
B: 评分 5 0% (0 票)
C: 评分 0 33% (1 票)
D: 评分 -5 0% (0 票)
E: 评分 -10 0% (0 票)

 


re:异步读写的简单串口类
因为没有一点comment,所以我只能给你投c了。 其实这个类还是很不错的

kalven 于 2004-04-20 11:42:46.0 编辑 [回复该贴]