.Net 串口通信帮助类

    public class SerialHelper
    {
        private SerialPort _serialPort;
        private SerialParam _serialParam;

        public SerialHelper(SerialParam param)
        {
            _serialParam = param;
            Open();
        }

        private void Open()
        {
            _serialPort = new SerialPort(_serialParam.PortName, _serialParam.BaudRate, _serialParam.PortParity, _serialParam.DataBits);
            _serialPort.Open();
        }

        public bool GetSerialPortState()
        {
            return _serialPort.IsOpen;
        }

        public void Close()
        {
            if (_serialPort == null) return;
            _serialPort.Close();
            _serialPort.Dispose();
            _serialPort = null;
        }

        /// <summary>
        /// 获取本机可用串口
        /// </summary>
        /// <returns></returns>
        public static string[] GetLocalSerialPortNames()
        {
            return SerialPort.GetPortNames();
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="msg">数据</param>
        /// <param name="timeout">超时时间</param>
        /// <param name="count">串口回复字节数</param>
        /// <returns></returns>
        public byte[] SendMessage(byte[] msg, TimeSpan timeout, int count)
        {
            var stopwatch = Stopwatch.StartNew();
            var originalWriteTimeout = _serialPort.WriteTimeout;
            var originalReadTimeout = _serialPort.ReadTimeout;
            try
            {

                _serialPort.WriteTimeout = (int)Math.Max((timeout - stopwatch.Elapsed).TotalMilliseconds, 0);
                _serialPort.Write(msg, 0, msg.Length);

                var tmpCount = count;
                byte[] buffer = new byte[tmpCount];
                int offset = 0;
                while (tmpCount > 0)
                {
                    _serialPort.ReadTimeout = (int)Math.Max((timeout - stopwatch.Elapsed).TotalMilliseconds, 0);
                    var readCount = _serialPort.Read(buffer, offset, tmpCount);
                    offset += readCount;
                    tmpCount -= readCount;
                }
                return buffer;
            }
            finally
            {
                _serialPort.ReadTimeout = originalReadTimeout;
                _serialPort.WriteTimeout = originalWriteTimeout;
            }
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="msg">数据</param>
        /// <param name="timeout">超时时间</param>
        /// <param name="count">串口回复字节数</param>
        /// <returns></returns>
        public async Task<byte[]> SendMessageAsync(byte[] msg, TimeSpan timeout, int count)
        {
            var sendTask = Task.Run(() => SendMessage(msg, timeout, count));
            try
            {
                await Task.WhenAny(sendTask, Task.Delay(timeout));
            }
            catch (TaskCanceledException)
            {
                throw new TimeoutException();
            }
            return await sendTask;
        }
    }

    public class SerialParam
    {
        public string PortName { get; set; } = "COM3";
        public int BaudRate { get; set; } = 57600;
        public int DataBits { get; set; } = 8;
        public Parity PortParity { get; set; } = Parity.None;
        public StopBits PortStopBits { get; set; } = StopBits.None;
    }

调用方式也很简单:

Console.WriteLine("Hello, World!");
// 查看本机可用串口
foreach (var val in SerialHelper.GetLocalSerialPortNames())
{
    Console.WriteLine(val);
}

// 初始化
var port = new SerialHelper(new SerialParam
{
    PortName = "COM4",
    BaudRate = 57600,
    DataBits = 8
});

// 发送并接收
var result = await port.SendMessageAsync(
    "239,1,255,255,255,255,1,0,3,1,0,5".Split(',').Select(c => byte.Parse(c)).ToArray(),
    TimeSpan.FromSeconds(1),
    14);

Console.WriteLine(string.Join(",", result));

Console.ReadLine();

注意:这边的发送接收是有超时机制的,注意捕获超时异常并处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值