异步方式同时打开moxa卡的串口有问题,数据读不出来。要用其他软件一一打开串口读到数据后,再启动我的程序才能读到数据.哪里错了?// BaseCommDevice.cpp: implementation of the CBaseCommDevice class.
//
//////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "BaseCommDevice.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////CBaseCommDevice::CBaseCommDevice()
{
m_hComm = INVALID_HANDLE_VALUE;
memset(m_Port,0,sizeof(m_Port));
m_BaudRate=0;
m_bOpened = FALSE;
m_dwInBuf = 512;
m_dwOutBuf = 512;
dwID=0;
hThreadHandle=NULL;
}CBaseCommDevice::~CBaseCommDevice()
{
CloseDevice();
}
void CBaseCommDevice::setPort(char *szPort)
{
memset(m_Port,0,sizeof(m_Port));
memcpy(m_Port,szPort,strlen(szPort));
}
char *CBaseCommDevice::getPort()
{
return m_Port;
}
void CBaseCommDevice::setBaudRate(int _BaudRate)
{
m_BaudRate=_BaudRate;
}
int CBaseCommDevice::getBaudRate()
{
return m_BaudRate;
}
bool CBaseCommDevice::OpenDevice()
{
ASSERT(m_BaudRate >= 110 || m_BaudRate <= 128000||strlen(m_Port)>0);
DCB dcb = {0};
dcb.DCBlength = sizeof(dcb);
char lpDef[15];
wsprintf(lpDef, "%d,n,8,1", m_BaudRate);
if( m_bOpened ) return true;
char szCom[20];
sprintf(szCom,"\\\\.\\%s",m_Port);
m_hComm = CreateFile(szCom, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if( m_hComm == INVALID_HANDLE_VALUE ) return false; FillMemory(&m_osReader, sizeof(OVERLAPPED), 0);
FillMemory(&m_osWriter, sizeof(OVERLAPPED), 0);
m_osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_osWriter.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
int byteUsedTime = 14400 / m_BaudRate +1; COMMTIMEOUTS timeouts = {20 + byteUsedTime, byteUsedTime, 1000, byteUsedTime , 20};
dcb.fParity = TRUE;
dcb.fErrorChar = TRUE;
dcb.ErrorChar = '~';
if( m_osReader.hEvent == NULL || m_osWriter.hEvent == NULL
|| !SetCommTimeouts(m_hComm, &timeouts)
|| !BuildCommDCB(lpDef, &dcb)
|| !SetupComm(m_hComm, m_dwInBuf, m_dwOutBuf))
{
if( m_osReader.hEvent != NULL )CloseHandle( m_osReader.hEvent );
if( m_osWriter.hEvent != NULL )CloseHandle( m_osWriter.hEvent );
CloseHandle( m_hComm );
return false;
}
m_bOpened = true;
return m_bOpened;}
void CBaseCommDevice::CloseDevice()
{
if (m_osReader.hEvent != NULL) CloseHandle( m_osReader.hEvent );
if (m_osWriter.hEvent != NULL) CloseHandle( m_osWriter.hEvent );
if (m_hComm != NULL)CloseHandle( m_hComm );
m_bOpened = FALSE;
}
void CBaseCommDevice::PreOpenSetupQueue(DWORD dwInQueue, DWORD dwOutQueue)
{
m_dwInBuf = dwInQueue;
m_dwOutBuf = dwOutQueue;
}
BOOL CBaseCommDevice::SetupQueue(DWORD dwInQueue, DWORD dwOutQueue){if (m_hComm == NULL) return FALSE;m_dwInBuf = dwInQueue;m_dwOutBuf = dwOutQueue;return SetupComm(m_hComm, m_dwInBuf, m_dwOutBuf);}
BOOL CBaseCommDevice::ResetParity(char Parity)
{
if (m_hComm == NULL) return FALSE;
DCB dcb;
dcb.DCBlength = sizeof( DCB );
if (!GetCommState(m_hComm, &dcb)) return FALSE;
BYTE cParity;
Parity = tolower(Parity);
switch (Parity) {
case 'o':cParity = 1;break;
case 'e':cParity = 2;break;
case 'm':cParity = 3;break;
case 's':cParity = 4;break;
default:cParity = 0;break;
}
dcb.Parity = cParity;
return SetCommState(m_hComm, &dcb);
}
BOOL CBaseCommDevice::SendData(LPCVOID lpBuf, DWORD dwToWrite)
{
TRACE("SSSSSSSSSSSSS 00\n");
if( !m_bOpened || m_hComm == NULL ) return FALSE;
DWORD dwWritten;
if (WriteFile(m_hComm, lpBuf, dwToWrite, &dwWritten, &m_osWriter)) return TRUE;
if (GetLastError() != ERROR_IO_PENDING) return FALSE;
GetOverlappedResult(m_hComm, &m_osWriter, &dwWritten, TRUE);
TRACE("SSSSSSSSSSSSS 11\n");
return (dwToWrite == dwWritten);}
DWORD CBaseCommDevice::ReadData(LPVOID lpBuf, DWORD dwToRead)
{
TRACE("RRRRRRRRRRRR 00\n");
if( !m_bOpened || m_hComm == NULL ) return 0;
DWORD dwRead;
if (ReadFile(m_hComm, lpBuf, dwToRead, &dwRead, &m_osReader) ) return dwRead;
if (GetLastError() != ERROR_IO_PENDING) return 0;
if (WaitForSingleObject(m_osReader.hEvent, INFINITE) != WAIT_OBJECT_0 )
return 0;
if (!GetOverlappedResult(m_hComm, &m_osReader, &dwRead, FALSE) )
return 0;
TRACE("RRRRRRRRRRRR 11\n");
return dwRead;}
void CBaseCommDevice::Start()
{
dwStopThread=0;
if(!m_bOpened)
{
PreOpenSetupQueue(BUFFLEN, BUFFLEN);
if (!OpenDevice())
{
char buff[100];
sprintf(buff,"Open %s %d error",m_Port,m_BaudRate);
OnError(buff);
return ;
}
hThreadHandle=CreateThread(NULL,0,ReceiveDataThread,this,0,&dwID);
OnAfterStartMonitor();
char buff[100];
sprintf(buff,"Open %s %d success",m_Port,m_BaudRate);
OnError(buff);
return;
}
char buff[100];
sprintf(buff,"Open %s %d already opened",m_Port,m_BaudRate);
OnError(buff);
return;
}
//停止监视
void CBaseCommDevice::Stop()
{
dwStopThread=1;
StopThread(hThreadHandle,dwID);
CloseDevice();
}
DWORD WINAPI CBaseCommDevice::ReceiveDataThread(LPVOID pParam)
{
CBaseCommDevice *pThis=(CBaseCommDevice *)pParam;
while(pThis->dwStopThread==0&&pThis->m_hComm!=INVALID_HANDLE_VALUE)
{
char buf[BUFFLEN];
memset(buf,0,BUFFLEN);
int readlen=pThis->ReadData(buf,BUFFLEN);
if(readlen>0)
{
if(strcmp(buf,"~")==0)pThis->OpenDevice();
else
pThis->OnRecData(buf,readlen);
}
Sleep(100);
}
return 0;
}
//
//////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "BaseCommDevice.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////CBaseCommDevice::CBaseCommDevice()
{
m_hComm = INVALID_HANDLE_VALUE;
memset(m_Port,0,sizeof(m_Port));
m_BaudRate=0;
m_bOpened = FALSE;
m_dwInBuf = 512;
m_dwOutBuf = 512;
dwID=0;
hThreadHandle=NULL;
}CBaseCommDevice::~CBaseCommDevice()
{
CloseDevice();
}
void CBaseCommDevice::setPort(char *szPort)
{
memset(m_Port,0,sizeof(m_Port));
memcpy(m_Port,szPort,strlen(szPort));
}
char *CBaseCommDevice::getPort()
{
return m_Port;
}
void CBaseCommDevice::setBaudRate(int _BaudRate)
{
m_BaudRate=_BaudRate;
}
int CBaseCommDevice::getBaudRate()
{
return m_BaudRate;
}
bool CBaseCommDevice::OpenDevice()
{
ASSERT(m_BaudRate >= 110 || m_BaudRate <= 128000||strlen(m_Port)>0);
DCB dcb = {0};
dcb.DCBlength = sizeof(dcb);
char lpDef[15];
wsprintf(lpDef, "%d,n,8,1", m_BaudRate);
if( m_bOpened ) return true;
char szCom[20];
sprintf(szCom,"\\\\.\\%s",m_Port);
m_hComm = CreateFile(szCom, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if( m_hComm == INVALID_HANDLE_VALUE ) return false; FillMemory(&m_osReader, sizeof(OVERLAPPED), 0);
FillMemory(&m_osWriter, sizeof(OVERLAPPED), 0);
m_osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_osWriter.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
int byteUsedTime = 14400 / m_BaudRate +1; COMMTIMEOUTS timeouts = {20 + byteUsedTime, byteUsedTime, 1000, byteUsedTime , 20};
dcb.fParity = TRUE;
dcb.fErrorChar = TRUE;
dcb.ErrorChar = '~';
if( m_osReader.hEvent == NULL || m_osWriter.hEvent == NULL
|| !SetCommTimeouts(m_hComm, &timeouts)
|| !BuildCommDCB(lpDef, &dcb)
|| !SetupComm(m_hComm, m_dwInBuf, m_dwOutBuf))
{
if( m_osReader.hEvent != NULL )CloseHandle( m_osReader.hEvent );
if( m_osWriter.hEvent != NULL )CloseHandle( m_osWriter.hEvent );
CloseHandle( m_hComm );
return false;
}
m_bOpened = true;
return m_bOpened;}
void CBaseCommDevice::CloseDevice()
{
if (m_osReader.hEvent != NULL) CloseHandle( m_osReader.hEvent );
if (m_osWriter.hEvent != NULL) CloseHandle( m_osWriter.hEvent );
if (m_hComm != NULL)CloseHandle( m_hComm );
m_bOpened = FALSE;
}
void CBaseCommDevice::PreOpenSetupQueue(DWORD dwInQueue, DWORD dwOutQueue)
{
m_dwInBuf = dwInQueue;
m_dwOutBuf = dwOutQueue;
}
BOOL CBaseCommDevice::SetupQueue(DWORD dwInQueue, DWORD dwOutQueue){if (m_hComm == NULL) return FALSE;m_dwInBuf = dwInQueue;m_dwOutBuf = dwOutQueue;return SetupComm(m_hComm, m_dwInBuf, m_dwOutBuf);}
BOOL CBaseCommDevice::ResetParity(char Parity)
{
if (m_hComm == NULL) return FALSE;
DCB dcb;
dcb.DCBlength = sizeof( DCB );
if (!GetCommState(m_hComm, &dcb)) return FALSE;
BYTE cParity;
Parity = tolower(Parity);
switch (Parity) {
case 'o':cParity = 1;break;
case 'e':cParity = 2;break;
case 'm':cParity = 3;break;
case 's':cParity = 4;break;
default:cParity = 0;break;
}
dcb.Parity = cParity;
return SetCommState(m_hComm, &dcb);
}
BOOL CBaseCommDevice::SendData(LPCVOID lpBuf, DWORD dwToWrite)
{
TRACE("SSSSSSSSSSSSS 00\n");
if( !m_bOpened || m_hComm == NULL ) return FALSE;
DWORD dwWritten;
if (WriteFile(m_hComm, lpBuf, dwToWrite, &dwWritten, &m_osWriter)) return TRUE;
if (GetLastError() != ERROR_IO_PENDING) return FALSE;
GetOverlappedResult(m_hComm, &m_osWriter, &dwWritten, TRUE);
TRACE("SSSSSSSSSSSSS 11\n");
return (dwToWrite == dwWritten);}
DWORD CBaseCommDevice::ReadData(LPVOID lpBuf, DWORD dwToRead)
{
TRACE("RRRRRRRRRRRR 00\n");
if( !m_bOpened || m_hComm == NULL ) return 0;
DWORD dwRead;
if (ReadFile(m_hComm, lpBuf, dwToRead, &dwRead, &m_osReader) ) return dwRead;
if (GetLastError() != ERROR_IO_PENDING) return 0;
if (WaitForSingleObject(m_osReader.hEvent, INFINITE) != WAIT_OBJECT_0 )
return 0;
if (!GetOverlappedResult(m_hComm, &m_osReader, &dwRead, FALSE) )
return 0;
TRACE("RRRRRRRRRRRR 11\n");
return dwRead;}
void CBaseCommDevice::Start()
{
dwStopThread=0;
if(!m_bOpened)
{
PreOpenSetupQueue(BUFFLEN, BUFFLEN);
if (!OpenDevice())
{
char buff[100];
sprintf(buff,"Open %s %d error",m_Port,m_BaudRate);
OnError(buff);
return ;
}
hThreadHandle=CreateThread(NULL,0,ReceiveDataThread,this,0,&dwID);
OnAfterStartMonitor();
char buff[100];
sprintf(buff,"Open %s %d success",m_Port,m_BaudRate);
OnError(buff);
return;
}
char buff[100];
sprintf(buff,"Open %s %d already opened",m_Port,m_BaudRate);
OnError(buff);
return;
}
//停止监视
void CBaseCommDevice::Stop()
{
dwStopThread=1;
StopThread(hThreadHandle,dwID);
CloseDevice();
}
DWORD WINAPI CBaseCommDevice::ReceiveDataThread(LPVOID pParam)
{
CBaseCommDevice *pThis=(CBaseCommDevice *)pParam;
while(pThis->dwStopThread==0&&pThis->m_hComm!=INVALID_HANDLE_VALUE)
{
char buf[BUFFLEN];
memset(buf,0,BUFFLEN);
int readlen=pThis->ReadData(buf,BUFFLEN);
if(readlen>0)
{
if(strcmp(buf,"~")==0)pThis->OpenDevice();
else
pThis->OnRecData(buf,readlen);
}
Sleep(100);
}
return 0;
}
if( m_osReader.hEvent == NULL || m_osWriter.hEvent == NULL
|| !SetCommTimeouts(m_hComm, &timeouts)
|| !BuildCommDCB(lpDef, &dcb)
|| !SetupComm(m_hComm, m_dwInBuf, m_dwOutBuf))
{
写成单独判断的语句,这样可以更清楚的知道什么地方出错了。
0, NULL, OPEN_EXISTING,0, NULL);
问题可能在你设定了缓冲区读N长的时候触发一次读事件,若缓冲区读到的没达到N他就不触发,就不会执行读函数,你可以设置成只要缓冲区有字符来就读