基于OOP方法编写串口助手类

串口知识回顾:

1常见的串口

(1)RS-232接口:通常适合于数据传输频率在0~20000bps范围的通信。在PC机上通常都是COM串口。

不足:抗干扰能力差,通信距离短,速率低。

(2)RS-422/485接口:传输速度和通信距离变得非常远(1200m),并且在一条平衡总线上连接最多10个接收器。

2串行通信的基本参数

(1)波特率:是指串行通信中每1秒所传送的数据位数,单位是bps。也就是传输速度。

比如发送一个字符需要8位,如果波特率是4800bps传输,则每秒可以传输600个字符。

(2)起始位:起始位表示字符传输的开始。在通信线上,没有数据传输时处于逻辑“1”状态。当发送一个字符数据时,首先发出一个“0”信号,这个逻辑低电平就是起始位。接收设备检测到低电平后,就准备开始接收。

(3)数据位:当接收设备收到起始位后,紧挨着的就是数据位,数据位的个数可以是5、6、7、8位。在字符串数据传送的过程中,数据位从最低有效位开始传输。

(4)奇偶校验位:数据位发送完以后,就可以发送奇偶校验位,用于有限差错的检查。通信双方需要约定一致的奇偶校验方式。

(5)停止位:在奇偶校验位或者数据位(无奇偶校验位时)之后是停止位,它可以是1位,1.5位或者2位,停止位是数据结束的标志。

3异步传输中的一帧数据组成

【发送端】->停止位(1-2)->奇偶校验位(1位)->数据位(7-8个)->起始位(0)【接收端】

串口助手类的设计


准备工作:准备一个进制转换类助手,能够完成十进制、16进制、汉字、英文、byte[]之间的转换。

新建一个HelpClass文件夹,并新建一个进制转换类:



using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows;


namespace SerialPortHelperDemo

{

    /// 

    /// 16进制使用的隔离符枚举

    /// 

    public enum Enum16Hex

    {

        None,//无

        Blank,//空格

        OX,  //OX

        Ox   //Ox

    }


    /// 

    ///计算进制类助手

    /// 

    public class AlgorithmHelper

    {

        #region十进制转十六进制

        public string From10To16(int d)

        {

            string hex = "";

            if (d < 16)

            {

                hex = BeginChange(d);

            }

            else

            {

                int c;

                int s = 0;

                int n = d;

                int temp = d;

                while (n >= 16)

                {

                    s++;

                    n = n / 16;

                }

                string[] m = new string[s];

                int i = 0;

                do

                {

                    c = d / 16;

                    m[i++] = BeginChange(d % 16);//判断是否大于10,如果大于10,则转换为A~F的格式

                    d = c;

                } while (c >= 16);

                hex = BeginChange(d);

                for (int j = m.Length - 1; j >= 0; j--)

                {

                    hex += m[j];

                }

            }

            return hex;

        }

        //判断是否为10~15之间的数,如果是则进行转换

        public string BeginChange(int d)

        {

            string hex = "";

            switch (d)

            {

                case 10:

                    hex = "A";

                    break;

                case 11:

                    hex = "B";

                    break;

                case 12:

                    hex = "C";

                    break;

                case 13:

                    hex = "D";

                    break;

                case 14:

                    hex = "E";

                    break;

                case 15:

                    hex = "F";

                    break;

                default:

                    hex = d.ToString();

                    break;

            }

            return hex;

        }

        #endregion


        #region其他函数【16进制中的隔离符处理】


        /// 

        ///把16进制隔离符转换成实际的字符串

        /// 

        /// 16进制隔离符枚举

        /// 

        private string AddSplitString(Enum16Hex enum16)

        {

            switch (enum16)

            {

                case Enum16Hex.None:

                    return "";

                case Enum16Hex.Ox:

                    return "0x";

                case Enum16Hex.OX:

                    return "0X";

                case Enum16Hex.Blank:

                    return " ";

                default:

                    return "";

            }

        }

        /// 

        ///去掉16进制字符串中的隔离符【 如:" ", "0x", "0X"】

        /// 

        /// 需要转换的字符串数据

        /// 

        private string DeleteSplitString(string inString)

        {

            string outString = string.Empty;

            string[] delArray = { " ", "0x", "0X" };

            if (inString.Contains(" ") || inString.Contains("0x") || inString.Contains("0X"))//存在隔离符

            {

                string[] str = inString.Split(delArray,

                    System.StringSplitOptions.RemoveEmptyEntries);//以隔离符进行转换数组,去掉隔离符,去掉空格。

                for (int i = 0; i < str.Length; i++)

                {

                    outString += str[i].ToString();

                }

                return outString;

            }

            else//不存在隔离符就直接返回

            {

                return inString;

            }

        }

