⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win32port.cpp

📁 磁卡读写器编程
💻 CPP
字号:
/*********************************************************************
 *   Designed by xiaohuiyang 2002.03.15    E-mail: yxh2001@21cn.com  * 
 *********************************************************************/
// Serial.cpp

#include "stdafx.h"
#include "Win32Port.h"


CWin32Port::CWin32Port()
{

	memset(&m_OverlappedRead, 0, sizeof(OVERLAPPED));
 	memset(&m_OverlappedWrite, 0, sizeof(OVERLAPPED));
	m_hIDComDev = NULL;
	mbOpened = 0;

}

CWin32Port::~CWin32Port()
{

	AsynClose();

}

void CWin32Port::SetupParam(int port, int BaudRate, char Parity, char ByteSize, char StopBits)
{
	nPort = port;
	mBaudRate=BaudRate;
	mParity=Parity;
	mStopBits = StopBits;
	mByteSize = ByteSize;
}

BOOL CWin32Port::AsynOpen()
{

	if(mbOpened) return(TRUE);

	char szPort[15];
	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));

	dcb.DCBlength = sizeof(DCB);
	GetCommState(m_hIDComDev, &dcb);

    if(mBaudRate == 300)
        dcb.BaudRate = CBR_300;
    else if(mBaudRate == 600)
        dcb.BaudRate = CBR_600;
    else if(mBaudRate == 1200)
        dcb.BaudRate = CBR_1200;
    else if(mBaudRate == 2400)
        dcb.BaudRate = CBR_2400;
    else if(mBaudRate == 4800)
        dcb.BaudRate = CBR_4800;
    else if(mBaudRate == 19200)
        dcb.BaudRate = CBR_19200;
    else if(mBaudRate == 38400)
        dcb.BaudRate = CBR_38400;
    else if(mBaudRate == 56000)
        dcb.BaudRate = CBR_56000;
    else if(mBaudRate == 57600)
        dcb.BaudRate = CBR_57600;
    else if(mBaudRate == 115200)
        dcb.BaudRate = CBR_115200;
    else
        dcb.BaudRate = CBR_9600;
    
    //奇偶校验设置
    if(mParity == 'O')//奇校验
        dcb.Parity = ODDPARITY;
    else if(mParity == 'E')//偶校验
        dcb.Parity = EVENPARITY;
    else//无校验
        dcb.Parity = NOPARITY;

    //数据位设置
    if(mByteSize == 7)
        dcb.ByteSize = 7;
    else
        dcb.ByteSize = 8;

    //停止位设置
    if(mStopBits == 2)
        dcb.StopBits = TWOSTOPBITS;
    else
        dcb.StopBits = ONESTOPBIT;

	COMMTIMEOUTS CommTimeOuts;
	CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
	CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
	CommTimeOuts.ReadTotalTimeoutConstant = 0;
	CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
	CommTimeOuts.WriteTotalTimeoutConstant = 5000;
	SetCommTimeouts(m_hIDComDev, &CommTimeOuts);


	m_OverlappedRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	m_OverlappedWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

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

	mbOpened = 1;

	return(TRUE);

}

BOOL CWin32Port::AsynClose(void)
{

	if(!mbOpened || 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);
	mbOpened = 0;
	m_hIDComDev = NULL;

	return(TRUE);

}

BOOL CWin32Port::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);

}

//正确:返回》0的个数
int CWin32Port::AsynSendData(const char *buffer, int size)
{

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

	DWORD dwBytesWritten = 0;
	int i;
	for(i=0; i<size; i++)
	{
		WriteCommByte(buffer[i]);
		dwBytesWritten++;
	}

	return((int) dwBytesWritten);

}

int CWin32Port::AsynGetReadLen(void)
{

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

	DWORD dwErrorFlags;
	COMSTAT ComStat;

	ClearCommError(m_hIDComDev, &dwErrorFlags, &ComStat);

	return((int) ComStat.cbInQue);

}

int CWin32Port::AsynReadData(void *buffer, int limit)
{

	if(!mbOpened || 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);
}

