123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- using System;
- using System.IO.Ports; // 添加必要的命名空间
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Windows.Forms; // 用于BeginInvoke调用
- namespace Bird_tool
- {
- class SerialManager
- {
- public delegate void LogHandler(string message, LogLevel level);
- public delegate void LogShowHandler(string message);
- public event LogHandler OnLog;
- public delegate void DisconnectHandler(bool isError);
- public delegate void ConnectHandler();
- public event DisconnectHandler OnDisconnect;
- public event ConnectHandler OnConnect;
- private SerialPort _uart = new SerialPort();
- private int MAX_BUFFER_SIZE = 4096; // 最大缓冲区大小
- // 定义行数据接收事件
- public event Action<string> OnLineReceived;
- public string _tmp_text = ""; // 暂存串口返回的数据
- public Regex reg_R = new Regex(@"\r"); // 匹配/r回车符
- public Regex reg_N = new Regex(@"\n"); // 匹配/n换行符
- public Regex reg_RN = new Regex(@"\r\n"); // 匹配标准换行符
- public void Config(int dataBits = 8, StopBits stopBits = StopBits.One, Parity parity = Parity.None)
- {
- _uart.DataBits = dataBits; // 数据位
- _uart.StopBits = stopBits; // 停止位
- _uart.Parity = parity; // 校验位
- }
- public void SetMaxBuffer(int buffer_size)
- {
- MAX_BUFFER_SIZE = buffer_size;
- }
- public bool Connect(string portName, int baudRate = 115200)
- {
- if (_uart.IsOpen)
- {
- OnLog?.Invoke("串口已经打开", LogLevel.debug);
- return true;
- }
- _uart.PortName = portName;
- _uart.BaudRate = baudRate;
- _uart.Encoding = Encoding.ASCII;
- _uart.DataReceived += CommDataReceived;
- try
- {
- _uart.Open();
- System.Threading.Thread.Sleep(150);
- OnConnect?.Invoke();
- return true;
- }
- catch (Exception ex)
- {
- ErrorHandle("串口打开失败", ex);
- return false;
- }
- }
- public void Disconnect(bool isError = false)
- {
- if (_uart.IsOpen)
- {
- _uart.DataReceived -= CommDataReceived;
- _uart.Close();
- OnDisconnect?.Invoke(isError);
- }
- _tmp_text = ""; // 清空缓冲区
- }
- public bool ReOpen()
- {
- return Connect(_uart.PortName, _uart.BaudRate);
- }
- public bool IsOpen ()
- {
- return _uart.IsOpen;
- }
- private void CommDataReceived(object sender, SerialDataReceivedEventArgs e)
- {
- try
- {
- int bytesToRead = _uart.BytesToRead;
- byte[] buffer = new byte[bytesToRead];
- _uart.Read(buffer, 0, bytesToRead);
- string receivedText = Encoding.ASCII.GetString(buffer);
- // 使用委托更新UI线程
- if (System.Windows.Forms.Application.OpenForms.Count > 0)
- {
- var mainForm = System.Windows.Forms.Application.OpenForms[0];
- mainForm.BeginInvoke((MethodInvoker)delegate {
- ProcessReceivedData(receivedText);
- });
- }
- else
- {
- // 非UI环境直接处理
- ProcessReceivedData(receivedText);
- }
- }
- catch (InvalidOperationException ex)
- {
- // 专门捕获串口断开异常
- ErrorHandle($"串口异常断开: {ex.Message}", ex);
- Disconnect(true); // 确保资源清理
- }
- catch (Exception ex)
- {
- ErrorHandle("串口接收异常", ex);
- if (ex is InvalidOperationException || ex is System.IO.IOException)
- {
- ErrorHandle($"串口意外断开: {ex.Message}", ex);
- Disconnect(true); // 确保资源清理
- }
- }
- }
- private void ProcessReceivedData(string newData)
- {
- _tmp_text += newData;
- // 缓冲区溢出保护
- if (_tmp_text.Length > MAX_BUFFER_SIZE)
- {
- ParseText(_tmp_text.Substring(0, MAX_BUFFER_SIZE));
- _tmp_text = _tmp_text.Substring(MAX_BUFFER_SIZE);
- }
-
- // 处理所有可能的换行符组合
- while (true)
- {
- int rnIndex = _tmp_text.IndexOf("\r\n");
- int rIndex = _tmp_text.IndexOf('\r');
- int nIndex = _tmp_text.IndexOf('\n');
- int splitIndex = -1;
- int splitLength = 0;
- if (rnIndex >= 0)
- {
- splitIndex = rnIndex;
- splitLength = 2;
- }
- else if (rIndex >= 0 && (rIndex < nIndex || nIndex < 0))
- {
- splitIndex = rIndex;
- splitLength = 1;
- }
- else if (nIndex >= 0)
- {
- splitIndex = nIndex;
- splitLength = 1;
- }
- if (splitIndex < 0) break;
- string line = _tmp_text.Substring(0, splitIndex);
- _tmp_text = _tmp_text.Substring(splitIndex + splitLength);
-
- if (!string.IsNullOrWhiteSpace(line))
- {
- ParseText(line);
- }
- }
- }
-
- private void ParseText(string line)
- {
- // 调用外部注册的事件处理器
- OnLineReceived?.Invoke(line);
- }
- public void SendCommand(string command)
- {
- if (_uart.IsOpen)
- {
- try
- {
- _uart.WriteLine(command);
- }
- catch (Exception ex)
- {
- ErrorHandle("发送命令失败", ex);
- }
- }
- }
- private void ErrorHandle(string tips, Exception ex)
- {
- // 确保日志系统存在或替换为您的实际实现
- bird_tool.Log_show($"{tips} {ex.Message}");
- bird_tool.Log($"{tips} {ex.Message}");
- Console.WriteLine($"{tips}: {ex.Message}");
- }
-
- }
- }
|