c# 串口通讯如何多次重复发送一帧数据,并且保证发送和回复每一帧数据的顺序正确

Chouna 发布于 2012/07/31 00:21
阅读 5K+
收藏 1
C#

C#串口通讯时,已经实现正确发送数据包,正确得到回复;如何实现若发送失败最多发送5次,并且发送多个数据包时,发送数据和回复数据在界面的显示不串行;我尝试做过,会出现数据串行,或者一帧数据已成功发送、回复还继续发送的情况,如图

我的大概思路如下:

// 每帧数据发送出去后,等待500ms接收返回的数据,若无信息返回,则连续发送5次,5次都失败则终止操作

private void SendData(string[] hexString)
{
    for (int i = 0; i < 6; i++)
    {
        if (i < 5)
        {
            if (!IsReceived)
            {
                WriteTable(hexString[0].Trim(), 2, 16, 0);
                System.Threading.Thread.Sleep(500);  //暂停500ms
            }
            else
            {
                IsReceived = false;
                break;
            }
        }
        else
        {
            MessageBox.Show("发送错误,无回应数据");
            return;
        }
    }

    for (int i = 0; i < 6; i++)
    {
        if (i < 5)
        {
            if (!IsReceived)
            {
                WriteTable(hexString[1].Trim(), 18, 0, 1);
                System.Threading.Thread.Sleep(500);  //暂停500ms
            }
            else
            {
                IsReceived = false;
                break;
            }
        }
        else
        {
            MessageBox.Show("发送错误,无回应数据");
            return;
        }
    }
}


private void WriteTable(string hexString, int dataLen, int startAddress, int tableType)
{   
    byte[] package = new byte[dataLen];
    int k = 0;

    package[0] = 0xAA;//帧头

    //帧数据
    byte[] bytes = Common.StrToToHexByte(hexString);
    foreach (byte b in bytes)
    {
        package[k++] = b;
    }
   
    //数据包组码
    。
    。
    。           
   
    if (!mycomm.IsOpen)
    {
        MessageBox.Show("串口没有打开,请打开串口!");
        return;
    }
    string data = ByteArrayToHexString(package);
    textBoxSend.AppendText("发送>>>:" + data + "\n");

    mycomm.Write(package, 0, package.Length);//向串口发送一包的数据 */
}

private void ReadTable(object sender, SerialDataReceivedEventArgs e)
{
    try
    {
        string errorInfo = "回复出错";
        int n = mycomm.BytesToRead;
        byte[] buf = new byte[n];
        mycomm.Read(buf, 0, n);//读取缓冲数据
       
        //<协议解析>
        bool data_1_catched = false;
        //1.缓存数据
        buffer.AddRange(buf);
        //2.完整性判断
        while (buffer.Count >= 4)
        {
            //2.1 查找帧头
            if (buffer[0] == 0xAA)
            {
                。。
                。。
                。。
                data_1_catched = true;
            }
            else
            {
                errorInfo = "帧头错误";
            }
        }

        if (data_1_catched)
        {
            //显示回复的数据
            this.textBoxSend.AppendText("<<<回复:" + ByteArrayToHexString(binary_data_1) + "\n\n");
            this.textBoxSend.AppendText("\n");
           
            //这个变量表示是否接收到数据,决定是否重复发送数据,要是改行代码放在该if块的第一行,得到的结果不一样,我猜想是因为显示回复的数据时占用了时间,这个如何设置更合理???
            IsReceived = true;
        }
        else
        {
            this.textBoxSend.AppendText("<<<回复:" + errorInfo + "\n\n");
        }          
    }
    catch
    {
        MessageBox.Show("接受数据时出错");
        return;
    }
}

加载中
0
樂
如果能加一位校验位就好了,通过这一校验位就能判断出来返回的数据是否串行了
0
Chouna
Chouna

引用来自“樂”的答案

如果能加一位校验位就好了,通过这一校验位就能判断出来返回的数据是否串行了
我已经加入校验码了,只是在我给出的代码里没有体现出来
0
Lunar_Lin
Lunar_Lin
典型的基于流的串行通信  都可以参考tcp的处理方式.
1. 加包头指明长度, 包头要含包头校验码, 这几乎是稳定收发 必须要做.   2. 加最简单的校验码  3. 链接,状态机.
Lunar_Lin
Lunar_Lin
平常直接读串口得到的一个包是: 底层的串口芯片能靠一定时间间隔无数据而帮你截的一个包出来, 但这不可靠,不能作为逻辑分包的依据. 毕竟对方CPU处理发包的速度, 远不是串口这种IO能比的. TCP作为该类通信的成熟代表, 其设计原理值得参考借鉴.
返回顶部
顶部