串口通讯最痛苦的在于无法深入了解串口内部的规则,只能调用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<len-2;i++)
{
if((tsend.Text[i]<='9')&&(tsend.Text[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<j;k++)
{
datarev[k] = datat[k];
}
return datarev;
}
private bool ishex(char x)
{
bool re = false;
if((x<='9')&&(x>='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;
}
浙公网安备 33010602011771号