VC 串口接收数据的解析

aoyihuashao 2009-04-10 12:32:00
以前没弄过串口编程,所以问题可能会比较白痴,我把问题描述的详细点。


从串口接收数据,串口会一直返回这样格式的数据:02001401018200000C334455660000000000000000421E,

02: 数据头
00 14:全数据长度
01 01:特殊含义的字段
82 00:特殊含义的字段
00 0C:需要得到的数据的长度
334455660000000000000000 需要得到的数据
421E:CRC校验

问题,我需要接收到的数据应该是02001401018200000C334455660000000000000000421E一整条,
但结果却是半条,或者一条半,两条半

为什么会这样,该怎样解决,最好详细点。


代码如下:

我接受数据的函数:
读串口:

DWORD CCESeries::ReadThreadFunc(LPVOID lparam)
{
CCESeries *ceSeries = (CCESeries*)lparam;

DWORD evtMask;
BYTE * readBuf = NULL;//读取的字节
DWORD actualReadLen=0;//实际读取的字节数
DWORD willReadLen;

DWORD dwReadErrors;
COMSTAT cmState;

// 清空缓冲,并检查串口是否打开。
ASSERT(ceSeries->m_hComm !=INVALID_HANDLE_VALUE);


//清空串口
PurgeComm(ceSeries->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR );

SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
while (TRUE)
{
if (WaitCommEvent(ceSeries->m_hComm,&evtMask,0))
{
SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
//表示串口收到字符
if (evtMask & EV_RXCHAR)
{
ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState);
willReadLen = cmState.cbInQue ;
if (willReadLen <= 0)
{
continue;
}

//分配内存
readBuf = new BYTE[willReadLen];
ZeroMemory(readBuf,willReadLen);
//读取串口数据
ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen,0);

//如果读取的数据大于0,
if (actualReadLen>0)
{
//触发读取回调函数
if (ceSeries->m_OnSeriesRead)
{
ceSeries->m_OnSeriesRead(ceSeries->m_pOwner,readBuf,actualReadLen);
}
}

//释放内存
delete[] readBuf;
readBuf = NULL;
}
}
//如果收到读线程退出信号,则退出线程
if (WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0)
{
break;
}
//Sleep(1000);
}
return 0;
}


串口响应函数:

void CALLBACK MyDlg::OnSerialRead(void * pOwner,BYTE* buf,DWORD bufLen)
{
BYTE *pRecvBuf = NULL; //接收缓冲区
//得到父对象指针
MyDlg* pThis = (MyDlg*)pOwner;
//将接收的缓冲区拷贝到pRecvBuf种
pRecvBuf = new BYTE[bufLen];
CopyMemory(pRecvBuf,buf,bufLen);
//发送异步消息,表示收到串口数据,消息处理完,应释放内存
pThis->PostMessage(WM_RECV_SERIAL_DATA,WPARAM(pRecvBuf),bufLen);
}

数据处理函数:

LONG MyDlg::OnRecvSerialData(WPARAM wParam,LPARAM lParam)
{
CString strRecv = L"";
//串口接收到的BUF
BYTE *pBuf = (BYTE*)wParam;
//串口接收到的BUF长度
DWORD dwBufLen = lParam;
CString temp;
for(int i=0;i<lParam;i++)
{
temp.Format(L"%02x",pBuf[i]);
strRecv+=temp;
}

//将新接收到的文本添加到接收框中
m_table.InsertItem(0,strRecv);

//释放内存
delete[] pBuf;
pBuf = NULL;
return 0;
}




...全文
3124 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
voice2007 2012-06-14
  • 打赏
  • 举报
回复
学习!!!!!!
willdehao 2012-06-01
  • 打赏
  • 举报
回复
加上包头包尾,这样按照头尾解析快
shaogent 2009-10-20
  • 打赏
  • 举报
回复
学习了
kaneself 2009-08-15
  • 打赏
  • 举报
回复
学习一下,参考参考
aoyihuashao 2009-05-06
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 iwillbeback008 的回复:]
引用 6 楼 aoyihuashao 的回复:
最后的解决方法:

读到的字符串放到另外一个字符串里面,然后处理另外一个字符串,解决同步问题就可以了。


那你的速度上跟得上么?
[/Quote]

好像有个地方是跟不上,不过不是上面这里,这里是没问题的,
跟不上的那个地方,我把POST改成了SEND,经过实践测试,还是不错的。
iwillbeback008 2009-04-28
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 aoyihuashao 的回复:]
最后的解决方法:

读到的字符串放到另外一个字符串里面,然后处理另外一个字符串,解决同步问题就可以了。
[/Quote]

那你的速度上跟得上么?
aoyihuashao 2009-04-23
  • 打赏
  • 举报
回复
最后的解决方法:

读到的字符串放到另外一个字符串里面,然后处理另外一个字符串,解决同步问题就可以了。
tian_yang_jian 2009-04-12
  • 打赏
  • 举报
回复
学习了
vcPlayer 2009-04-12
  • 打赏
  • 举报
回复
这个其实跟网络通信中的拆包一样的道理。你数据不是已经有了一个数据长度的“域”了吗?为什么不用它呢?第一段数据,你都按照这个长度取,取完后就是下一段数据了,没取够就不处理。
wutaihua 2009-04-10
  • 打赏
  • 举报
回复
我做过一个串口通讯的软件,本来要求很简单的,但是由于linux内核一直狂打印数据,所以做的后来就复杂了,但是也更加完备了,基本跟SecureCRT差不多了。

我的做法是申请一个COM缓冲区大小一样的缓存(只可以更大些。或者2倍大小)。当WaitCommEvent得到消息后,立即读取缓冲中的数据以追加的方式到缓存,并清空COM缓冲。

在缓存中,如果半条数据,如果是前半条,那就暂存数据,等后半条到达。

如果是一条半数据的话,就读取一条数据。把那半条数据放到缓存的头部,然后其他位置清空。等到后半条到达。

如果是2条半,就读取2条数据,把那半条数据放到缓存的头部,然后其他位置清空。等到后半条到达,这样,就在外部完成了数据的拼接了。
davyaxl 2009-04-10
  • 打赏
  • 举报
回复
只要涉及到这种数据收发程序,不管是串口还是网口,都应该考虑接收端无法一次接收所有数据的问题。
我以前的做法是接收线程将接收到的数据一直追加到buf后面,由另一个子程序去分析处理该buf的内容。不过要注意线程同步问题,避免接收线程和数据处理线程同时操作buf.
56xue 2009-04-10
  • 打赏
  • 举报
回复
我觉得是数据传输可能有延迟,时钟怎么定都不可能完全达到一个周期刚好收一条完整的数据
你都知道定长了,还不好办,检查strRecv长度,到这么多时就处理显示
当然要注意CRC效验正确才处理,不然这一条就丢掉,等下一条

16,549

社区成员

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

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

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