RS485读写头文件 VC++代码
// SerialPort.h: interface for the CSerialPort class.
//
//
#if !defined(AFX_SERIALPORT_H__5EA960A8_CC22_11D4_86FD_5254AB12C040__INCLUDED_)
#define AFX_SERIALPORT_H__5EA960A8_CC22_11D4_86FD_5254AB12C040__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CHanwangEye;
#define ASCII_BEL 0x07
#define ASCII_BS 0x08
#define ASCII_LF 0x0A
#define ASCII_CR 0x0D
#define ASCII_XON 0x11
#define ASCII_XOFF 0x13
DWORD FAR PASCAL CommWatchProc(LPVOID lpData);
#include "CommonSocket.h"
class CSerialPort
{
public:
CSerialPort();
virtual ~CSerialPort();
HANDLE m_hCom;
BOOL m_fConnected;
HANDLE m_hCommWatchThread;
DWORD m_dwThreadID;
OVERLAPPED m_osRead, m_osWrite;
CHanwangEye* m_pEye;
bool m_blIdle;
LPBYTE pReceive;
int nReceive; //当前报文长度
int mReceive; //最大长度
/*#ifdef LPR_DOHERELARGE
BYTE m_pInfo[e_nInfoLength];
BYTE m_pID[e_nIDLength];
BYTE m_pEmptyID[e_nIDLength];
BYTE m_pImage[e_nImageLength];
int m_nImageState;
#endif*/
BOOL m_bClearUntillEmpty;
public:
BOOL Connect(CString szCom, DWORD BaudRate, BYTE ByteSize, BYTE StopBits, BYTE Parity);
BOOL Disconnect();
BOOL GetCommState(DCB* pDCB);
BOOL SetCommState(DCB* pDCB);
BOOL GetCommTimeouts(LPCOMMTIMEOUTS lpCommTimeouts);
BOOL SetCommTimeouts(LPCOMMTIMEOUTS lpCommTimeouts);
BOOL Write(LPBYTE pData, DWORD dwLength);
DWORD Read(LPBYTE pData, DWORD dwLength);
DWORD ReadByBlock(LPBYTE pBuffer, DWORD dwWantSize, DWORD dwBlockSize);
static int Write(CSerialPort* pSerial1, LPBYTE pData1, DWORD dwLength1, CSerialPort* pSerial2, LPBYTE pData2, DWORD dwLength2);
};
#endif // !defined(AFX_SERIALPORT_H__5EA960A8_CC22_11D4_86FD_5254AB12C040__INCLUDED_)
RS485读写源程序 VC++代码
// SerialPort.cpp: implementation of the CSerialPort class.
//
//
//Author:horse_b
#include "stdafx.h"
#include "SerialPort.h"
#include /<stdlib.h/>
#include /<stdio.h/>
#include /<time.h/>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
extern CRoadSvrDlg* pRoadSvrDlg;
//LARGE_INTEGER lia, lib, lif, lis;
//int lin;
//串口类的初始化
CSerialPort::CSerialPort()
{
m_blIdle = false;
m_hCom = INVALID_HANDLE_VALUE;
m_hCommWatchThread = NULL;
m_fConnected = false;
memset(&m_osRead, 0, sizeof(OVERLAPPED));
memset(&m_osWrite, 0, sizeof(OVERLAPPED));
m_osRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL);
m_osWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL);
m_pEye = NULL;
mReceive = 1024000;
pReceive = new BYTE[mReceive];
m_bClearUntillEmpty = false;
/*#ifdef LPR_DOHERELARGE
memset(m_pEmptyID, 0, e_nIDLength);
m_nImageState = 0;
#endif*/
}
CSerialPort::~CSerialPort()
{
Disconnect();
if (m_osRead.hEvent)
CloseHandle(m_osRead.hEvent);
if (m_osWrite.hEvent)
CloseHandle(m_osWrite.hEvent);
delete pReceive;
}
/****************************************************************************************
* 函数名 : CSerialPort::Connect
* 说 明 : 连接一个串口,非Overlap方式
* 返回值 : BOOL - 是否连接成功
* 参 数 : HWND hWnd - 接收到数据之后,通知的窗口
* 参 数 : CString szCom - 串口名称 "Com1" or "Com2"
* 参 数 : DWORD BaudRate - 波特率 2400 9600 etc.
* 参 数 : BYTE ByteSize - 数据位 8
* 参 数 : BYTE StopBits - 停止位 0,1,2 = 1, 1.5, 2 stop bits
* 参 数 : BYTE Parity - 奇偶校验 0-4=no,odd,even,mark,space
****************************************************************************************/
BOOL CSerialPort::Connect(CString szCom, DWORD BaudRate, BYTE ByteSize, BYTE StopBits, BYTE Parity)
{
if (m_osRead.hEvent == NULL || m_osWrite.hEvent == NULL)
{
m_fConnected = false;
return false;
}
m_hCom = CreateFile(szCom, GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, // overlapped I/O
NULL);
if (m_hCom == INVALID_HANDLE_VALUE)
{
m_fConnected = false;
return FALSE;
}
SetCommMask(m_hCom, EV_RXCHAR|EV_CTS);
//SetupComm(m_hCom, 20480, 20480);
SetupComm(m_hCom, 512000, 512000);
PurgeComm(m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
DCB dcb;
GetCommState(&dcb);
dcb.BaudRate = BaudRate;
dcb.ByteSize = ByteSize;
dcb.Parity = Parity;
dcb.StopBits = StopBits;
dcb.fBinary = TRUE;
dcb.fParity = TRUE;
dcb.fOutxDsrFlow = false;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fOutxCtsFlow = false;
//#ifdef LPR_DOHERELARGE
// dcb.fRtsControl = RTS_CONTROL_ENABLE;
//#else
dcb.fRtsControl = RTS_CONTROL_DISABLE;
//#endif
dcb.fInX = false;
dcb.fOutX = false;
dcb.XonChar = ASCII_XON;
dcb.XoffChar = ASCII_XOFF;
dcb.XonLim = 100;
dcb.XoffLim = 100;
m_fConnected = SetCommState(&dcb);
if (!m_fConnected)
return false;
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0;
CommTimeOuts.ReadTotalTimeoutMultiplier = __max(1, 2 * CBR_9600 / BaudRate);
CommTimeOuts.ReadTotalTimeoutConstant = 10;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 0 ;
m_fConnected = ::SetCommTimeouts(m_hCom, &CommTimeOuts) ;
if (!m_fConnected)
return false;
m_hCommWatchThread = CreateThread((LPSECURITY_ATTRIBUTES) NULL,
0,
(LPTHREAD_START_ROUTINE)CommWatchProc,
(LPVOID) this,
0,
&m_dwThreadID);
if (m_hCommWatchThread == NULL)
m_fConnected = false;
SetThreadPriority(m_hCommWatchThread, THREAD_PRIORITY_ABOVE_NORMAL);//THREAD_PRIORITY_TIME_CRITICAL);//THREAD_PRIORITY_HIGHEST);//);
return m_fConnected;
}
BOOL CSerialPort::GetCommState(DCB* pDCB)
{
if (m_hCom == INVALID_HANDLE_VALUE)
return false;
return ::GetCommState(m_hCom, pDCB) ;
}
BOOL CSerialPort::SetCommState(DCB* pDCB)
{
if (m_hCom == INVALID_HANDLE_VALUE)
return false;
return ::SetCommState(m_hCom, pDCB);
}
DWORD FAR PASCAL CommWatchProc(LPVOID lpData)
{
CSerialPort* pSerial = (CSerialPort*)lpData;
DWORD dwEvtMask;
DWORD nLength;
DWORD dwBlockSize = 128;
LARGE_INTEGER freq, begin, end;
::QueryPerformanceFrequency(&freq);
COMSTAT ComStat ;
DWORD dwErrorFlags = 0;
memset(&ComStat, 0, sizeof(ComStat));
#ifdef LPR_DOHERELARGE
BOOL blTriggered = false;
#endif
pSerial->m_blIdle = false;
while (pSerial->m_fConnected)
{
dwEvtMask = 0 ;
if (pRoadSvrDlg->e_nIO == 0 && !pRoadSvrDlg->e_bWithToll)
pRoadSvrDlg->SetWindowText("RoadSvr - Idle");
else
pRoadSvrDlg->PostMessage(WM_NOTIFYSERIALSTATE, 0, (LPARAM)pSerial); //Idle
if (pRoadSvrDlg->m_bl485 && pSerial == &(pSerial->m_pEye->m_Serial1))
{
while(pSerial->m_fConnected)
{
::QueryPerformanceCounter(&begin);
::QueryPerformanceCounter(&end);
while((end.QuadPart - begin.QuadPart) * 1000 / freq.QuadPart < pRoadSvrDlg->m_n485Interval)
{
Sleep(0);
ClearCommError(pSerial->m_hCom, &dwErrorFlags, &ComStat);
//在等候的时间内,若有数据上来,则继续
if (ComStat.cbInQue > 0)
break;
::QueryPerformanceCounter(&end);
}
if (ComStat.cbInQue == 0)
{
//如果数据没有接受完,则最多等1秒钟
// while (pRoadSvrDlg->e_btEyeData != 0 &&
// (end.QuadPart - begin.QuadPart) * 1000 / freq.QuadPart < 1000)
// {
// ::QueryPerformanceCounter(&end);
// }
//若有需要查找的汉王眼,则查找
if (pRoadSvrDlg->m_nAddressList > 0)
{
pRoadSvrDlg->m_nAddress ++;
if (pRoadSvrDlg->m_nAddress >= pRoadSvrDlg->m_nAddressList)
pRoadSvrDlg->m_nAddress = 0;
pSerial->Write(&(pRoadSvrDlg->m_pAddressList[pRoadSvrDlg->m_nAddress]), 1);
}
//继续,等待是否有结果上来
continue;
}
//若有结果上来,则继续执行下面的接受部分
break;
}
}
else
{ //等待10m,若没有数据,则认为已经空闲,可以下发数据,及进入Wait状态
::QueryPerformanceCounter(&begin);
::QueryPerformanceCounter(&end);
while((end.QuadPart - begin.QuadPart) * 1000 / freq.QuadPart < 5) //5ms
{
ClearCommError(pSerial->m_hCom, &dwErrorFlags, &ComStat);
if (ComStat.cbInQue > 0)
break;
Sleep(0);
::QueryPerformanceCounter(&end);
}
if (ComStat.cbInQue == 0)
pSerial->m_blIdle = true;
}
WaitCommEvent(pSerial->m_hCom, &dwEvtMask, NULL);
if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
{
ClearCommError(pSerial->m_hCom, &dwErrorFlags, &ComStat);
if (ComStat.cbInQue == 0)
continue;
pSerial->m_blIdle = false;
if (pRoadSvrDlg->e_nIO == 0 && !pRoadSvrDlg->e_bWithToll)
pRoadSvrDlg->SetWindowText("RoadSvr - Receiving ...");
else
pRoadSvrDlg->PostMessage(WM_NOTIFYSERIALSTATE, 1, (LPARAM)pSerial); //Receiving
nLength = 0;
BOOL bError = false;
while(pSerial->m_fConnected)
{
while((nLength = pSerial->Read(pSerial->pReceive, 1)) == 1 && pSerial->pReceive[0] == 0);
if (nLength == 0)
break;
ASSERT(nLength == 1);
ASSERT(pSerial->pReceive[0] != 0);
nLength = pSerial->Read(pSerial->pReceive+1, 4);
if (nLength == 0)
break;
nLength ++;
pSerial->nReceive = nLength;
if (nLength == 5 && //报文头的长度
((pSerial->pReceive[0] == 0xF0 && pSerial->pReceive[1] == 0x0F) //如果报文头的格式正确
|| //报文的格式为可能错误的那种格式,即只有识别数据报文的第一个字节发错误为0xFC,其他字节是正确的。
(pSerial->pReceive[0] == 0xFC && pSerial->pReceive[1] == 0x0F && pSerial->pReceive[2] == 0x3B &&
pSerial->pReceive[3] == 0x00 && (pSerial->pReceive[4] == 0x01 || pSerial->pReceive[4] == 0x02 || pSerial->pReceive[4] == 0x03))
)
)
{
DWORD len = pSerial->pReceive[2] + pSerial->pReceive[3] * 0x100;//报文长度
if ((pSerial->pReceive[4] == 0x03 || pSerial->pReceive[4] == 0x01 || pSerial->pReceive[4] == 0x02) && len + pSerial->nReceive > 64)
bError = true;
if (pSerial->pReceive[4] == 0x21 && len + pSerial->nReceive > (DWORD)pSerial->mReceive)
bError = true;
else if (pSerial->pReceive[4] == 0x22 && len + pSerial->nReceive > (DWORD)pSerial->mReceive)
bError = true;
else if (pSerial->pReceive[4] == 0x23 && len != 0)
bError = true;
else
{
switch(pSerial->pReceive[4])
{
case 0x01:
case 0x02:
case 0x03:
if (pSerial->pReceive[0] == 0xFC) //针对黄冈的通讯错误进行的处理
pSerial->pReceive[0] = 0xF0; //更正错误的内容
nLength = pSerial->Read(pSerial->pReceive + 5, len);
pSerial->nReceive += nLength;
pRoadSvrDlg->OnReceiveMeInfo(pSerial->pReceive, pSerial->nReceive);
//#ifdef LPR_MATCHDEMO
pRoadSvrDlg->OnSerialNotifyInfo(0, 0);
//#else
// pRoadSvrDlg->PostMessage(WM_SERIALNOTIFY_INFO, 0, 0);
//#endif
pSerial->m_pEye->bImage = true; //图片是否正确的标记,只对正确的图片发送和进行图片比较
if (pRoadSvrDlg->m_pInfoExtractDlg != NULL)
((CInfoExtractDlg*)pRoadSvrDlg->m_pInfoExtractDlg)->ShowInfoExtract(pSerial->pReceive, pSerial->nReceive);
break;
case 0x11:
if (len > 0)
{
nLength = pSerial->Read(pSerial->pReceive + 5, 1);
pSerial->nReceive += nLength;
if (nLength == 1)
{
switch(pSerial->pReceive[5])
{
case 0x00:
case 0x01:
{
nLength = pSerial->ReadByBlock(pRoadSvrDlg->e_pImage, len - 1, dwBlockSize);
if (nLength < len - 1)
memset(pRoadSvrDlg->e_pImage + nLength, 0, len - 1 - nLength);
}
pSerial->nReceive += nLength;
pSerial->m_pEye->nImageOdd = nLength / 2;
pSerial->m_pEye->nImageEven = nLength - pSerial->m_pEye->nImageOdd;
SetEvent(pSerial->m_pEye->m_hImageReceivedEven);
SetEvent(pSerial->m_pEye->m_hImageReceivedOdd);
break;
case 0x02:
nLength = pSerial->ReadByBlock(pSerial->pReceive + 6, len - 1, dwBlockSize);
if (nLength < len - 1)
memset(pSerial->pReceive + 6 + nLength, 0, len - 1 - nLength);
pSerial->nReceive += nLength;
{
if (pSerial->m_pEye->bImage && nLength != len - 1)
pSerial->m_pEye->bImage = false;
for (DWORD i = 0 ; i < len - 1 ; i ++)
{
if (i < nLength)
pRoadSvrDlg->e_pImage[i * 2] = pSerial->pReceive[6 + i];
else
pRoadSvrDlg->e_pImage[i * 2] = 0;
}
pSerial->m_pEye->nImageEven = len - 1;//nLength; //强迫数据长度是对的,以可以显示一些虽然错误,但是还能基本解码的图片
SetEvent(pSerial->m_pEye->m_hImageReceivedEven);
}
break;
case 0x12:
nLength = pSerial->ReadByBlock(pSerial->pReceive + 6, len - 1, dwBlockSize);
if (nLength < len - 1)
memset(pSerial->pReceive + 6 + nLength, 0, len - 1 - nLength);
pSerial->nReceive += nLength;
{
if (pSerial->m_pEye->bImage && nLength != len - 1)
pSerial->m_pEye->bImage = false;
for (DWORD i = 0 ; i < len - 1 ; i ++)
{
if (i < nLength)
pRoadSvrDlg->e_pImage[1 + i * 2] = pSerial->pReceive[6 + i];
else
pRoadSvrDlg->e_pImage[1 + i * 2] = 0;
}
pSerial->m_pEye->nImageOdd = len - 1; //nLength;
SetEvent(pSerial->m_pEye->m_hImageReceivedOdd);
}
break;
default:
bError = true;
}
}
}
pSerial->m_pEye->QueryReceiveImage();
break;
case 0x21:
case 0x22:
nLength = pSerial->Read(pSerial->pReceive + 5, len);
pSerial->nReceive += nLength;
case 0x23:
pRoadSvrDlg->OnReceiveMeMatch(pSerial->pReceive, pSerial->nReceive);
pRoadSvrDlg->m_dwMatchStatus |= MAT_BYIMAGE; //仅图像匹配有该报文,车牌号码匹配不在该报文的管辖范围之内(新的修改,2001年11月15日)
break;
case 0xF1:
nLength = pSerial->Read(pSerial->pReceive + 5, 5);
pSerial->nReceive += nLength;
if (nLength == 5)
{
DWORD dwImageSize = *((DWORD*)(pSerial->pReceive+6));
switch(pSerial->pReceive[5])
{
case 0x00:
case 0x01:
{
nLength = pSerial->ReadByBlock(pSerial->m_pEye->pImage, dwImageSize, dwBlockSize);
if (nLength < dwImageSize)
memset(pSerial->m_pEye->pImage + nLength, 0xFF, dwImageSize - nLength);
pSerial->m_pEye->nImageEven = dwImageSize;
pSerial->m_pEye->nImageOdd = 0;
pSerial->m_pEye->nImage = dwImageSize;
ResetEvent(pSerial->m_pEye->m_hImageReceivedEven);
ResetEvent(pSerial->m_pEye->m_hImageReceivedOdd);
pRoadSvrDlg->OnReceiveDebugImage(pSerial->m_pEye->pImage, pSerial->m_pEye->nImage, len);
}
break;
case 0x02://模拟收费计算机接收第一个车牌图片报文
{
nLength = pSerial->ReadByBlock(pSerial->pReceive + 10, dwImageSize, dwBlockSize);
for (DWORD i = 0 ; i < dwImageSize ; i ++)
{
if (i < nLength)
pSerial->m_pEye->pImage[i * 2] = pSerial->pReceive[10 + i];
else
pSerial->m_pEye->pImage[i * 2] = 0xFF;
}
pSerial->m_pEye->nImageEven = dwImageSize;
SetEvent(pSerial->m_pEye->m_hImageReceivedEven);
}
break;
case 0x12:
{
nLength = pSerial->ReadByBlock(pSerial->pReceive + 10, dwImageSize, dwBlockSize);
for (DWORD i = 0 ; i < dwImageSize ; i ++)
{
if (i < nLength)
pSerial->m_pEye->pImage[1 + i * 2] = pSerial->pReceive[10 + i];
else
pSerial->m_pEye->pImage[1 + i * 2] = 0xFF;
}
pSerial->m_pEye->nImageOdd = dwImageSize;
SetEvent(pSerial->m_pEye->m_hImageReceivedOdd);
}
break;
default:
bError = true;
}
}
else
bError = true;
pSerial->m_blIdle = true; //正常来说,过了这个报文就没有报文了,而下一个触发是很难预料什么时候的
pSerial->m_pEye->QueryReceiveDebugImage(len);
break;
case 0x31:
#ifdef LPR_DOHERELARGE
if (pRoadSvrDlg->m_nTriggerMethod == 1)
{
if (pRoadSvrDlg->m_pCaptureDlg != NULL)
{
#ifdef CAP_DAHENG
((CDHCaptureDlg*)(pRoadSvrDlg->m_pCaptureDlg))->Capture("", true);
#endif
}
}
//else
//if (pRoadSvrDlg->m_pCaptureDlg != NULL)
// pRoadSvrDlg->m_pCaptureDlg->PostMessage(WM_NOTIFYCAPTURENOW, 0, 0);
#endif
break;
default:
nLength = pSerial->Read(pSerial->pReceive + 5, len);
pSerial->nReceive += nLength;
if (nLength != len)
bError = true;
}
}
}
if (pRoadSvrDlg->m_pDebugDlg != NULL)
pRoadSvrDlg->m_pDebugDlg->Message(pSerial->pReceive, pSerial->nReceive, "[->] ");
if (bError)
{
ClearCommError(pSerial->m_hCom, &dwErrorFlags, &ComStat);
while(ComStat.cbInQue)
{
PurgeComm(pSerial->m_hCom, PURGE_RXABORT | PURGE_RXCLEAR);
CHssApp::Idle(1);
ClearCommError(pSerial->m_hCom, &dwErrorFlags, &ComStat);
}
}
}
}
#if 0
if ((dwEvtMask & EV_CTS) == EV_CTS)
{
#ifdef LPR_DOHERELARGE
if (pRoadSvrDlg->m_nTriggerMethod == 0)
{
DWORD dwModemStat;
GetCommModemStatus(pSerial->m_hCom, &dwModemStat);
if (dwModemStat & MS_CTS_ON)
{
if (!blTriggered)
{
blTriggered = true;
if (pRoadSvrDlg->m_pCaptureDlg != NULL)
{
#ifdef CAP_DAHENG
((CDHCaptureDlg*)(pRoadSvrDlg->m_pCaptureDlg))->Capture("", true);
#endif
}
}
}
else
{
blTriggered = false;
}
}
#endif
}
#endif
}
pSerial->m_dwThreadID = 0;
pSerial->m_hCommWatchThread = NULL;
return TRUE;
}
BOOL CSerialPort::GetCommTimeouts(LPCOMMTIMEOUTS lpCommTimeouts)
{
if (m_hCom == INVALID_HANDLE_VALUE)
return false;
return ::GetCommTimeouts(m_hCom, lpCommTimeouts);
}
BOOL CSerialPort::SetCommTimeouts(LPCOMMTIMEOUTS lpCommTimeouts)
{
if (m_hCom == INVALID_HANDLE_VALUE)
return false;
return ::SetCommTimeouts(m_hCom, lpCommTimeouts);
}
BOOL CSerialPort::Disconnect()
{
if (m_hCom == INVALID_HANDLE_VALUE)
return true;
if (!m_fConnected)
return true;
m_fConnected = false;
//SetCommMask(m_hCom, 0);
int count = 0;
while(m_dwThreadID != 0 && count < 100)
{
Sleep(10);
count ++;
}
EscapeCommFunction(m_hCom, CLRDTR) ;
PurgeComm(m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
CloseHandle(m_hCom) ;
m_hCom = INVALID_HANDLE_VALUE;
return true;
}
BOOL CSerialPort::Write(LPBYTE pData, DWORD dwLength)
{
if (m_hCom == INVALID_HANDLE_VALUE)
return false;
DWORD dwBytesSent = 0;
DWORD dwBytesWritten ;
DWORD dwErrorFlags;
DWORD dwError;
COMSTAT ComStat;
BOOL fWriteStat = ::WriteFile(m_hCom, pData, dwLength, &dwBytesWritten, &m_osWrite);
if (!fWriteStat)
{
if(GetLastError() == ERROR_IO_PENDING)
{
while(!GetOverlappedResult(m_hCom, &m_osWrite, &dwBytesWritten, false))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
{
dwBytesSent += dwBytesWritten;
continue;
}
else
{
ClearCommError(m_hCom, &dwErrorFlags, &ComStat ) ;
break;
}
}
dwBytesSent += dwBytesWritten;
if( dwBytesSent != dwLength )
return false;
}
else
{
ClearCommError( m_hCom, &dwErrorFlags, &ComStat ) ;
if (pRoadSvrDlg->m_pDebugDlg != NULL)
pRoadSvrDlg->m_pDebugDlg->Message(pData, dwLength, "[×] ");
return false;
}
}
if (pRoadSvrDlg->m_pDebugDlg != NULL)
pRoadSvrDlg->m_pDebugDlg->Message(pData, dwLength, "[√] ");
return true;
}
DWORD CSerialPort::Read(LPBYTE pData, DWORD dwLength)
{
BOOL fReadStat;
COMSTAT ComStat;
DWORD dwErrorFlags;
DWORD dwError;
DWORD dwBytesReaded, dwBytesReceive = 0;
fReadStat = ReadFile(m_hCom, pData, dwLength, &dwBytesReaded, &m_osRead);
if (!fReadStat)
{
if (GetLastError() == ERROR_IO_PENDING)
{
while(!GetOverlappedResult(m_hCom, &m_osRead, &dwBytesReaded, true))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
{
dwBytesReceive += dwBytesReaded;
continue;
}
else
{
ClearCommError(m_hCom, &dwErrorFlags, &ComStat);
return dwBytesReceive;
}
}
dwBytesReceive += dwBytesReaded;
return dwBytesReceive;
}
else
{
ClearCommError(m_hCom, &dwErrorFlags, &ComStat);
return dwBytesReceive;
}
}
return dwBytesReaded;
}
//0 :false 1 : first true 2 : second true 3 two true
int CSerialPort::Write(CSerialPort* pSerial1, LPBYTE pData1, DWORD dwLength1,
CSerialPort* pSerial2, LPBYTE pData2, DWORD dwLength2)
{
BOOL bCom1 = (pSerial1->m_hCom != INVALID_HANDLE_VALUE && pSerial1->m_fConnected);
BOOL bCom2 = (pSerial2->m_hCom != INVALID_HANDLE_VALUE && pSerial2->m_fConnected);
if (!bCom1 && !bCom2)
return 0;
DWORD dwBytesSent1 = 0, dwBytesSent2 = 0;
DWORD dwBytesWritten1, dwBytesWritten2 ;
DWORD dwErrorFlags;
DWORD dwError;
COMSTAT ComStat;
BOOL bFinish1 = false, bFinish2 = false;
if (bCom1 && !WriteFile(pSerial1->m_hCom, pData1, dwLength1, &dwBytesWritten1, &pSerial1->m_osWrite))
{
if (GetLastError() != ERROR_IO_PENDING)
{
ClearCommError(pSerial1->m_hCom, &dwErrorFlags, &ComStat ) ;
bCom1 = false;
}
}
else
{
//dwBytesSent1 == dwBytesWritten1;
bFinish1 = true;
}
if (bCom2 && !WriteFile(pSerial2->m_hCom, pData2, dwLength2, &dwBytesWritten2, &pSerial2->m_osWrite))
{
if (GetLastError() != ERROR_IO_PENDING)
{
ClearCommError(pSerial2->m_hCom, &dwErrorFlags, &ComStat ) ;
bCom2 = false;
}
}
else
{
//dwBytesSent2 == dwBytesWritten2;
bFinish2 = true;
}
while((bCom1 && !bFinish1) || (bCom2 && !bFinish2))
{
if (bCom1 && !GetOverlappedResult(pSerial1->m_hCom, &pSerial1->m_osWrite, &dwBytesWritten1, false))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
;//dwBytesSent1 += dwBytesWritten1;
else
bCom1 = false;
}
else
bFinish1 = true;
if (bCom2 && !GetOverlappedResult(pSerial2->m_hCom, &pSerial2->m_osWrite, &dwBytesWritten2, false))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
;//dwBytesSent1 += dwBytesWritten1;
else
bCom2 = false;
}
else
bFinish2 = true;
}
//return (bCom1 ? (dwBytesSent1 == dwLength1 ? 1 : 0) : 0) + (bCom2 ? (dwBytesSent2 == dwLength2 ? 2 : 0) : 0);
return (bCom1 && bFinish1 ? 1 : 0) + (bCom2 && bFinish2 ? 2 : 0);
}
DWORD CSerialPort::ReadByBlock(LPBYTE pBuffer, DWORD dwWantSize, DWORD dwBlockSize)
{
DWORD dwReceived = 0;
DWORD dwReceiving = __min(dwWantSize - dwReceived, dwBlockSize);
while(dwReceived < dwWantSize)
{
DWORD nLength = Read(pBuffer + dwReceived, dwReceiving);
dwReceived += nLength;
if (nLength != dwReceiving)
return dwReceived;
dwReceiving = __min(dwWantSize - dwReceived, dwBlockSize);
}
return dwReceived;
}
更多技术文章请参看施昌权的个人网站: http://www.joyvc.cn