        #endregion


        #region汉字、英文、纯16进制数、byte[]之间的各种转换方法


        /// 

        ///字符串转换成16进制

        /// 

        /// 

        /// 

        /// 

        public string StringTo16(string inSting, Enum16Hex enum16)

        {

            string outString = "";

            byte[] bytes = Encoding.Default.GetBytes(inSting);

            for (int i = 0; i < bytes.Length; i++)

            {

                int strInt = Convert.ToInt16(bytes[i] - '\0');

                string s = strInt.ToString("X");

                if (s.Length == 1)

                {

                    s = "0" + s;

                }

                s = s + AddSplitString(enum16);

                outString += s;

            }

            return outString;

        }

        /// 

        ///字符串转换成byte[]

        /// 

        /// 

        /// 

        public byte[] StringToBtyes(string inSting)

        {

            inSting = StringTo16(inSting, Enum16Hex.None);//把字符串转换成16进制数

            return From16ToBtyes(inSting);//把16进制数转换成byte[]

        }

        /// 

        ///把16进制字符串转换成byte[]

        /// 

        /// 

        /// 

        public byte[] From16ToBtyes(string inSting)

        {

            inSting = DeleteSplitString(inSting);//去掉16进制中的隔离符

            byte[] stringByte = new byte[inSting.Length / 2];

            for (int a = 0, b = 0; a < inSting.Length; a = a + 2, b++)

            {

                try

                {

                    string str = inSting.Substring(a, 2);

                    stringByte[b] = (byte)Convert.ToInt16(str, 16);

                }

                catch (Exception ex)

                {

                    throw new Exception("输入的数据不是纯16进制数!  参考错误信息:" + ex.Message);

                }

            }

            return stringByte;

        }

        /// 

        ///把16进制字符串转换成英文数字和汉字混合格式

        /// 

        /// 需要转换的16进制字符串

        /// 

        public string From16ToString(string inSting)

        {

            inSting = DeleteSplitString(inSting);

            return Encoding.Default.GetString(From16ToBtyes(inSting));

        }

        /// 

        ///把byte[]转换成String

        /// 

        /// 需要转换的byte[]

        /// 隔离符

        /// 

        public string BytesToString(byte[] bytes, Enum16Hex enum16)

        {

            return From16ToString(BytesTo16(bytes, enum16));

        }

        /// 

        /// byte[]转换成16进制字符串

        /// 

        /// 需要转换的byte[]

        /// 

        /// 

        public string BytesTo16(byte[] bytes, Enum16Hex enum16)

        {

            string outString = "";

            for (int i = 0; i < bytes.Length; i++)

            {

                if (bytes[i].ToString("X").Length < 2)//16进制数为一位时前面填充0

                {

                    outString += "0" + bytes[i].ToString("X") + AddSplitString(enum16);//转成16进制数据

                }

                else

                {

                    outString += bytes[i].ToString("X") + AddSplitString(enum16);//转成16进制数据

                }

            }

            return outString;

        }

        /// 

        ///把byte[]直接转换成字符串,直接以2进制形式显示出来。

        /// 

        /// 

        /// 

        public string BytesTo2String(byte[] bytes, Enum16Hex enum16)

        {

            string outString = "";

            for (int i = 0; i < bytes.Length; i++)

            {

                string tempString = Convert.ToString(bytes[i], 2);

                if (tempString.Length != 8)

                {

                    string add0 = "";

                    for (int j = 0; j < 8 - tempString.Length; j++)

                    {

                        add0 += "0";

                    }

                    outString += add0 + tempString + AddSplitString(enum16);

                }

                else

                {

                    outString += tempString + AddSplitString(enum16);

                }

            }

            return outString;

        }


        /// 

        ///把字符串传进来,输出一个byte数组【可以把此byte数组直接发送到串口中】

        /// 

        /// 要转换的字符串

        /// 是否已经是16进制数据,true时已经是(已经转换好的数据),false时不是(需要内部转换)

        /// 输出一个byte数组

        public byte[] StringToBytes(string inString, bool is16)

        {

            if (is16)

            {

                return From16ToBtyes(inString);

            }

            else

            {

                return StringToBtyes(inString);

            }

        }


