CSerial.h
// 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
// #define COMMTIMERUP 5000
class CSerial
{
public:
CSerial();
virtual ~CSerial();
BOOL Open( int nPort, int nBaud);
BOOL PortClose (void);
BOOL Send(unsigned char *buff,int len);
BOOL Revice(unsigned char *buff,int maxlen,int &len);
void ClearBuff();
BOOL m_bOpened;
BOOL porterror;
HANDLE m_hIDComDev;
DWORD dwError;
DWORD dwThreadID;
};
extern CSerial mySerial;
CSerial.cpp
// Serial.cpp: implementation of the CSerial class.
//
//
#include "stdafx.h"
#include "resource.h"
#include "CSerial.h"
//
// Construction/Destruction
//
CSerial::CSerial()
{
m_hIDComDev = NULL;
m_bOpened = FALSE;
porterror =FALSE;
}
CSerial::~CSerial()
{
PortClose ();
}
BOOL CSerial::Open( int nPort, int nBaud )
{
if( m_bOpened ) return( TRUE );
char szPort[15];
DCB dcb;
sprintf( szPort, _T("COM%d:"), nPort );
m_hIDComDev = CreateFile( szPort,//指向端口名的Pointer
GENERIC_READ | GENERIC_WRITE,//允许读和写
0,//独占方式(共享模式)
NULL, //NULL为缺省安全属性
OPEN_EXISTING,//打开而不是创建(创建方式)
0,//FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,//重叠方式(文件属性和标志)
NULL
);
if( m_hIDComDev == INVALID_HANDLE_VALUE)
{
DWORD dwError=GetLastError();
::MessageBox(0,_T("打开端口出错!请确定端口设备的使用情况后关闭重试."),_T("ERROR!"),MB_OK );
porterror=TRUE;
return( FALSE );
}
else
{
// ::MessageBox(0,_T("打开端口正确!"),_T("RIGHT!"),MB_OK );
porterror=FALSE;
m_bOpened = TRUE;
}
/*
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
*/
//
// Change the CommTimeOuts structure settings.
COMMTIMEOUTS CommTimeOuts;
GetCommTimeouts (szPort, &CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout =MAXWORD; // not use
CommTimeOuts.ReadTotalTimeoutMultiplier = 5; // 5*byte
CommTimeOuts.ReadTotalTimeoutConstant = 10000; //5s
CommTimeOuts.WriteTotalTimeoutMultiplier = 1; //5*byte
CommTimeOuts.WriteTotalTimeoutConstant = 1; //5s
if(!SetCommTimeouts( m_hIDComDev, &CommTimeOuts ))
{
//could not creatthe read thread;
::MessageBox (NULL,_T("不能设置延时参数"),_T("ERROR"),MB_OK);
DWORD dwError=GetLastError();
return FALSE;
}
/* else
{
::MessageBox (NULL,_T("延时参数设置正确"),_T("RIGHT"),MB_OK);
}
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.fBinary = TRUE; // Binary mode; no EOF check
dcb.fParity = FALSE; // Enable parity checking
dcb.fOutxCtsFlow = FALSE; // No CTS output flow control ***keiy**
dcb.fOutxDsrFlow = FALSE; // No DSR output flow control ****keiy*
dcb.fDtrControl = DTR_CONTROL_ENABLE;
// DTR flow control type
dcb.fDsrSensitivity = FALSE; // DSR sensitivity
dcb.fTXContinueOnXoff = FALSE; // XOFF continues Tx
dcb.fOutX = FALSE; // No XON/XOFF out flow control
dcb.fInX = FALSE; // No XON/XOFF in flow control
dcb.fErrorChar = FALSE; // Disable error replacement
dcb.fNull = FALSE; // Disable null stripping
dcb.fRtsControl = RTS_CONTROL_ENABLE;
// RTS flow control
dcb.fAbortOnError = FALSE; // Do not abort reads/writes on
// error
dcb.ByteSize = 8; // Number of bits/byte, 4-8
dcb.Parity = 0; // 0-4=no,odd,even,mark,space
dcb.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
/* 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, 1024, 1024 )/*||
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 );
//::MessageBox(0,_T("初始化端口不正确!"),_T("ERROR!"),MB_OK );
return( FALSE );
}
else
{//::MessageBox (NULL,_T("初始化正确,欢迎使用终端测试仪!"),_T("RIGHT"),MB_OK);
}
m_bOpened = TRUE;
return( m_bOpened );
}
//======================
BOOL CSerial::PortClose (void)
{
if (m_bOpened){
// Close the communication port.
if (!CloseHandle (m_hIDComDev))
{
DWORD dwError = GetLastError ();
::MessageBox (NULL,_T("关闭端口错误"),_T("ERROR"),MB_OK);
}
else {
// ::MessageBox (NULL,_T("正常退出,谢谢使用!"),_T("RIGHT"),MB_OK);
m_bOpened=FALSE;
}
}
else{return(FALSE); }
return( TRUE );
}
BOOL CSerial::Send(unsigned char *buff,int len)
{
DWORD wd=0;
if (m_bOpened)
return WriteFile(m_hIDComDev,buff,len,&wd,NULL);
else
return false;
}
//BOOL timeup=FALSE;
//void TimerUp()
//{
// timeup=TRUE;
//}
BOOL CSerial::Revice(unsigned char *buff,int maxlen,int &len)
{
// DWORD ev,rv;
// int mytimerid;
// 清空接收
buff[len=0]='\x0';
if ((!m_bOpened) || maxlen==0)
return false;
// 设定超时
// mytimerid=SetTimer(NULL,1,COMMTIMERUP,(TIMERPROC)TimerUp);
// timeup=FALSE;
// 指定监视的端口事件
//..// SetCommMask (m_hIDComDev, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD );
// while (!timeup) // 总时间 5S
// {
// 等待端口事件
//..// WaitCommEvent (m_hIDComDev, &ev, 0);
// 重新指定监视的端口事件
//..// SetCommMask (m_hIDComDev, EV_RXCHAR | EV_CTS | EV_DSR );
//..// if (ev & EV_RXCHAR)
// {
ReadFile (m_hIDComDev,buff, maxlen, (DWORD *)&len, 0);
if (len!=0)
{
// KillTimer(NULL,mytimerid);
//len=rv;
buff[len]=0;
return true;
}
// }
// 等。。。
// MSG msg;
// if(PeekMessage((LPMSG)&msg,(HWND)NULL,(WORD)NULL,(WORD)NULL,TRUE))
// {
// TranslateMessage((LPMSG)&msg);
// DispatchMessage((LPMSG)&msg);
// }
// }
// buff[len]='\x0';
// KillTimer(NULL,mytimerid);
return false;
}
void CSerial::ClearBuff()
{
PurgeComm(m_hIDComDev,PURGE_RXCLEAR);
}
CSerial mySerial;