串口接收数据与鼠标移动事件冲突怎么办

blue2moon 2013-05-20 03:37:57
我在C#中用serialport控件实现了一个串口小程序,具体如下:
1.该程序每100ms发出一个命令给外部接收设备,由一个timer控制
2.设置串口接收的ReceivedBytesThreshold为1,即每接收到一个字节就触发DataReceive事件,DataReceive事件代码如下:
public void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
long lExecuteTime = 0;

// modified trigger condition to maximum time
serialPort1.ReceivedBytesThreshold = serialPort1.ReadBufferSize;

int curbyte = serialPort1.ReadByte();

recvbuf[iCurPos++] = (byte)curbyte;

if (curbyte == 0x7E) // received a completed response
{
EndTime = DateTime.UtcNow;
timer_timeout.Enabled = false;

lExecuteTime = (EndTime.Ticks - StartTime.Ticks) / 10; // change to us
lb_time.Text = lExecuteTime.ToString() + " us";

InforDisplay(recvbuf, iCurPos);
iCurPos = 0;
}
else if (iCurPos > 79)
{
txtBox_Err.Text += "Error: Receive buffer over flow!\r\n";

iCurPos = 0;
}

// recover trigger condition to 1
serialPort1.ReceivedBytesThreshold = 1;
}

这其中调用了一个函数InfoDisplay, 这个函数用来将接收到的数据显示到界面上。

3. 问题:程序运行之后,命令收发正常,显示也正常;但是当鼠标在窗体上移动时,串口数据就会有丢失的可能,鼠标移动的越快,出错几率越大。我推断,鼠标移动时,程序要响应mousemove事件(我并没有处理这个事件),导致来不及响应datareceive事件,造成数据丢失

4. 从网上查,用多线程可以解决这个问题,但是我不知道该怎么设计这个多线程,请大家指点

多谢
...全文
610 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
shenlanql 2013-05-20
  • 打赏
  • 举报
回复
为啥非要1个字节就触发事件呢?线程读取 串口中有多少读多少,直到读不到,然后开始处理数据。 如果使用线程调用界面刷新,需要Invoke方法。 个人认为,你不用设置1字节 触发接收事件 就OK的。
vpjian 2013-05-20
  • 打赏
  • 举报
回复
其实这个和你鼠标没有任何关系,这样使用是一定有问题的。 接收事件里不要做处理,只接收就好了,接收事件中有比较耗时的处理逻辑都会导致丢数据。处理要另开线程。具体原因不清楚,我觉得使用事件接收后,串口软件缓冲都无效了,无论设置多大的缓冲,都会丢数据。 txtBox_Err.Text += "Error: Receive buffer over flow!\r\n";这个有问题,不要操作UI控件,接收事件不在主线程中,没有同步非UI线程操作UI控件会出错的。 最简单的使用方法是使用一个Timer 定期检查串口有没有数据,如果有的话就读出来处理。

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (serialPort1.BytesToRead > 0)
            {

                byte[] buffer = new byte[serialPort1.BytesToRead];
                serialPort1.Read(buffer, 0, buffer.Length);
                // 处理........
            }
        }
gomoku 2013-05-20
  • 打赏
  • 举报
回复
MSDN
...不保证对接收到的每个字节引发 DataReceived 事件。 使用 BytesToRead 属性确定缓冲区中剩余的要读取的数据量
http://msdn.microsoft.com/zh-cn/library/system.io.ports.serialport.datareceived.aspx 你的响应函数每次只读一个字节,是可能会"丢失数据"。 建议按照MSDN的方法进行改进。
江湖评谈 2013-05-20
  • 打赏
  • 举报
回复
代码没有,怎么分析?
blue2moon 2013-05-20
  • 打赏
  • 举报
回复
进一步的测试,只要是鼠标移动,无论在不在这个窗体上,都会对串口接收数据造成影响。或者说,只要是操作了本台PC上的任何其他程序,都会对串口接收造成影响!

110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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