        #endregion

    }

}

1、新建一个串口类SerialPortHelper.cs

namespace SerialPortHelper

{

    /// 

    ///串口助手通用类

    /// 

    public class SerialPortHelper

    {

    }

}

2、引入串口所使用的命名空间

using System.IO.Ports;

3.设置相关的属性


(1)属性:串口操作对象。

/// 

        ///创建一个串口操作对象

        /// 

        private SerialPort serialPort = null;

        public SerialPort SerialPortObject

        {

            get { return serialPort; }//只读

        }

(2)属性:获取计算机串口列表。

/// 

        ///获取当前计算机上可用的端口列表【只读】

        /// 

        public string[] PortNames

        {

            get { return System.IO.Ports.SerialPort.GetPortNames(); }

        }

(3)属性:进制转换对象。

        /// 

        ///进制转换对象属性

        /// 

        private AlgorithmHelper algorithmHelper = null;

        public AlgorithmHelper AlgorithmHelperObject

        {

            get { return algorithmHelper; }

        }

(4)构造方法:完成属性初始化和串口参数默认值。

        /// 

        ///构造方法中初始化相关数据

        /// 

        public SerialPortHelper()

        {

            this.serialPort = new SerialPort();//创建串口实例

            this.algorithmHelper = new AlgorithmHelper();//创建进制转换对象


            //串口基本参数初始化

            this.serialPort.BaudRate = 9600;

            this.serialPort.Parity = System.IO.Ports.Parity.None;//校验位默认NONE

            this.serialPort.DataBits = 8;//数据位默认8位

            this.serialPort.StopBits = System.IO.Ports.StopBits.One;//停止位默认1位

        }

4.设置相关的方法


(1)打开或关闭串口(端口)。

       #region打开或关闭串口

        /// 

        ///根据端口名称打开端口或关闭端口

        /// 

        /// 端口名称

        /// 操作状态:1表示打开,0表示关闭

        /// 返回当前端口的打开状态true或false

        public bool OpenSerialPort(string portName, int status)

        {

            if (status == 1)

            {

                this.serialPort.PortName = portName;//只有在端口没有打开的时候,才能设置名称。

                this.serialPort.Open();

            }

            else

            {

                this.serialPort.Close();

            }

            return this.serialPort.IsOpen;//返回串口打开的状态

        }

 #endregion

(2)枚举限制格式

   #region发送格式选择枚举


    /// 

    ///发送格式选择

    /// 

    public enum SendFormat

    {

        Hex,//十六进制

        String

    }


    #endregion


(3)编写发送数据的方法。

        #region发送数据


        /// 

        ///判断十六进制字符串hex是否正确

        /// 

        /// 十六进制字符串

        /// true:正确,false:不正确

        private bool IsIIlegalHex(string hex)

        {

            return System.Text.RegularExpressions.Regex.IsMatch(hex, @"([^A-Fa-f0-9]|\s+?)+");

        }

        /// 

        ///发送数据(可以是16进制,也可以是字符串)

        /// 

        /// 要发送的数据

        /// 发送的数据格式

        public void SendData(string data, SendFormat format)

        {

            if (!this.serialPort.IsOpen)

            {

                throw new Exception("端口未打开!请打开相关端口!");//让调用者处理

            }

            else

            {

                byte[] byteData;


                if (format == SendFormat.Hex)//如果是16进制

                {

                    if (this.IsIIlegalHex(data))

                    {

                        byteData = algorithmHelper.From16ToBtyes(data);//将16进制转换成byte[]数组

                    }

                    else

                    {

                        throw new Exception("数据不是16进制格式!");

                    }

                }

                else  //发送字符串

                {

                    byteData = algorithmHelper.StringToBytes(data, false);

                }

                this.serialPort.Write(byteData, 0, byteData.Length);//发送数据(数据,从0开始,结束位置)

            }

        }


        #endregion

(4)编写接收数据的方法。

       #region接收数据


        /// 

        ///串口接收数据

        /// 

        /// 

        public byte[] ReceiveData()

        {

            //定义一个接收数组,获取接收缓冲区数据的字节数

            byte[] byteData = new byte[this.serialPort.BytesToRead];

            //读取数据(存储区,起始位置,终点位置)

            this.serialPort.Read(byteData, 0, serialPort.BytesToRead);

            return byteData;

        }


        #endregion

5.串口助手UI设计和任务编写

你可能感兴趣的:(基于OOP方法编写串口助手类)