short CWin32Port::AsynReadByLen(short len)
{

	BOOL bReadStatus;
	DWORD dwBytesRead, dwErrorFlags;
	COMSTAT ComStat;

	short i, RcvCurrent=0, RcvBefore=0;


	
	memset(chRcvbuf,'\0', MAXBLOCK);
	nRcvlen = 0;

    ClearCommError(m_hIDComDev, &dwErrorFlags, &ComStat);
	dwBytesRead = (DWORD) ComStat.cbInQue;
	if(dwBytesRead<=0) return(_NO_DATA);

    unsigned long TimeCurr, TimeDelay;
	unsigned char ch[2];
	char *chInBuf;

    TimeCurr = GetTickCount();
    TimeDelay = 1000;

	chInBuf = chRcvbuf;
	RcvBefore = (short) dwBytesRead;

	bReadOK = 0;
	RcvBefore = 0;
	nRcvlen = 0;
	while(1)
	{
		if(GetTickCount()-TimeCurr > TimeDelay)
		{
			AsynClearReadBuffer();
			return _ERR_RCVLEN;
		}
		SleepEx(50,TRUE);

        ClearCommError(m_hIDComDev, &dwErrorFlags, &ComStat);
	    RcvCurrent = (short) ComStat.cbInQue;
		if(RcvCurrent == 0) continue;

		for(i=0;i<RcvCurrent;i++) 
		{
			bReadStatus = ReadFile(m_hIDComDev, ch,1, 
						  &dwBytesRead,&m_OverlappedRead);
			if(!bReadStatus)
			{
				if(GetLastError() == ERROR_IO_PENDING)
				{
					return _ERR_READCOM;
				}
				return _ERR_READCOM2;
			}

			*chInBuf = ch[0];
			nRcvlen++;
			chInBuf++;
		}   // end for
		if(nRcvlen >= len)
		{
			 bReadOK = 1;
			 break;
		}
	}
    *chInBuf = '\0';

    AsynClearReadBuffer();
    return nRcvlen;


}


void CWin32Port::AsynClearReadBuffer()
{
	PurgeComm(m_hIDComDev, PURGE_TXCLEAR);//清除输入缓冲区
}

short CWin32Port::AsynReadByEndChar(unsigned char chEndChar)
{

	BOOL bReadStatus;
	DWORD dwBytesRead, dwErrorFlags;
	COMSTAT ComStat;

	short i, RcvCurrent=0, RcvBefore=0;

	memset(chRcvbuf,'\0', MAXBLOCK);
	nRcvlen = 0;

    ClearCommError(m_hIDComDev, &dwErrorFlags, &ComStat);
	dwBytesRead = (DWORD) ComStat.cbInQue;
	if(!dwBytesRead) return(_NO_DATA);

    unsigned long TimeCurr, TimeDelay;
	unsigned char ch[2];
	char *chInBuf;

    TimeCurr = GetTickCount();
    TimeDelay = 1000;

	chInBuf = chRcvbuf;
	RcvBefore = (short) dwBytesRead;

	bReadOK = 0;
	RcvBefore = 0;
	while(1)
	{
		if(GetTickCount()-TimeCurr > TimeDelay)
		{
			AsynClearReadBuffer();
			return _ERR_ENDCHAR;
		}
		SleepEx(50,TRUE);
        ClearCommError(m_hIDComDev, &dwErrorFlags, &ComStat);
	    RcvCurrent = (short) ComStat.cbInQue;
		if(RcvCurrent == 0) continue;

		for(i=0;i<RcvCurrent;i++) 
		{
			if(GetTickCount()-TimeCurr > TimeDelay)
			{
				AsynClearReadBuffer();
				return _ERR_ENDCHAR;
			}
			bReadStatus = ReadFile(m_hIDComDev, ch,1, 
						  &dwBytesRead,&m_OverlappedRead);
			if(!bReadStatus)
			{
				if(GetLastError() == ERROR_IO_PENDING)
				{
					SleepEx(200,TRUE);
					continue;
				}
			}

			if(ch[0]==chEndChar)
			{
				 bReadOK = 1;
			}

			*chInBuf = ch[0];
			nRcvlen++;
			chInBuf++;
		}
		if(bReadOK) break;
	}
    *chInBuf = '\0';

    AsynClearReadBuffer();
    return nRcvlen;

}

