【自己动手写上位机】串口通信

【自己动手写上位机】串口通信

简单介绍

串口通信是指采用串行通信协议(serial communication)在一条信号线上

将数据一个比特一个比特地逐位进行传输的通信模式。

串口通信最重要的参数是波特率数据位、停止位和奇偶校验

对于两个进行通信的端口,这些参数必须匹配。

更深的概念自行百度。

一般的串口调试工具都是默认数据位为8,停止位1,奇偶校验0

C#串口类:SerialPort

编写串口助手时,可能会用到的一些属性和方法。

构造函数:

  名称 描述
公共方法 SerialPort() 初始化 SerialPort 类的新实例。
公共方法 SerialPort(String) 使用指定的端口名初始化 SerialPort 类的新实例。
公共方法 SerialPort(String, Int32) 使用指定的端口名和波特率初始化 SerialPort 类的新实例。
公共方法 SerialPort(String, Int32, Parity) 使用指定的端口名、波特率和奇偶校验位初始化 SerialPort 类的新实例。
公共方法 SerialPort(String, Int32, Parity, Int32) 使用指定的端口名、波特率、奇偶校验位和数据位初始化SerialPort 类的新实例。
公共方法 SerialPort(String, Int32, Parity, Int32, StopBits) 使用指定的端口名、波特率、奇偶校验位、数据位和停止位初始化 SerialPort 类的新实例。

属性:

  名称 描述
公共属性 BaudRate 获取或设置串行波特率。
公共属性 BytesToRead 获取接收缓冲区中数据的字节数。
公共属性 Handshake 使用 Handshake 中的值获取或设置串行端口数据传输的握手协议。
公共属性 IsOpen 获取一个值,该值指示 SerialPort 对象的打开或关闭状态。
公共属性 NewLine 获取或设置用于解释 ReadLine 和 WriteLine 方法调用结束的值。
公共属性 Parity 获取或设置奇偶校验检查协议。
公共属性 PortName 获取或设置通信端口,包括但不限于所有可用的 COM 端口。
公共属性 ReadBufferSize 获取或设置 SerialPort 输入缓冲区的大小。
公共属性 ReadTimeout 获取或设置读取操作未完成时发生超时之前的毫秒数。
公共属性 ReceivedBytesThreshold 获取或设置 DataReceived 事件发生前内部输入缓冲区中的字节数。
公共属性 StopBits 获取或设置每个字节的标准停止位数。
公共属性 WriteBufferSize 获取或设置串行端口输出缓冲区的大小。
公共属性 WriteTimeout 获取或设置写入操作未完成时发生超时之前的毫秒数。

方法:

  名称 描述
公共方法 Close 关闭端口连接,将 IsOpen 属性设置为 false,并释放内部Stream 对象。
公共方法静态成员 GetPortNames 获取当前计算机的串行端口名的数组。
受保护的方法 MemberwiseClone(Boolean) 创建当前 MarshalByRefObject 对象的浅表副本。 (继承自MarshalByRefObject。)
公共方法 Open 打开一个新的串行端口连接。
公共方法 Read(Byte[], Int32, Int32) 从 SerialPort 输入缓冲区读取一些字节并将那些字节写入字节数组中指定的偏移量处。
公共方法 Read(Char[], Int32, Int32) 从 SerialPort 输入缓冲区中读取一些字符,然后将这些字符写入字符数组中指定的偏移量处。
公共方法 ReadByte 从 SerialPort 输入缓冲区中同步读取一个字节。
公共方法 ReadChar 从 SerialPort 输入缓冲区中同步读取一个字符。
公共方法 ReadExisting 在编码的基础上,读取 SerialPort 对象的流和输入缓冲区中所有立即可用的字节。
公共方法 ReadLine 一直读取到输入缓冲区中的 NewLine 值。
公共方法 ReadTo 一直读取到输入缓冲区中的指定 value 的字符串。
公共方法 Write(String) 将指定的字符串写入串行端口。
公共方法 Write(Byte[], Int32, Int32) 使用缓冲区中的数据将指定数量的字节写入串行端口。
公共方法 Write(Char[], Int32, Int32) 使用缓冲区中的数据将指定数量的字符写入串行端口。
公共方法 WriteLine 将指定的字符串和 NewLine 值写入输出缓冲区。

事件

  名称 描述
公共事件 DataReceived 指示已通过由 SerialPort 对象表示的端口接收了数据。

封装串口类:

SerialPort类并不一定符合我们的需求,个人喜欢封装为新的类实现一些自定义功能,

而且封装会使程序比较模块化,清晰方便。当然,不封装也行。

接下来,对SerialPort类进行封装:

我将新类命名为Comm,使它继承SerialPort类

public class Comm : SerialPort
{

}

接收数据缓存

public StringBuilder RevData;//接收的数据

发送、接收字节计数:

            public ulong SendCount
            {
                set;
                get;
            }
            public ulong GetCount
            {
                set;
                get;
            }

计数清零:

            public void ClearCount()
            {
                SendCount = 0;
                GetCount = 0;
            }

设置串口类基本参数:

该方面用来设置串口的基本参数,由于Parity(校验)和StopBit(停止位)是枚举类型,所以需要用switch判断语句

            public void CommSetting(String port, String baudRate, String dataBit, String parity, String stopBit)
            {
                PortName = port;
                BaudRate = int.Parse(baudRate);
                DataBits = int.Parse(dataBit);
                switch (parity)
                {
                    case "无":
                        Parity = Parity.None; break;
                    case "奇校验":
                        Parity = Parity.Odd; break;
                    case "偶校验":
                        Parity = Parity.Even; break;
                }
                switch (stopBit)
                {
                    case "1":
                        StopBits = StopBits.One; break;
                    case "1.5":
                        StopBits = StopBits.OnePointFive; break;
                    case "2":
                        StopBits = StopBits.Two; break;
                }
            }

发送、接收是否是十六进制:

            public bool IsHexData
            {
                get;
                set;
            }
            public bool RevIsHexData
            {
                get;
                set;
            }

是否自动换行:

            public bool SendNewLine
            {
                get;
                set;
            }

串口发送:

串口发送有16进制和字符串两种方式,需要说明的是,
以字符串形式发送时需要使用Encoding.Default.GetBytes()对字符串进行字符编码,
在接收也需要相同函数进行字符解码,这样中文就不会出现乱码了

            public void WriteData(string data)
            {
                if (IsHexData)
                {
                    MatchCollection mc = Regex.Matches(data, @"(?i)[\da-f]{2}");
                    List<byte> buf = new List<byte>();//填充到这个临时列表中  
                    //依次添加到列表中  
                    foreach (Match m in mc)
                    {
                        buf.Add(byte.Parse(m.Value, System.Globalization.NumberStyles.HexNumber));
                    }
                    if (SendNewLine)
                    {
                        buf.Add(0x0A);
                        // buf.Add(0x0D);
                    }
                    //转换列表为数组后发送  
                    this.Write(buf.ToArray(), 0, buf.Count);
                    SendCount = SendCount + (ulong)buf.Count;
                }
                else
                {
                    byte[] bf = new byte[data.Length];
                    bf = Encoding.Default.GetBytes(data);
                    this.Write(bf, 0, bf.Length);
                    if (SendNewLine)
                    {
                        this.Write("\r\n");
                        SendCount = SendCount + 2;
                    }
                    SendCount = SendCount + (ulong)bf.Length;
                }
            }




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值