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




posted on 2013-05-17 19:44  月神苍龙  阅读(2252)  评论(0编辑  收藏  举报