C# 在Linux系统使用串口通讯

1. NuGet上安装 flyfire.CustomSerialPort

企业微信截图_17609302215051

 2. 串口类

public class serialPort
    {
        public byte Lo;
        public byte Hi;
        public SerialPort Comm = new SerialPort();
        public bool Open()
        {
            try
            {
                Comm.Open();
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return false;
            }
        }
        public bool Close()
        {
            try
            {
                Comm.Close();
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return false;
            }
        }

        public bool Setting(string Name, int BaudRate, int DataBits, int StopBits, int ReadTimeout)
        {
            try
            {
                if (Comm.IsOpen == true) Comm.Close();
                Comm.PortName = Name;
                Comm.BaudRate = BaudRate;   //波特率设置
                Comm.DataBits = DataBits;             //数据位设置
                Comm.StopBits = (StopBits)StopBits;    //停止位设置
                Comm.Parity = Parity.None;
                


                return true;


            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return false;
            }
        }
        public delegate void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e);

        private object WriteLock = new object();
        public bool WriteBinary(byte[] value)
        {
            try
            {
                if (Comm.IsOpen == false) Comm.Open();

                //int i = Comm.BytesToWrite;
                lock (WriteLock)
                {
                    Comm.Write(value, 0, value.Length);
                }
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return false;
            }
        }

        

        /// <summary>
        /// 延时读取全部
        /// </summary>
        /// <param name="Timeout">延时时间</param>
        /// <returns></returns>
        public byte[] ReadBinary(int sleep)
        {
            try
            {
                if (Comm.IsOpen == false) Comm.Open();

                Thread.Sleep(sleep);
                byte[] data = new byte[Comm.BytesToRead];
                Comm.Read(data, 0, data.Length);

                return data;
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// 等待读取固定字节数
        /// </summary>
        /// <param name="readNum">读取字节数</param>
        /// <param name="a"></param>
        /// <returns></returns>
        public byte[] ReadBinaryA(int readNum)
        {
            try
            {
                if (Comm.IsOpen == false) Comm.Open();
                while (Comm.BytesToRead <= readNum)
                {
                    Thread.Sleep(1);
                }
                //Thread.Sleep(Timeout);
                byte[] data = new byte[readNum];
                Comm.Read(data, 0, data.Length);

                return data;
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// 轮询缓存区状态读取数据
        /// </summary>
        /// <param name="readNum"></param>
        /// <returns></returns>
        public byte[] ReadBinaryB()
        {
            try
            {
                if (Comm.IsOpen == false) Comm.Open();
                int count = -1;
                while (Comm.BytesToRead != count)
                {
                    Thread.Sleep(1);
                    if (Comm.BytesToRead != 0)
                    {
                        count = Comm.BytesToRead;
                    }
                }
                byte[] data = new byte[count];
                Comm.Read(data, 0, data.Length);

                return data;
            }
            catch (Exception)
            {
                return null;
            }
        }
        public byte[] ReadBinaryTimeout(int number)
        {
            try
            {
                if (Comm.IsOpen == false) Comm.Open();
                byte[] data = new byte[number];
                try
                {
                    DateTime starttime = DateTime.Now;
                    Thread.Sleep(200);
                    Comm.Read(data, 0, data.Length);
                }
                catch (Exception)
                {

                }
                return data;
            }
            catch (TimeoutException)
            {
                byte[] data = new byte[Comm.BytesToRead];
                Comm.Read(data, 0, Comm.BytesToRead);
                return data;
            }

        }
        public byte[] Chr_crc(byte[] data, int Index)
        {
            int len = data.Length - Index;
            if (len > 0)
            {
                ushort crc = 0xFFFF;

                for (int i = 0; i < len; i++)
                {
                    crc = (ushort)(crc ^ (data[i]));
                    for (int j = 0; j < 8; j++)
                    {
                        crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1);
                    }
                }
                Hi = (byte)((crc & 0xFF00) >> 8); //高位置
                Lo = (byte)(crc & 0x00FF); //低位置

                return new byte[] { Hi, Lo };
            }
            return null;
        }

        /// <summary>
        /// 检验异或校验
        /// </summary>
        /// <param name="Buffer"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public int BCC_Xor_Check(byte[] Buffer, int len)
        {
            int Xor = 0;
            int i;
            for (i = 0; i < len - 1; i++) Xor = Xor ^ Buffer[i];
            if (Buffer[len - 1] == Xor) return 1;
            else return 0;
        }

        /// <summary>
        /// 添加异或校验
        /// </summary>
        /// <param name="Buffer"></param>
        /// <param name="len"></param>
        public void BCC_Xor_Write(byte[] Buffer, int len)
        {
            int Xor = 0;
            int i;
            for (i = 0; i < len - 1; i++) Xor = Xor ^ Buffer[i];
            Buffer[len - 1] = (byte)Xor;
        }

        public static byte[] CalculateAdd(byte[] buffer, int start, int length)//取低八位
        {
            int cks = 0;

            for (int i = start; i < length; i++)
            {
                cks = (cks + buffer[i]) % 0xffff;
            }

            byte Hi = (byte)((cks & 0xff00) >> 8);//取校验和高8位
            byte Lo = (byte)(cks & 0xff);//取校验和低8位

            return new byte[] { Lo, Hi };

        }
        
    }
View Code

3. 调用(简单的只需要关注<comm>对象就行)

static serialPort comm = new serialPort();

// 打开串口
public static rth_OpenSerialPort OpenSerialPort(string JsonString)
{
    try
    {
        OpenSerialPort json = JsonHelper.DeserializeJsonToObject<OpenSerialPort>(JsonString);
        if (json == null) throw new System.Exception("json解析失败!");
        rth_OpenSerialPort rth = new rth_OpenSerialPort();
        // $"/dev/{json.PortName}"
        if (comm.Comm.IsOpen) { rth.IsOpen = true; return rth; }
        comm.Setting(json.PortName, json.BaudRate, 8, 1, 200);

        rth.IsOpen = comm.Open();
        if (rth.IsOpen && (upCTS == null))
        {
            MessageReceived();
            SendSerialPort();
            Thread.Sleep(1000);
        }

        return rth;
    }
    catch (Exception ex)
    {
        Logger.Error("OpenSerialPort:" + ex.Message);
        return new rth_OpenSerialPort() { IsOpen = false };
    }

}

// 关闭串口
public static rth_CloseSerialPort CloseSerialPort(string JsonString)
{
    try
    {
        CloseSerialPort json = JsonHelper.DeserializeJsonToObject<CloseSerialPort>(JsonString);
        if (json == null) throw new System.Exception("json解析失败!");
        rth_CloseSerialPort rth = new rth_CloseSerialPort();

        if (upCTS != null) upCTS.Cancel();

        Thread.Sleep(1000);

        rth.IsClose = comm.Close();


        return rth;
    }
    catch (Exception ex)
    {
        Logger.Error("CloseSerialPort:" + ex.Message);
        return new rth_CloseSerialPort() { IsClose = false };
    }

}

// 接收数据
static CancellationTokenSource upCTS;
public static void MessageReceived()
{
    upCTS = new CancellationTokenSource();
    Task.Run(() =>
    {
        while (!upCTS.Token.IsCancellationRequested)
        {
            try
            {
                BasicDataModel a = new BasicDataModel();
                byte[] bytes = null;
                
                // 电压电流量程
                lock (SendLock)
                {
                    comm.WriteBinary(new byte[] { 0x01, 0x03, 0x04, 0x14, 0x00, 0x03, 0x44, 0xFF });
                    bytes = comm.ReadBinary(200);
                }
                if (bytes != null && bytes.Length > 0)
                {
                    //a.voltageRange = (bytes[4]).ToString();
                    //a.currentRange = (bytes[6]).ToString();
                    a.outEnergyModel = (bytes[8]).ToString();
                }


                lock (Lock_M)
                {
                    MonitorData = a;
                }
            }
            catch (Exception ex)
            {
                Logger.Error("MessageReceived:" + ex.Message);
                Console.WriteLine(ex.ToString());
            }
        }
        upCTS = null;
    });
}

public static object Lock_M { get; set; } = new object();
public static BasicDataModel MonitorData { get; set; } = new BasicDataModel();


// 发送数据
public static object SendLock { get; set; } = new object();
public static object SDLock { get; set; } = new object();
public static List<byte[]> SendDatas { get; set; } = new List<byte[]>();
static CancellationTokenSource sendCTS { get; set; }
public static void SendSerialPort()
{
    sendCTS = new CancellationTokenSource();
    Task.Run(() =>
    {
        while (!sendCTS.Token.IsCancellationRequested)
        {
            try
            {
                List<byte[]> senddata = new List<byte[]>();
                lock (SDLock)
                {
                    senddata.AddRange(SendDatas);
                    SendDatas.Clear();
                }

                foreach (byte[] data in senddata)
                {
                    lock (SendLock)
                    {
                        comm.WriteBinary(data);
                        comm.ReadBinary(200);
                    }

                }
                Thread.Sleep(500);
            }
            catch (Exception ex)
            {
                Logger.Error("SendSerialPort:" + ex.Message);
            }
        }
    });
}
View Code

 

posted @ 2025-10-20 11:38  妖言惑众'  阅读(6)  评论(0)    收藏  举报