// Serial.h: interface for the CSerial class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_SERIAL_H__33AC291A_EF86_4555_A021_4EAF73986F60__INCLUDED_) #define AFX_SERIAL_H__33AC291A_EF86_4555_A021_4EAF73986F60__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#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 #define MAX_FRAMGAPE 10 // 祯间隔时间
class CSerial {
public: CSerial(); virtual ~CSerial(); BOOL Open( int nPort, int nBaud, int nDataBit, int nStopBit, int nParity ); BOOL Close( void ); int ReadData(unsigned char *, int ); int SendData( BYTE *, int ); int ReadDataInLen( void ); BOOL IsOpened( void ){ return( m_bOpened ); } protected: BOOL WriteCommByte( unsigned char ); HANDLE m_hIDComDev; OVERLAPPED m_OverlappedRead, m_OverlappedWrite; BOOL m_bOpened;
DWORD dwErrorFlags; COMSTAT ComStat; };
extern CSerial * pCom; #endif // !defined(AFX_SERIAL_H__33AC291A_EF86_4555_A021_4EAF73986F60__INCLUDED_)
// Serial.cpp: implementation of the CSerial class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "Serial.h"
#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif
CSerial * pCom = NULL ;
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
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 ComId, int nBaud,int nDataBit,int nStopBit,int nParity ) {
if( m_bOpened ) return( TRUE );
char szPort[15]; char szComParams[50]; DCB dcb; wsprintf( szPort, "COM%d", ComId ); 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 = 1000; CommTimeOuts.ReadTotalTimeoutMultiplier = 500; CommTimeOuts.ReadTotalTimeoutConstant = 5000; CommTimeOuts.WriteTotalTimeoutMultiplier = 500; CommTimeOuts.WriteTotalTimeoutConstant = 5000; SetCommTimeouts( m_hIDComDev, &CommTimeOuts );
wsprintf( szComParams, "COM%d:%d,%d,%d,%d", ComId, nBaud,nDataBit,nStopBit,nParity ); TRACE(szComParams); 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 = nDataBit; dcb.StopBits=nStopBit;
dcb.Parity=nParity; BOOL b1,b2; b1=SetCommState( m_hIDComDev, &dcb ); DWORD dwError = GetLastError(); b2=SetupComm( m_hIDComDev, 10000, 10000 );
if(!b1 || ! b2|| m_OverlappedRead.hEvent == NULL || m_OverlappedWrite.hEvent == NULL ) { 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( BYTE *buffer, int size ) {
if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
DWORD dwBytesWritten = 0; ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat ); if( ComStat.cbOutQue> 0) { PurgeComm(m_hIDComDev,PURGE_TXABORT| PURGE_TXCLEAR); Sleep(100); } WriteFile( m_hIDComDev, (LPSTR) buffer, size, &dwBytesWritten, &m_OverlappedWrite ); dwBytesWritten=size; return( (int) dwBytesWritten ); }
int CSerial::ReadDataInLen( void ) {
if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
return( (int) ComStat.cbInQue );
}
int CSerial::ReadData(unsigned char *buffer, int limit ) { if( !m_bOpened || m_hIDComDev == NULL ) return( 0 ); DWORD dwBytesRead=0, dwErrorFlags; ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat ); if( !ComStat.cbInQue ) return( 0 ); limit=ComStat.cbInQue;//取得缓冲区的数据长度,以便读入 ReadFile( m_hIDComDev, buffer,limit , &dwBytesRead, &m_OverlappedRead ); return( (int) dwBytesRead ); } |