win10 串口通讯求助?

lyanwang1251 2016-08-11 05:47:05
现象:

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 也就是读不到数据,而且

每次读到的大小不定


请大神帮忙


...全文
2548 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
chinahsan 2018-04-26
  • 打赏
  • 举报
回复
你好,你的win10串口数据不正常解决了吗,怎么解决的?
56625079 2016-10-04
  • 打赏
  • 举报
回复
波特率越高,串口连接线要越短。高波特率最好打开校验位
Eleven 2016-10-04
  • 打赏
  • 举报
回复
dcb.BaudRate = 921600; 你设备波特率支持这么大??
三岁、就很帅 2016-08-26
  • 打赏
  • 举报
回复
这种方法时序上估计是有问题的
三岁、就很帅 2016-08-26
  • 打赏
  • 举报
回复
用Active串口控件试试 CMscomm1 试试 顺便说下你的波特率吓死我了 越高越容易丢包吧
木有童年 2016-08-25
  • 打赏
  • 举报
回复
引用 7 楼 zhao4zhong1 的回复:
串口线好长
赵老师你这。。。
赵4老师 2016-08-25
  • 打赏
  • 举报
回复
串口线好长
木有童年 2016-08-25
  • 打赏
  • 举报
回复
波特率好高
liquanhai 2016-08-24
  • 打赏
  • 举报
回复
我最近好像也遇到了 串口到win10后,显示不正常问题
a3622041 2016-08-19
  • 打赏
  • 举报
回复
不知道发射数据的设备是不是你们写的。。 一般会将通讯协议某几个字节设置为包长, 例如第二个字节是长度,你可以将接受的数据进行对比,如果长度不够就判断缓冲区再接收,如果还不对 可以把数据抛弃掉,然后发一条命令,让设备再发一次数据 重复这样
liquanhai 2016-08-18
  • 打赏
  • 举报
回复
引用 2 楼 zgl7903 的回复:
1 单独线程或死循环 读数据写入文件,看看是否正常 2 SetupComm 放大, 按 1M 波特率,1S差不多100K数据,4K缓冲 要保证读取超过25次/s 3 缓冲区尽量避免重复申请,系统安全性越高,申请缓冲区效率越低下 4 使用合理的分包和重发机制,数据包太大,任何一个错误 都会导致整个数据报无效
写的蛮好的,我来学习一下!
zgl7903 2016-08-17
  • 打赏
  • 举报
回复
1 单独线程或死循环 读数据写入文件,看看是否正常 2 SetupComm 放大, 按 1M 波特率,1S差不多100K数据,4K缓冲 要保证读取超过25次/s 3 缓冲区尽量避免重复申请,系统安全性越高,申请缓冲区效率越低下 4 使用合理的分包和重发机制,数据包太大,任何一个错误 都会导致整个数据报无效
Wenxy1 2016-08-16
  • 打赏
  • 举报
回复
windows driver放linux版,不合适呀,--> windows版.

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