C# 一个串口通信的案例实现

通信规格书:

指定页读取规范:

HOST:<LF>RPP1<CR>
Reader:<LF>R<FAIL> <CR><LF> // 读取失败
Reader:<LF>R12345678<CR><LF>// 读取成功

Example:
HOST:0A 52 50 50 31 0D
Reader:0A 52 30 31 32 33 34 35 59 54 0D 0A // 成功
Reader:0A 52 46 41 49 4C 0D 0A // 失败

  1. HOST发送指令

    • HOST通过串口向RFID读写器发送指定页读取的命令。
    • 命令格式为 <LF>RPP1<CR>,其中:
      • <LF> 表示换行符,ASCII码为 0x0A。
      • <CR> 表示回车符,ASCII码为 0x0D。
      • RPP1 表示指定读取第一页的数据。
  2. 读写器响应

    • 如果读写器成功读取了数据,会返回如下格式的响应:
      • <LF>R12345678<CR><LF>,其中:
        • R 是固定的标识符,表示读取操作。
        • 12345678 是具体的数据内容。
        • <LF> 表示换行符。
        • <CR> 表示回车符。
    • 如果读取失败,读写器返回如下格式的响应:
      • <LF>RFAIL<CR><LF>,其中:
        • RFAIL 表示读取失败。

指定页写入规范:

HOST:<LF>WPP1,12345678<CR>
Reader:<LF>W<FAIL> <CR><LF> //写入失败
Reader:<LF>W<OK> <CR><LF> // 写入成功

Example:
HOST:0A 57 50 50 31 2C 31 32 33 34 35 36 37 38 0D
Reader:0A 57 4F 4B 0D 0A // 写入成功
Reader:0A 57 46 41 49 4C 0D 0A // 写入失败

  1. HOST发送指令

    • HOST通过串口向RFID读写器发送指定页写入的命令。
    • 命令格式为 <LF>WPP1,12345678<CR>,其中:
      • <LF> 表示换行符,ASCII码为 0x0A。
      • <CR> 表示回车符,ASCII码为 0x0D。
      • WPP1,12345678 表示写入数据到第一页,数据为 12345678
  2. 读写器响应

    • 如果写入操作成功,读写器会返回如下格式的响应:
      • <LF>W<OK><CR><LF>,其中:
        • W 是固定的标识符,表示写入操作。
        • <OK> 表示写入成功。
        • <LF> 表示换行符。
        • <CR> 表示回车符。
    • 如果写入操作失败,读写器会返回如下格式的响应:
      • <LF>W<FAIL><CR><LF>,其中:
        • W 是固定的标识符,表示写入操作。
        • <FAIL> 表示写入失败。

