串口通信接受处理速度跟不上发送速度的问题怎样解决??

pingyuanwei 2011-04-27 09:14:10
我的串口程序用的是一个串口类,编译环境Visual C++ 6.0。

串口类中定义用户消息
#define WM_COMM_RXCHAR WM_USER+7 // A character was received and placed in the input buffer.

在主对话框类头文件中,声明函数:
afx_msg LONG OnCommunication(WPARAM ch,LPARAM port);

在主对话框类源文件中,完成消息映射:
ON_MESSAGE(WM_COMM_RXCHAR,OnCommunication)

消息处理函数:
LONG CSCommDlg::OnCommunication(WPARAM ch,LPARAM port)
{

完成字符的接收及一帧数据的处理
......

}

我的数据的帧结构是:
在此举个例子说明:"AA 55 00 00 04 00 03 "
其中"AA 55 "为帧头,"00 00 04 00"为数据位,转化为十进制代表1024,"03 "为校验,校验规则是把AA+55+00+00+04+00=103,取"03 "作为校验位.

我有一个如上结构帧的数据文件,该文件有3021帧.
现在的问题是当波特率选为38400bps时,接收端数据处理速度能够跟上发送速度(即能够同步),并且能数据能够实时的显示在对话框的画图区,实际接收帧数为3021帧;


但当波特率选为115200bps时,接收端数据处理速度就不能跟发送速度,当接收到1700多帧时局出现误码丢帧现象;
问题应该是由于接收处理速度慢,造成读缓冲区没读完,就被发送来的新的数据所覆盖,从而出现误码丢帧现象。
而要求波特率在460800bps时,该程序仍能工作,即实时显示数据波形。

怎样解决这个问题呢?想听听大家的意见。在此先谢过。
...全文
2422 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenjiawei007 2011-04-29
  • 打赏
  • 举报
回复
你可以做个监测 。
int nMaxBufferSize = 1024;

int nlen = readfile返回读取长度,

if(nlen == nMaxBufferSize )
printf("warning Buffer Size not enough");

以此来扩大你的缓冲大小,因为线程读取串口的开销比较大,我觉得1024的缓存可能不够大。

其实你可以根据你的波特率大小来选择你的buffer大小,这样灵活些。
chenjiawei007 2011-04-29
  • 打赏
  • 举报
回复
你读串口数据,然后进行自己的数据拼接吗?还是直接播放?

如此快的速度,你用1024的缓存接受,你可以跟下断点,基本都是1024吧?

如果出现了1024那基本就是满出了,你可以设置的大一点,1024才1K的,

根据你数据流的大小增大缓存,不知道缓存上限是多少,你开大点,再尝试下。
pingyuanwei 2011-04-29
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 chenjiawei007 的回复:]
我们这硬件设备115200就是最高了,想紧紧通过串口提高到如此高的波特率有些难啊。

你的问题,是不是串口接收端根本来不及接受呢?你的串口缓冲区开辟的是多大?

如此快的速度,你缓冲区太小,导致溢出,你线程去取出串口数据时其实已经可能丢失了。
[/Quote]
我的串口板波特率最高可达到921600bps。
接收缓冲区大小为1024。
我是想实时处理这些数据并以波形图显示,达到发送与接收显示同步。
正如你说的,应该是来不及接收,有什么更好的解决方法吗?
chenjiawei007 2011-04-29
  • 打赏
  • 举报
回复
我们这硬件设备115200就是最高了,想紧紧通过串口提高到如此高的波特率有些难啊。

你的问题,是不是串口接收端根本来不及接受呢?你的串口缓冲区开辟的是多大?

如此快的速度,你缓冲区太小,导致溢出,你线程去取出串口数据时其实已经可能丢失了。
pingyuanwei 2011-04-29
  • 打赏
  • 举报
回复
回复:zhxingway
谢谢你的建议!
pingyuanwei 2011-04-29
  • 打赏
  • 举报
回复
回复miy_autumn:
你想问的是判断文件接收完成的判断吗?如果是这样,
串口类中定义用户消息
#define WM_COMM_TXEMPTY_DETECTED WM_USER+9 // The last character in the output buffer was sent.


在主对话框类头文件中,声明函数:
afx_msg LONG OnFileSendingEnded(WPARAM wParam,LPARAM port);

在主对话框类源文件中,完成消息映射:
ON_MESSAGE(WM_COMM_TXEMPTY_DETECTED,OnFileSendingEnded)

消息处理函数:
LONG CSCommDlg::OnFileSendingEnded(WPARAM wParam,LPARAM port)
{

......

}
zhxingway 2011-04-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zgl7903 的回复:]
1改协议 每帧多发一些数据, 以降低头部和校验开销
2开线程接受和处理,通过消息处理的效率很低
[/Quote]

你这个要求比较严格呀,找个多线程的串口通信控件或方式就可以了。

搜索“多线程串口通信”
pingyuanwei 2011-04-29
  • 打赏
  • 举报
回复
回复zgl7903:能稍微具体说一下你的第二条方案吗?谢谢
pingyuanwei 2011-04-29
  • 打赏
  • 举报
回复
回复vcf_reader:
我提的问题的确不清楚。
1、帧结构不是我定义的,是一个确定的帧结构,不能由我更改。
2、3021帧在这里我想说明的是:当波特率为19200bps时,发送端发送3021帧的数据文件大约耗时30s(计算式为3021*21*9/19200=29.73s,停止位为1位,校验位无)左右,此时,接收端要想和发送端同步,每帧的处理速度10ms左右,程序可以正常同步;
当波特率为115200bps时,发送端发送3021帧的数据大约耗时5s左右,此时,接收端要想和发送端同步,每帧的处理速度大约1.65ms,程序跟不上发送速度,出现误码丢帧现象。
当波特率为460800bps时,发送端发送3021帧的数据大约耗时1.24s左右,此时,接收端要想和发送端同步,每帧的处理速度大约0.41ms,程序跟不上发送速度,出现误码丢帧现象。
Forrest 2011-04-29
  • 打赏
  • 举报
回复
楼主是怎么判断 串口 一帧数据接收完成 的 ? 就是以仕么作为接收完整条件?

我也在做串口 ?麻烦楼主分享一下 ! 非常 谢谢1
zgl7903 2011-04-29
  • 打赏
  • 举报
回复
1改协议 每帧多发一些数据, 以降低头部和校验开销
2开线程接受和处理,通过消息处理的效率很低
vcf_reader 2011-04-28
  • 打赏
  • 举报
回复
不明白楼主想说什么?每帧才 7 个字节。
假如每秒钟传一帧,怎么可能来不及收呢?
如果你是用Windows的定时器定时发送,发送间隔也将至少达到 55 ms。

每间隔55毫秒才发送7个字节,不论波特率设置成多少,都来得及接收。

另外也想告诉楼主,你那个3021帧数据根本不是用来说事的。
打个比方说,有1万斤粮食扛回家,你扛得动吗?反正我是扛得动的,3岁小孩都扛得动,每次扛1斤就是了。

所以我根本不明白楼主到底想说什么。

我实战过,9600 bps 的情下,每55毫秒可以成动的发送和接收一帧数据。每帧数据大概是500字节!!!!

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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