博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 串口通讯的数据丢失和同步异步问题
阅读量:5068 次
发布时间:2019-06-12

本文共 5333 字,大约阅读时间需要 17 分钟。

串口通讯最痛苦的在于无法深入了解串口内部的规则,只能调用c#提供的SerialPort类,但是使用的时候也出现了很多问题,有的是自身的有的是由于不了解造成的。

首先SerialPort类提供了很多很好的方法,对于读写都很有帮助,但是有的读是同步,有的是异步,同步就是和主程序保持一致,只有运行完了ReadByte之后才能运行程序之后的代码,异步就是重新开启一个线程来处理这些问题,主程序不受到干扰,继续运行。

serialPort中有6个读的方法:

Read();
                           ReadLine()
                           ReadByte();
                           ReadChar();
                           ReadExisting();
                           ReadTo();

ReadTo和ReadExisting是异步读取,剩下的都是同步读取。

其次就是一般来说对于这种串口的读取我们会用到多线程,所以要用委托来改变窗口中的一些值,所以就要用到

this.Invoke(new weituo(Setinfo));

Invoke和BeginInvoke 在http://www.cnblogs.com/mashang/archive/2009/08/01/1536730.html解释的很清楚了,Invoke是同步,后面的是异步。

我最开始就是使用了BeginInvoke ,所以总会出现读取不到数据的情况,就是因为委托方法执行的太快了,所以导致了数据的丢失,显示不出来了,如果你也碰到了这种问题,也可以在

while (true)

            {
                //resultLength = _serialPort.Read(result, 0, result.Length);
                //legheit = resultLength;
                //string Currentword = Encoding.UTF8.GetString(result, 0, resultLength);
                byte[] data = new byte[1];
                data[0]=(byte)_serialPort.ReadByte();
                ss = ToHexString(data);
                this.BeginInvoke (new weituo(Setinfo));//Invoke这个更好
               Thread.Sleep(500);

也可以在读取函数中加上Sleep停顿一段时间就行了,但是这只是权宜之计,还是使用同步最好了。

如果你也是发现数据出现了丢失情况,多半是这个问题,因为串口有缓冲区,如果不是数据被读取出去了,一般来说数据是不会自己清空的。

接下来就是因为串口通信多半是16进制的通讯方式,所以把找到了一些16进制转换函数贴出来:

public static char[] hexDigits = {             '0',     '1',     '2',     '3',     '4',     '5',     '6',     '7',             '8',     '9',     'A',     'B',     'C',     'D',     'E',     'F'};        public static string ToHexString(byte[] bytes)        {            char[] chars = new char[bytes.Length * 3];            for (int i = 0; i < bytes.Length; i++)            {                int b = bytes[i];                chars[i * 3] = hexDigits[b >> 4];                chars[i * 3 + 1] = hexDigits[b & 0xF];                chars[i * 3 + 2] = ' ';            }            return new string(chars);        }
以上是将读取到了byte类型转换成16进制并以string形式输出的函数。

还有一些大家自己看吧都很不错:

private byte[] getdata()        {            int len = tsend.Text.Length;            int j = 0;            byte []datat = new byte[len];            for(int i=0;i
='0')&&(tsend.Text[i+1]>='0')&&(tsend.Text[i+1]<='9')&&(tsend.Text[i+2]<=' ')) { datat[j] = (byte)((tsend.Text[i]-'0')*16+(tsend.Text[i+1]-'0')); j++; } } byte[] datarev = new byte[j]; for(int k=0;k
='0')) { re = true; } else if((x<='F')&&(x>='A')) { re = true; } else if ((x <= 'f') && (x >= 'a')) { re = true; } return re; } private byte[] GetByteData(string s) { byte[] data = new byte[s.Length / 2]; for (int i = 0; i < s.Length / 2; i++) { if (s[i * 2] <= '9') { data[i] = (byte)((s[i * 2] - '0') * 16); } else if (s[i * 2] <= 'f' && s[i * 2] >= 'a') { data[i] = (byte)((s[i * 2] - 'a' + 10) * 16); } else if (s[i * 2] <= 'F' && s[i * 2] >= 'A') { data[i] = (byte)((s[i * 2] - 'A' + 10) * 16); } if (s[i * 2 + 1] <= '9') { data[i] = (byte)(data[i] + (byte)((s[i * 2 + 1] - '0'))); } else if (s[i * 2 + 1] <= 'f' && s[i * 2 + 1] >= 'a') { data[i] = (byte)(data[i] + (byte)((s[i * 2 + 1] - 'a' + 10))); } else if (s[i * 2 + 1] <= 'F' && s[i * 2 + 1] >= 'A') { data[i] = (byte)(data[i] + (byte)((s[i * 2 + 1] - 'A' + 10))); } } return data; } private string GetHexString(string str) { int len = str.Length; string datarev = ""; int i=0; for(i=0;i<(len)/3;i++) { if ((ishex(str[3 * i])) && (ishex(str[3 * i + 1])) && (str[3 * i + 2] == ' ')) { datarev = datarev + str[3 * i] + str[3 * i + 1]; } else if ((ishex(str[3 * i])) && (ishex(str[3 * i + 1])) && (3 * i + 2 == len)) { datarev = datarev + str[3 * i] + str[3 * i + 1]; } } if(len-i*3==2) { if ((ishex(str[len-1])) && (ishex(str[len-2]))) { datarev = datarev + str[len-2] + str[len-1]; } } return datarev; } private bool ishexstring(string strl) { string del = " "; string str = strl.Trim(del.ToCharArray()); int len = str.Length; bool re = false; for (int i = 0; i < (len) / 3; i++) { if ((ishex(str[3 * i])) && (ishex(str[3 * i + 1])) && (str[3 * i + 2] == ' ')) { re = true; } else if ((ishex(str[3 * i])) && (ishex(str[3 * i + 1])) && (3 * i + 2 == len)) { re = true; } else { re = false; } } return re; }

转载于:https://www.cnblogs.com/yueshen-blog/archive/2013/05/17/3182774.html

你可能感兴趣的文章
JAVA第九次作业
查看>>
字符串反转,如将 '12345678' 变成 '87654321'
查看>>
Docker 安装 PHP+Nginx
查看>>
(转)MySQL排序原理与案例分析
查看>>
Miller-Rabin素数测试算法(POJ1811Prime Test)
查看>>
子路由配置
查看>>
grep和egrep正则表达式
查看>>
C语言中system函数用法解释
查看>>
Jsch初步
查看>>
[转] HBase异常:hbase-default.xml file seems to be for an old version of HBase
查看>>
C# Windows - SDI和MDI应用程序
查看>>
SDWebImage 加载显示 WebP 与性能问题
查看>>
java正则表达式(基本语法)
查看>>
入驻博客园
查看>>
Microsoft Visual Studio 2015 下载、注册、安装过程、功能列表、问题解决
查看>>
机器学习 machine learning
查看>>
c++ primer读书笔记之c++11(三)
查看>>
小结:c++中的new、operator new和placement new
查看>>
NAT穿墙小记
查看>>
Mysql之创建和操纵表
查看>>