串口通讯最痛苦的在于无法深入了解串口内部的规则,只能调用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; }