实现代码类: 

    public class RfidCls : IDisposable
    {
        private SerialPort port;
        private Thread initThread;
        private readonly object mylock = new object();
        private string portName = "COM2";
        private int baudRate = 9600;
        public bool IsLink { get; private set; }

        public void Start(string portname, int baudrate)
        {
            portName = portname;
            baudRate = baudrate;
            initThread = new Thread(InitializePort);
            initThread.Start();
        }

        private void InitializePort()
        {
            try
            {
                if (string.IsNullOrEmpty(portName))
                    throw new ArgumentException("串口参数未设置,请检查!");

                port = new SerialPort(portName, baudRate)
                {
                    StopBits = StopBits.One,
                    DataBits = 8,
                    Parity = Parity.None
                };

                port.Open();
                if (port.IsOpen)
                {
                    IsLink = true;
                    LogInfo("RFID连接成功");
                }
                else
                {
                    throw new Exception("串口未能成功打开!");
                }
            }
            catch (Exception ex)
            {
                LogError($"串口连接失败:{ex.Message}");
            }
        }

        public void Close()
        {
            try
            {
                if (port != null && port.IsOpen)
                {
                    port.Close();
                    LogInfo("RFID连接已关闭");
                }
            }
            catch (Exception ex)
            {
                LogError($"关闭RFID连接失败:{ex.Message}");
            }
        }

        public bool ReadRFID(int pageIndex, out string pageInfo)
        {
            pageInfo = null;
            try
            {
                lock (mylock)
                {
                    if (port == null || !port.IsOpen)
                        throw new InvalidOperationException("RFID端口未打开或已关闭");

                    string command = $"RPP{pageIndex + 1}";
                    byte[] commandBytes = ConstructCommand(command, "");
                    port.Write(commandBytes, 0, commandBytes.Length);
                    byte[] responseBytes = ReadResponse();

                    if (responseBytes != null && responseBytes.Length >= 4)
                    {
                
                        byte[] Bytes = responseBytes.Skip(2).Take(responseBytes.Length - 4).ToArray();
                        string response = Encoding.Default.GetString(Bytes);

                        if (response.StartsWith("R"))
                        {
                            if (response == "RFAIL")
                            {
                                LogError("读取RFID失败");
                                return false;
                            }
                            else
                            {
                                pageInfo = response.Substring(1);
                                LogInfo($"读取RFID成功:{pageInfo}");
                                return true;
                            }
                        }
                    }

                    LogError("读取RFID未知响应");
                    return false;
                }
            }
            catch (Exception ex)
            {
                LogError($"读取RFID出错:{ex.Message}");
                return false;
            }
        }

        public bool WriteRFID(int pageIndex, string hexValue)
        {
            try
            {
                lock (mylock)
                {
                    if (port == null || !port.IsOpen)
                        throw new InvalidOperationException("RFID端口未打开或已关闭");

                    string command = $"WPP{pageIndex + 1},{hexValue}";
                    byte[] commandBytes = ConstructCommand(command, "");
                    port.Write(commandBytes, 0, commandBytes.Length);
                    byte[] responseBytes = ReadResponse();

                    if (responseBytes != null && responseBytes.Length >= 4)
                    {
                        byte[] Bytes = responseBytes.Skip(2).Take(responseBytes.Length - 4).ToArray();
                        string response = Encoding.Default.GetString(Bytes);
                        if (response.StartsWith("W"))
                        {
                            if ( response == "WOK")
                            {
                                LogInfo("写入RFID成功");
                                return true;
                            }
                            else 
                            {
                                LogError("写入RFID失败");
                                return false;
                            }
                        }
                    }

                    LogError("写入RFID未知响应");
                    return false;
                }
            }
            catch (Exception ex)
            {
                LogError($"写入RFID出错:{ex.Message}");
                return false;
            }
        }

        private byte[] ConstructCommand(string command, string hexValue)
        {
            StringBuilder commandHex = new StringBuilder();
            foreach (char c in command)
            {
                commandHex.Append(Convert.ToString(c, 16));
            }

            string dataHex = hexValue;

            string fullHex = $"0A{commandHex}2C{dataHex}0D";

            byte[] commandBytes = new byte[fullHex.Length / 2];
            for (int i = 0; i < fullHex.Length; i += 2)
            {
                commandBytes[i / 2] = Convert.ToByte(fullHex.Substring(i, 2), 16);
            }

            return commandBytes;
        }

        private byte[] ReadResponse()
        {
            DateTime startTime = DateTime.Now;
            byte[] buffer = new byte[1024];
            int totalBytes = 0;

            while (DateTime.Now.Subtract(startTime).TotalSeconds < 3)
            {
                int bytesToRead = port.BytesToRead;
                if (bytesToRead > 0)
                {
                    if (totalBytes + bytesToRead > buffer.Length)
                        Array.Resize(ref buffer, totalBytes + bytesToRead);

                    totalBytes += port.Read(buffer, totalBytes, bytesToRead);

                    if (totalBytes >= 2&& buffer[totalBytes - 2] == 0x0D&& buffer[totalBytes - 1] == 0x0A)
                    {
                        Array.Resize(ref buffer, totalBytes);
                        return buffer;
                    }
                                              
                }
                else
                {
                    Thread.Sleep(100);
                }
            }

            return null;
        }

        private void LogInfo(string message)
        {
            // 实现信息日志记录,例如使用日志框架记录到文件或其他存储介质
            Console.WriteLine($"信息:{message}");
        }

        private void LogError(string message)
        {
            // 实现错误日志记录,例如使用日志框架记录到文件或其他存储介质
            Console.WriteLine($"错误:{message}");
        }

        public void Dispose()
        {
            Close();
            if (initThread != null)
            {
                initThread.Join(); // 确保线程已终止
                initThread = null;
            }
            if (port != null)
            {
                port.Dispose(); // 释放串口资源
                port = null;
            }
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值