zoukankan      html  css  js  c++  java
  • C# + .net下使用serialPort做串口开发 1

         在.net下使用serialPort做串口通信开发,在环境状态比较好的情况下还是比较容易的。我们可是使用serialPort.write(),将组织好的byte数组写入到串口中。也可以通过serialPort的DataReceived 事件来触发读取。

        但是,如果通信情况不好,或者比特率较低的情况下,在接受的时候会出现很多情况,当触发一次Datareceived的事件,可能是收到了全部数据帧,也可能只收到了半个帧,第二次触发的时候,也许就是完整的一个帧了,这样就给写程序带来的N多问题。无法通过DataReceived事件来触发读取了。

       最后,没办法,想出一个变通的手法,因为我们可以知道serialPort中当前输入缓冲区的内容的大小,BytesToRead,我们可以在一段时间间隔内,获取这个值,如果它不改变了,说明后面没有数据了,也就是下位机发送完成。这个时间是和serialPort的波特率有关的。

      波特率的单位是 bps 就是 bit 每秒,所以换成字节的话,得除以8,在考虑上完成字节的头尾等,完成的一个字节是11bit,所以,我们就可以换算出 (波特率/11) 得到一秒可以发送的字节数,然后我们在拿 1000ms除以这个值,就可以得到 一个字节需要多少毫秒来发送: 1000/(波特率/11) 。

      理论上,我们等待这个时间,就可以获取到下一个字节了,但是考虑到实际情况,可能需要适当的延长时间,所以,我们可是适当的增加等待时间。

      我们可以使用timer来实现;

    timer1.Interval = (1000 / (serialPort1.BaudRate / 11)) + 20;
    int timer2Bytes = -1;
    private void timer2_Tick(object sender, EventArgs e)
    {
    int newBytes = serialPort1.BytesToRead;
    if (timer2Bytes == newBytes && newBytes != 0)
    {
    byte[] data = new byte[newBytes];
    serialPort1.Read(data,
    0, data.Length);
    if (data != null)
    {
    textBoxResult.Text
    += BitConverter.ToString(data) + "\r\n";
    Application.DoEvents();
    }
    timer2Bytes
    = -1;

    }
    else
    {
    timer2Bytes
    = newBytes;
    }
    }

    OK,这样就基本完成了,但是依然还是有可能出现接受的帧不完整的情况,这个时候可以尝试在发送一次命令读取一次。这个好处是可以读取到通信时间,只需要在里面添加一个计时器,比如在 else下 添加 time += timer2.Interval ;  但是这个时间很不准确,不知道为什么。

    最后一个比较好的方法就是:通过bytesToRead的长度来确定是否接受完成,并指定超时时限,这样的好处是,能保证接受到的就是长度符合的,否则就继续等,知道超时,可是,问题是必须事先知道,我读取的长度将会是多少,这对程序的扩展性等,都引来很多问题。纠结中。

    继续研究如何比较好的实现,并精确的记录下通信时间;

  • 相关阅读:
    SoapUI 使用笔记
    git 使用笔记(二)
    git 使用笔记(一)
    jquery 拓展
    hdu 1024 Max Sum Plus Plus (DP)
    hdu 2602 Bone Collector (01背包)
    hdu 1688 Sightseeing (最短路径)
    hdu 3191 How Many Paths Are There (次短路径数)
    hdu 2722 Here We Go(relians) Again (最短路径)
    hdu 1596 find the safest road (最短路径)
  • 原文地址:https://www.cnblogs.com/lingfengchencn/p/serialPort.html
Copyright © 2011-2022 走看看