short CWin32Port::sReadByEndChar(unsigned char chEndChar, char TimeOut)
{

    unsigned long TimeCurr, TimeDelay;
	short ret;
	MSG Message;


    TimeCurr = GetTickCount();
    TimeDelay = TimeOut * 1000;

	while(1)
	{
		if(::PeekMessage(&Message,NULL,0,0,PM_REMOVE))
		{
			::TranslateMessage(&Message);
			::DispatchMessage(&Message);
		}

		if(GetTickCount()-TimeCurr > TimeDelay)
		{
			AsynClearReadBuffer();
			return _ERR_ENDCHAR;
		}
		ret = AsynReadByEndChar(chEndChar);
		if(ret == _NO_DATA) 
		{
			SleepEx(200,TRUE);
			continue;
		}
		return ret;
	}
	return ret;

}

short CWin32Port::sReadByLen(short len,short TimeOut)
{
    unsigned long TimeCurr, TimeDelay;
	short ret;
	MSG Message;


    TimeCurr = GetTickCount();
    TimeDelay = TimeOut * 1000;

	while(1)
	{
		if(::PeekMessage(&Message,NULL,0,0,PM_REMOVE))
		{
			::TranslateMessage(&Message);
			::DispatchMessage(&Message);
		}

		if(GetTickCount()-TimeCurr > TimeDelay)
		{
			AsynClearReadBuffer();
			return _ERR_RCVLEN;
		}
		ret = AsynReadByLen(len);
		if(ret == _NO_DATA) 
		{
			SleepEx(200,TRUE);
			continue;
		}
		return ret;
	}
	return ret;

}

short CWin32Port::sReadComNormal(char TimeOut)
{
	BOOL bReadStatus;
	DWORD dwBytesRead, dwErrorFlags;
	COMSTAT ComStat;

	memset(chRcvbuf,'\0', MAXBLOCK);
	nRcvlen = 0;

    unsigned long  TimeBegin,TimeEnd;
	unsigned char ch[2];
	char *chInBuf;

    TimeBegin = GetTickCount();
    TimeEnd = 1000 * TimeOut;

	chInBuf = chRcvbuf;

	bReadOK = 0;
	nRcvlen = 0;

	while(1)
	{
		if(GetTickCount()-TimeBegin > TimeEnd)
		{
			AsynClearReadBuffer();
			return _ERR_RCVDATA;
		}

		ClearCommError(m_hIDComDev, &dwErrorFlags, &ComStat);
	    dwBytesRead = (DWORD) ComStat.cbInQue;
		if(dwBytesRead<=0)
		{
			SleepEx(50,TRUE);
			continue;
		}
		break;
	}

    TimeBegin = GetTickCount();
    TimeEnd = 200;

	char bNoDataRcvStatus = 0;

	SleepEx(200,TRUE);

	while(1)
	{

		bReadStatus = ReadFile(m_hIDComDev, ch,1, &dwBytesRead,&m_OverlappedRead);
		if(!bReadStatus)
		{
			if(GetLastError() == ERROR_IO_PENDING)
			{
				return _ERR_READCOM;
			}
			return _ERR_READCOM2;
		}

		if(dwBytesRead < 1)
		{
            if(GetTickCount()-TimeBegin > TimeEnd)
			    break;
		}

		if(dwBytesRead < 1 && bNoDataRcvStatus == 0)
		{
			bNoDataRcvStatus  = 1;
		    TimeBegin = GetTickCount();
			continue;
		}

		bNoDataRcvStatus = 0;

		*chInBuf = ch[0];
		nRcvlen++;
		chInBuf++;
	}
    *chInBuf = '\0';
	 bReadOK = 1;

    AsynClearReadBuffer();
    return nRcvlen;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -