win10 串口通讯求助?

lyanwang1251 lyanwang1251 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
现象:

win7 win8 没有问题 ,win10上收包时 总是收不全

代码:

//Open

DWORD CUsb::Open(BOOL bCom)
{
DWORD dwRet = DERR_OPENPORT;
m_hDevice = CreateFile(m_strSymbolLink, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
if(m_hDevice == INVALID_HANDLE_VALUE)
{
TRACE_ERROR();
if(nRetry)
{
CHECKCANCEL(m_csPort)
Sleep(1000);
}
TRACE_INFO(_T("Open Error, Retry ......\r\n"));
}
else
{
Sleep(50);
TRACE_INFO(_T("Open OK\r\n"));
dwRet = DERR_SUCCEED;
if(bCom)
{
// SetCommState
DCB dcb;
::GetCommState(m_hDevice,&dcb);
dcb.BaudRate = 921600;
dcb.fParity=NOPARITY;
dcb.ByteSize=DATABITS_8;
dcb.StopBits=ONESTOPBIT;
::SetCommState(m_hDevice,&dcb);
::SetupComm(m_hDevice,4096,4096);
// SetCommTimeouts
COMMTIMEOUTS timeouts;
::GetCommTimeouts(m_hDevice,&timeouts);
timeouts.ReadIntervalTimeout = -1;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutConstant = 5000;
::SetCommTimeouts(m_hDevice,&timeouts);

}
return dwRet;
}


//Send

DWORD CUsb::Send(LPBYTE pData, DWORD dwLen, DWORD dwTimeout)
{
DWORD dwStartTime = GetTickCount();
LPBYTE pPos = pData;
DWORD dwRemainLen = dwLen;
while(dwRemainLen)
{
DWORD dwCurTime = GetTickCount();
if( dwCurTime - dwStartTime > dwTimeout )
{
TRACE_ERROR();
return DERR_SENDDATA;
}

DWORD dwWriten = 0;
OVERLAPPED osWrite={0};
/* TRACE_INFO(_T("write ========\n"));
LogHex(pPos, dwRemainLen);*/
BOOL bWrite = WriteFile(m_hDevice, pPos, dwRemainLen, &dwWriten, &osWrite);
if(!bWrite)
{
if (GetLastError() == ERROR_IO_PENDING)
{
if(!GetOverlappedResult(m_hDevice, &osWrite, &dwWriten, TRUE))
{
TRACE_ERROR();
return DERR_SENDDATA;
}
else
{
pPos += dwWriten;
dwRemainLen -= dwWriten;
}
}
else
{
TRACE_ERROR();
return DERR_SENDDATA;
}
}
else
{
pPos += dwWriten;
dwRemainLen -= dwWriten;
}
}
// ::PurgeComm(m_hDevice, PURGE_TXABORT|PURGE_TXCLEAR);

return DERR_SUCCEED;

}

//Recv


DWORD COMMUNICATION::CUsb::Recv(LPBYTE& pData, DWORD& dwLen, DWORD dwTimeout)
{
DWORD dwRet = DERR_UNKNOWN;
CDevHelper devhelp;
CByteBuffer buffer;
m_Buffer.Reset();
buffer.SetBuffer(1024*1024);
int len = 0;
COMSTAT stat;
int nTime = 1;
int count = 0;
while(true)
{
DWORD dwReaded = 0;
OVERLAPPED osRead={0};
CHECKCANCEL(m_csPort)
::ClearCommError(m_hDevice, NULL, &stat);
if (stat.cbInQue == 0)
{
if(dwTimeout<=10*nTime)
{
return DERR_REVCDATA;
}
nTime++;
Sleep(10);
continue;
}
len = stat.cbInQue;
if(len>buffer.m_nBufferLen) len = buffer.m_nBufferLen;
osRead.hEvent = CreateEvent(0, TRUE, FALSE, 0);
BOOL bRead = ReadFile(m_hDevice, buffer.m_pBuffer,len, &dwReaded, &osRead);
if(!bRead)
{
if (GetLastError() == ERROR_IO_PENDING)
{
WaitForSingleObject(osRead.hEvent, dwTimeout);
if(!GetOverlappedResult(m_hDevice, &osRead, &dwReaded, FALSE))
{

TRACE_ERROR();
CloseHandle(osRead.hEvent);
return DERR_REVCDATA;
}
else
{
m_Buffer.Append(buffer.m_pBuffer, dwReaded);
}
}
else
{
TRACE_ERROR();
CloseHandle(osRead.hEvent);
return DERR_REVCDATA;
}
}
else
{
m_Buffer.Append(buffer.m_pBuffer, dwReaded);
// TRACE_INFO(_T("Recv len len is %d\n"),dwReaded);
}

CloseHandle(osRead.hEvent);

if(DealFunc(m_Buffer.m_pBuffer, m_Buffer.m_nBufferLen))
{
TRACE_INFO(_T("Recv count len is %d\n"), m_Buffer.m_nBufferLen);
// ::PurgeComm(m_hDevice, PURGE_RXABORT|PURGE_RXCLEAR);
dwRet = DERR_SUCCEED;
break;
}

}
pData = m_Buffer.m_pBuffer;
dwLen = m_Buffer.m_nBufferLen;
return dwRet;
}


描述:

在win10 小数据没有问题 当服务器端放松了一包 1M左右的数据时,Recv 一般在Read到一部分数据后 ClearCommError(m_hDevice, NULL, &stat); stat.cbInQue 一直为0 也就是读不到数据,而且

每次读到的大小不定


请大神帮忙


...全文
评论 14
收藏 已收藏
分享
返回顶部
lyanwang1251
VC/MFC 16,550 成员 421,605 内容