zoukankan      html  css  js  c++  java
  • C# 串口操作系列(4) -- 协议篇,文本协议数据解析(转)

    如何:在十六进制字符串与数值类型之间转换(C# 编程指南)

    https://msdn.microsoft.com/zh-cn/library/bb311038.aspx

    如何:将字符串转换为数字(C# 编程指南)

    https://msdn.microsoft.com/zh-cn/library/Bb397679.aspx

    数字和字符串转换:

    https://msdn.microsoft.com/zh-cn/library/zh1hkw6k.aspx

    c# 串口接收北斗定位数据

    http://download.csdn.net/detail/u010160393/5314593

    https://msdn.microsoft.com/zh-tw/library/system.io.ports.serialport.getportnames.aspx

    http://www.doc88.com/p-200225730359.html

    http://www.doc88.com/p-200225730359.html

    http://blog.sina.com.cn/s/blog_680942070101dfp7.html  串口

    上一篇已经介绍了协议的组成,一个协议,一般具有 :协议头+长度+数据+校验 , 文本格式可以直观的定义回车换行是协议的结尾,所以我们可以省略数据长度,增加协议尾。即: 协议头 + 数据 + 校验 + 数据尾 。

    文本方式的数据比较容易分析。如果数据缓存,可以考虑用StringBuilder。或是不缓存也可以。文本格式数据大多有换行结尾。稍微修改即可。例如分析常见的NMEA 0183格式的卫星坐标数据GGA。

    $GPGGA,121252.000,3937.3032,N,11611.6046,E,1,05,2.0,45.9,M,-5.7,M,,0000*77

    $              开始

    GPGGA     命令字

    *              结尾

    77            校验

    对上一篇代码稍作修改就可以了。例子不贴了。文本格式比较简单,只是为了内容完整。贴来做参考。只有分析的地方简化很多。

            void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                if (Closing) return;//如果正在关闭,忽略操作,直接返回,尽快的完成串口监听线程的一次循环
                try
                {
                    Listening = true;//设置标记,说明我已经开始处理数据,一会儿要使用系统UI的。
                    //文本格式比较简单,你可以死等。
                    string line = comm.ReadLine();//这就得到回车换行结尾的了。但是不是从头开始的就要检查了
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //<协议解析>
                    //因为恢复的代码在finally中。你可以直接的return
                    if(line[0] != '$') return;//虽然可能有点垃圾,但是数据不重要。直接丢弃就可以了。后续的都是对的
                    int star = line.IndexOf("*",1);
                    if(star == -1) return;
                    //根据$后面数据计算异或校验,并和*后面的数字对比。如果不同,也不进行分析。因为校验错误
                    
                    //当确定头尾存在,校验正确。就可以分析数据了。
                    //分析数据
                    ////因为要访问ui资源,所以需要使用invoke方式同步ui。
                    this.Invoke((EventHandler)(delegate
                    {
                        //判断是否是显示为16禁止
                        if (checkBoxHexView.Checked)
                        {
                            //依次的拼接出16进制字符串
                            foreach (byte b in buf)
                            {
                                builder.Append(b.ToString("X2") + " ");
                            }
                        }
                        else
                        {
                            //直接按ASCII规则转换成字符串
                            builder.Append(Encoding.ASCII.GetString(buf));
                        }
                        //追加的形式添加到文本框末端,并滚动到最后。
                        this.txGet.AppendText(builder.ToString());
                        //修改接收计数
                        labelGetCount.Text = "Get:" + received_count.ToString();
                    }));
                }
                finally
                {
                    Listening = false;//我用完了,ui可以关闭串口了。
                }
            }
    
            
    发现自己的不足,善于利用找到的方法去扬长避短。行动起来。
  • 相关阅读:
    LeetCode 42. Trapping Rain Water
    LeetCode 209. Minimum Size Subarray Sum
    LeetCode 50. Pow(x, n)
    LeetCode 80. Remove Duplicates from Sorted Array II
    Window10 激活
    Premiere 关键帧缩放
    AE 「酷酷的藤」特效字幕制作方法
    51Talk第一天 培训系列1
    Premiere 视频转场
    Premiere 暴徒生活Thug Life
  • 原文地址:https://www.cnblogs.com/rechen/p/5126738.html
Copyright © 2011-2022 走看看