.net实现串口通信

本文详细介绍了使用.NET进行串口通信的过程,包括配置串口信息、打开串口、发送和接收数据(无返回值及有返回值的情况),以及关闭串口和释放资源的重要性。在发送数据时强调了设置WriteTimeout的必要性,接收数据部分提到了通过DataReceived委托和从缓冲区读取数据的方法。


我这里是项目要求,基于 .net framework4.0 框架。
功能实现主要依靠.net提供的 System.IO.Ports.SerialPort 类。
串口通信分为6个步骤:

1、配置串口信息

根据设备厂商提供的串口对接说明实例化SerialPort对象。

//设置串口属性
var ComDevice = new SerialPort
{
    PortName = "COM1",	//串口
    BaudRate = 4800,	//波特率
    Parity = Parity.None,	//校验位
    DataBits = 8,		//数据位
    StopBits = StopBits.One,		//停止位
    WriteTimeout = 1000,	//设置串口写入数据阻塞时长,阻塞到写入数据或超时(这里为1秒)
    ReadTimeout = 1000,	//设置串口读取数据阻塞时长,阻塞到读取数据或超时(这里为1秒)
};

2、打开串口

        /// <summary>
        /// 开启端口
        /// </summary>
        /// <returns></returns>
        public bool OpenPort()
        {
            try
            {
                if (!ComDevice.IsOpen)
                {
                    //开启串口
                    ComDevice.Open();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("未能成功开启串口:" + ex.Message);
                return false;
            }
            return true;
        }

3、发送数据

注意设置WriteTimeout 。如果没设置,调用ComDevice.Write之后可能会卡死。

        /// <summary>
        /// 将编码后的消息传递给串口
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool SendData(byte[] bytesData)
        {
            //串口已开启
            if (ComDevice.IsOpen)
            {
                try
                {
                    //将消息传递给串口
                    ComDevice.Write(bytesData, 0, bytesData.Length);
                    return true;
                }
                catch (Exception ex)
                {
                   Console.WriteLine("发送失败:" + ex.Message);
                }
            }
            else
            {
                Console.WriteLine("串口未开启"); 
            }
            return false;
        }

4、接收数据

1)无返回值

通过SerialPort对象的DataReceived委托实现。

            //接收数据
            ComDevice.DataReceived += new SerialDataReceivedEventHandler((sender, e) => 
            {
                //开辟接收缓冲区
                byte[] bytesData = new byte[ComDevice.BytesToRead];
                //从串口读取数据
                ComDevice.Read(bytesData, 0, bytesData.Length);
                //数据解码,根据设备厂商约定的方式解码
                var data = Encoding.ASCII.GetString(bytesData);
            });

2)有返回值

从串口缓冲区循环读取,直到读到有效数据,返回有效数据。
有效数据的标识根据设备厂商的约定设置。

        /// <summary>
        /// 循环读取串口数据
        /// </summary>
        /// <param name="key">数据标识</param>
        /// <param name="serialPort">串口</param>
        /// <returns></returns>
        private string CirclularReadData(string key)
        {
            for (int i = 0; i < 50; i++)
            {
                int bytesRead = ComDevice.BytesToRead; //获取接收缓冲区中数据的字节数
                //接收缓冲区数据不为空,读取缓冲池数据
                if (bytesRead > 0)
                {
                    //开辟接收缓冲区
                    byte[] bytesData = new byte[bytesRead];
                    //从串口读取数据
                    ComDevice.Read(bytesData, 0, bytesData.Length);
                    //数据编码,根据设备厂商约定的方式编码
                    var data = Encoding.ASCII.GetString(bytesData);
                    Console.WriteLine($"【串口】缓冲区数据读取(第{i}次):" + data);
                    //如果检测到标识,退出,并返回数据
                    if (data.Contains(key))
                    {
                        return data;
                    }
                }
                //接收缓冲区数据为空,阻塞当前进程,2s
                else
                {
                    Console.WriteLine("【串口】缓冲区暂无可读数据,等待2s");
                    Thread.Sleep(2000);
                }
            }
            return null;
        }

5、关闭串口

        /// <summary>
        /// 关闭串口
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool ClosePort(ref string msg)
        {
            try
            {
                if (ComDevice.IsOpen)
                {
                    ComDevice.Close();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("串口关闭错误:" + ex.Message);
                return false;
            }
            return true;
        }

6、释放资源

这点很重要,串口用完就要立即释放。

ComDevice.Dispose();
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值