zoukankan      html  css  js  c++  java
  • c# 串口SerialPort

    创建SerialPortFun类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO.Ports;
    using System.Threading;
    using LogSpace;
    
    namespace SerialPortSpace
    {
        public class SerialPortFun
        {
            /// <summary>
            /// 串口及串口缓存数据
            /// </summary>
            public static List<ComPort> LstComPort = new List<ComPort>();
    
            /// <summary>
            /// 是否在进行串口结束操作
            /// </summary>
            public static bool PortIsCloseing = false;
    
            /// <summary>
            /// 初始化串口,并返回当前串口的结构
            /// </summary>
            /// <param name="Port"></param>
            /// <param name="PortNo"></param>
            /// <param name="BaudRate"></param>
            /// <param name="ReciveData"></param>
            public static ComPort InitSerialPort(SerialPort Port, string PortNo, int BaudRate, BagStruct CurBagStruct, string StartStr, string EndStr, string PortNameDesc, string PortRemark)
            {
                Port.PortName = PortNo;
                Port.BaudRate = BaudRate;
                Port.DataBits = 8;
                Port.Parity = Parity.None;
                Port.StopBits = StopBits.One;
                Port.NewLine = "
    ";
                Port.WriteTimeout = 5000;
                Port.ReadTimeout = 5000;
                Port.Handshake = Handshake.None;
                Port.ReceivedBytesThreshold = 1;
                Port.RtsEnable = true;
                Port.DataReceived += Port_DataReceived;//定义接收数据事件
    
                ComPort PortItem = new ComPort();
                PortItem.Port = Port;
                PortItem.PortRealName = PortNameDesc;
                PortItem.PortDesc = PortRemark;
                PortItem.PortIsRcving = false;
                PortItem.LastRebackTime = DateTime.Now;
                PortItem.RcvBag = CurBagStruct;
                PortItem.StartStr = StartStr;
                PortItem.EndStr = EndStr;
                PortItem.SendOrder = new List<string>();
    
                PortItem.RcvData = string.Empty;
                PortItem.RcvLst = new List<PortReciveDataItem>();
                if (LstComPort.Count(c => c.Port == Port) > 0)
                {
                    LstComPort.RemoveAll(c => c.Port == Port);
                }
                LstComPort.Add(PortItem);
                return PortItem;
            }
            /// <summary>
            /// 定义数据包中每项的开始位置及所占字节数
            /// </summary>
            /// <param name="StartPosition"></param>
            /// <param name="Length"></param>
            /// <returns></returns>
            public static BagItemPosition SetBagItemPosition(int StartPosition, int Length)
            {
                BagItemPosition Item = new BagItemPosition();
                Item.StartPosition = StartPosition;
                Item.Length = Length;
                return Item;
            }
    
            /// <summary>
            /// 定义返回数据包结构
            /// </summary>
            /// <param name="ByteOrder">字节顺序约定 0--高字节在前,低字节在后,1--高字节在后,低字节在前</param>
            /// <param name="HeadItem">包头所占字节数</param>
            /// <param name="HeadItem">命令所占字节数</param>
            /// <param name="OthItem">其他位总共占字节数</param>
            /// <param name="DataLenItem">数据长度位所占字节数</param>
            /// <param name="VerItem">校验位所占字节数</param>
            /// <param name="EndItem">包尾所占字节数</param>
            /// <returns></returns>
            public static BagStruct SetBagStruct(int ByteOrder, BagItemPosition HeadItem, BagItemPosition CmdItem, BagItemPosition OthItem, BagItemPosition DataLenItem, int RealDataItem, int VerItem, int EndItem)
            {
                BagStruct CurRcvBagStruct = new BagStruct();
                CurRcvBagStruct.ByteOrder = ByteOrder;
                CurRcvBagStruct.Head = HeadItem;
                CurRcvBagStruct.Cmd = CmdItem;
                CurRcvBagStruct.Other = OthItem;
                CurRcvBagStruct.DataLen = DataLenItem;
                CurRcvBagStruct.RealDataPos = RealDataItem;
                CurRcvBagStruct.VerifyLen = VerItem;
                CurRcvBagStruct.EndLen = EndItem;
                return CurRcvBagStruct;
            }
    
            /// <summary>
            /// 打开串口
            /// </summary>
            /// <param name="PortName"></param>
            public static void OpenSerialPort(SerialPort Port)
            {
                if (!Port.IsOpen)
                {
                    Port.Open();
                }
            }
           
            /// <summary>
            /// 发送串口数据
            /// </summary>
            /// <param name="Port"></param>
            /// <param name="Data"></param>
            public static bool SetPortData(SerialPort Port, string Data)
            {
                bool CurSendFlag = false;
                if (Port.IsOpen)
                {
                    byte[] buf = strToHexByte(Data);
                    Port.Write(buf, 0, buf.Length);
                    CurSendFlag = true;
                }
                return CurSendFlag;
            }
    
            #region 接收串口应答包
    
            /// <summary>
            /// 接收串口应答包
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            public static void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                if (PortIsCloseing)
                {
                    return;
                }
                SerialPort port = sender as SerialPort;
                DateTime CurTime = DateTime.Now;
                string RcvData = string.Empty;
                if (LstComPort != null)
                {
                    if (LstComPort.Count(c => c.Port.PortName == port.PortName) > 0)
                    {
                        ComPort comPort = LstComPort.Find(c => c.Port.PortName == port.PortName);
                        try
                        {
                            Log.WriteLogToLocal(CurTime + "接收前" + comPort.PortRealName + "数据包临时数据:
    " + comPort.RcvData + "
    ------------------------
    ", "Log\IBO_LOG", comPort.PortDesc + "_Receive");
                            RcvData = comPort.RcvData;
                            comPort.PortIsRcving = true;//正在接收串口数据
                            StringBuilder CurRcvData = new StringBuilder();
                            if (port.IsOpen && port.BytesToRead != 0)
                            {
                                while (port.BytesToRead != 0)
                                {
                                    byte[] recvBytes = new byte[port.BytesToRead];
                                    int bytes = port.Read(recvBytes, 0, recvBytes.Length);
                                    if (recvBytes.Length != 0)
                                    {
                                        foreach (byte b in recvBytes)
                                        {
                                            CurRcvData.Append(b.ToString("X2") + " ");
                                        }
                                    }
                                    //Thread.Sleep(20);
                                }
                                Log.WriteLogToLocal(CurTime + "接收" + comPort.PortRealName + "原始数据:
    " + CurRcvData + "
    ------------------------
    ", "Log\IBO_LOG", comPort.PortDesc + "_Receive");
                                RcvData += CurRcvData;
                                CurRcvData.Clear();
                                //接收到的数据进行处理,并存储在串口对应的接收队列中
                                //SerialPortFun.DealPortData(comPort, RcvData, CurTime);
                                SerialPortFun.ConcatFullBag(comPort, comPort.RcvBag, RcvData, CurTime);
                                comPort.LastRebackTime = CurTime;
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.WriteLogToLocal(CurTime + "接收" + comPort.PortRealName + "串口数据(" + RcvData + ")错误:(" + ex.Message+")"+ex.StackTrace + "
    ", "Log\IBO_LOG\ErrorLog", comPort.PortDesc + "_Receive");
                        }
                        finally
                        {
                            comPort.PortIsRcving = false;//接收串口数据完毕
                        }
                    }
                }
            }
    
            #endregion
            /// <summary>
            /// 接收到的数据进行处理,并存储在串口对应的接收队列中
            /// </summary>
            /// <param name="port"></param>
            /// <param name="Struct"></param>
            /// <param name="CurRcvData"></param>
            /// <param name="CurTime"></param>
            public static void ConcatFullBag(ComPort port, BagStruct Struct, string CurRcvData, DateTime CurTime)
            {
                Log.WriteLogToLocal(CurTime + "数据包处理" + port.PortRealName + "原始数据:
    " + CurRcvData + "
    ------------------------
    ", "Log\IBO_LOG", port.PortDesc + "_Receive");
                string temp = CurRcvData;
                while (true)
                {
                    //校验包头,包尾
                    if (!temp.StartsWith(port.StartStr))
                    {
                        int index = temp.IndexOf(port.StartStr);
                        if (index == -1)
                            temp = "";
                        else
                            temp = temp.Remove(0, index);
                    }
                    if (temp.Length > 0)
                    {
                        int NoDataBagLen = Struct.Head.Length + Struct.Cmd.Length + Struct.Other.Length + Struct.DataLen.Length + Struct.VerifyLen + Struct.EndLen;
                        int BagDataLen = 0;
                        if (temp.Length > (Struct.DataLen.StartPosition * 3 + Struct.DataLen.Length * 3))
                        {
                            #region 获取数据包的业务数据长度
                            BagDataLen = GetBagDataLen(Struct, temp);
                            //string CurDataLen = "";
                            //string CurDataLenOrg = temp.Substring(Struct.DataLen.StartPosition * 3, Struct.DataLen.Length * 3);
                            //if (Struct.ByteOrder == 1)//高字节在后,低字节在前
                            //{
                            //    CurDataLen = ReverseStr(CurDataLenOrg, 2);
                            //    BagDataLen = Convert.ToInt32(CurDataLen, 16);//16进制
                            //}
                            //else
                            //{
                            //    CurDataLen = CurDataLenOrg;
                            //    BagDataLen = Convert.ToInt32(CurDataLen, 10);//华气特殊 10进制
                            //}
                            #endregion
                        }
                        if (BagDataLen > 0 && temp.Length / 3 >= NoDataBagLen + BagDataLen)
                        {
                            string FullBag = temp.Substring(0, (NoDataBagLen + BagDataLen) * 3);
                            BagItemContent CurBagItem = new BagItemContent();
                            CurBagItem.Head = FullBag.Substring(Struct.Head.StartPosition * 3, Struct.Head.Length * 3).Replace(" ", "");
                            CurBagItem.Cmd = FullBag.Substring(Struct.Cmd.StartPosition * 3, Struct.Cmd.Length * 3).Replace(" ", "");
                            CurBagItem.Other = FullBag.Substring(Struct.Other.StartPosition * 3, Struct.Other.Length * 3).Replace(" ", "");
                            CurBagItem.DataLen = FullBag.Substring(Struct.DataLen.StartPosition * 3, Struct.DataLen.Length * 3).Replace(" ", "");
                            CurBagItem.RealData = FullBag.Substring(Struct.RealDataPos * 3, BagDataLen * 3);
                            CurBagItem.Verify = FullBag.Substring(FullBag.Length - (Struct.VerifyLen + Struct.EndLen) * 3, Struct.VerifyLen * 3).Replace(" ", "");
                            CurBagItem.End = FullBag.Substring(FullBag.Length - Struct.EndLen * 3, Struct.EndLen * 3).Replace(" ", "");
                            if (Struct.ByteOrder == 1)//高字节在后,低字节在前
                            {
                                CurBagItem.Head = Struct.Head.Length <= 1 ? CurBagItem.Head : ReverseStr(CurBagItem.Head, 2);
                                CurBagItem.Cmd = (Struct.Cmd.Length <= 1 ? CurBagItem.Cmd : ReverseStr(CurBagItem.Cmd, 2));
                                CurBagItem.DataLen = Struct.DataLen.Length <= 1 ? CurBagItem.DataLen : ReverseStr(CurBagItem.DataLen, 2);
                                //CurBagItem.RealData,CurBagItem.Other需根据具体情况解析暂不反转
                                //CurBagItem.RealData = RealDataLen <= 1 ? CurBagItem.RealData : ReverseStr(CurBagItem.RealData, 2);
                                //CurBagItem.Other = Struct.Other.Length <= 1 ? CurBagItem.Other : ReverseStr(CurBagItem.Other, 2);
                                CurBagItem.Verify = Struct.VerifyLen <= 1 ? CurBagItem.Verify : ReverseStr(CurBagItem.Verify, 2);
                                CurBagItem.End = Struct.EndLen <= 1 ? CurBagItem.End : ReverseStr(CurBagItem.End, 2);
                            }
                            PortReciveDataItem NewItem = new PortReciveDataItem();
                            NewItem.ReciveTime = CurTime;
                            NewItem.ReciveDataItem = CurBagItem;
                            NewItem.ReciveDataStr = FullBag;
                            port.RcvLst.Add(NewItem);
                            Log.WriteLogToLocal(CurTime + "加入" + port.PortRealName + "完整数据包:
    " + FullBag + "
    ------------------------
    ", "Log\IBO_LOG", port.PortDesc + "_Receive");
                            temp = temp.Remove(0, FullBag.Length);
                            if (temp.Length <= 0)
                            {
                                port.RcvData = "";
                                break;
                            }
                           // port.RcvData = temp.Substring((NoDataBagLen + BagDataLen) * 3);//剩余字符放入下个数据包
                        }
                        else
                        {
                            port.RcvData = CurRcvData;//不是完整包,等待完整数据
                            break;
                        }
                    }
                    else
                    {
                        //丢弃不符合的串口数据
                        port.RcvData = "";
                        Log.WriteLogToLocal(CurTime + "丢弃" + port.PortRealName + "原始数据:
    " + CurRcvData + "
    ------------------------
    ", "Log\IBO_LOG", port.PortDesc + "_Receive");
                        break;
                    }
                }
            }
            
            /// <summary>
            /// 获取包长度
            /// </summary>
            /// <param name="Struct"></param>
            /// <param name="AllBagData"></param>
            /// <returns></returns>
            public static int GetBagDataLen(BagStruct Struct, string AllBagData)
            {
                int BagDataLen = 0;
                string CurDataLen = "";
                AllBagData = AllBagData.Replace(" ", "");
                string CurDataLenOrg = AllBagData.Substring(Struct.DataLen.StartPosition * 2, Struct.DataLen.Length * 2);
                if (Struct.ByteOrder == 1)//高字节在后,低字节在前
                {
                    CurDataLen = ReverseStr(CurDataLenOrg, 2);
                    BagDataLen = Convert.ToInt32(CurDataLen, 16);//16进制  需改成通用
                }
                else
                {
                    CurDataLen = CurDataLenOrg;
                    BagDataLen = Convert.ToInt32(CurDataLen, 10);//华气特殊 10进制
                }
                return BagDataLen;
            }
            
            /// <summary>
            /// 校验数据包
            /// </summary>
            /// <param name="BagStr"></param>
            /// <returns></returns>
            public static bool CheckBag(string BagHead, string BagEnd, BagStruct Struct, string BagStr, out int RealDataLen)
            {
                bool IsRight = true;
                RealDataLen = 0;
                BagStr = BagStr.Replace(" ", "");
                //校验包头,包尾
                if (!(BagStr.StartsWith(BagHead) && BagStr.EndsWith(BagEnd)))
                {
                    IsRight = IsRight && false;
                }
    
                #region 校验包总长度
                int CurTotalBagLen = Struct.Head.Length + Struct.Cmd.Length + Struct.Other.Length + Struct.DataLen.Length + Struct.VerifyLen + Struct.EndLen;
                if (BagStr.Length < Struct.DataLen.StartPosition + Struct.DataLen.Length)
                {
                    IsRight = IsRight && false;
                }
                else
                {
                    string CurDataLen = "";
                    string CurDataLenOrg = BagStr.Substring(Struct.DataLen.StartPosition * 2, Struct.DataLen.Length * 2);
                    if (Struct.ByteOrder == 1)//高字节在后,低字节在前
                    {
                        CurDataLen = ReverseStr(CurDataLenOrg, 2);
                        //for (int i = Struct.DataLen.Length; i > 0; i--)
                        //{
                        //    CurDataLen += CurDataLenOrg.Substring((i - 1) * 2, 2);
                        //}
                        RealDataLen = Convert.ToInt32(CurDataLen, 16);
                    }
                    else
                    {
                        CurDataLen = CurDataLenOrg;
                        RealDataLen = Convert.ToInt32(CurDataLen, 10);//华气特殊
                    }
                    CurTotalBagLen += RealDataLen;
                    if (BagStr.Length / 2 != CurTotalBagLen)
                    {
                        IsRight = IsRight && false;
                    }
                }
                #endregion
    
                return IsRight;
            }
    
            /// <summary>
            /// 反转字符串
            /// </summary>
            /// <param name="Str"></param>
            /// <param name="Len"></param>
            /// <returns></returns>
            public static string ReverseStr(string Str, int Len)
            {
                Str = Str.Replace(" ", "");
                string NewStr = "";
                List<string> ls = new List<string>();
                for (int i = 0; i < Str.Length; i += Len)
                {
                    ls.Add(Str.Substring(i, Len)); // 两两截取
                }
                ls.Reverse();// 两两反转
                foreach (string item in ls)
                {
                    NewStr += item;
                }
                return NewStr;
            }
    
            /// <summary>   
            /// 16进制字符串转字节数组   
            /// </summary>   
            /// <param name="hexString"></param>   
            /// <returns></returns>   
            public static byte[] strToHexByte(string hexString)
            {
                hexString = hexString.Replace(" ", "");
                if ((hexString.Length % 2) != 0)
                    hexString += " ";
                byte[] returnBytes = new byte[hexString.Length / 2];
                for (int i = 0; i < returnBytes.Length; i++)
                    returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Trim(), 16);
                return returnBytes;
            }
        }
    }

    创建数据接收

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO.Ports;
    
    namespace SerialPortSpace
    {
        /// <summary>
        /// 接收数据类
        /// </summary>
        public class PortReciveDataItem
        {
            public BagItemContent ReciveDataItem { get; set; }
            public DateTime ReciveTime { get; set; }
            public string ReciveDataStr { get; set; }
        }
        
        /// <summary>
        /// 串口缓存数据
        /// </summary>
        public class ComPort
        {
            /// <summary>
            /// 串口
            /// </summary>
            public SerialPort Port
            {
                set;
                get;
            }
            
            /// <summary>
            /// 当前串口名称
            /// </summary>
            public string PortRealName
            {
                set;
                get;
            }
            
            /// <summary>
            /// 当前串口描述
            /// </summary>
            public string PortDesc
            {
                set;
                get;
            }
    
            /// <summary>
            /// 当前串口是否正在接收数据---关闭串口判断
            /// </summary>
            public bool PortIsRcving
            {
                set;
                get;
            }
    
            /// <summary>
            /// 最近返回数据时间
            /// </summary>
            public DateTime LastRebackTime
            {
                get;
                set;
            }
    
            /// <summary>
            /// 定义接收包结构
            /// </summary>
            public BagStruct RcvBag
            {
                get;
                set;
            }
            
            /// <summary>
            /// 开始字符
            /// </summary>
            public string StartStr
            {
                set;
                get;
            }
    
            /// <summary>
            /// 结束字符
            /// </summary>
            public string EndStr
            {
                set;
                get;
            }
            /// <summary>
            /// 串口发送是指令集合
            /// </summary>
            public List<string> SendOrder
            {
                set;
                get;
            }
    
            /// <summary>
            /// 存储不完整包 临时数据
            /// </summary>
            public string RcvData
            {
                set;
                get;
            }
            
            /// <summary>
            /// 接收到的串口数据--完整包,临时存放
            /// </summary>
            public List<PortReciveDataItem> RcvLst
            {
                set;
                get;
            }
        }
    
        /// <summary>
        /// 接收包的结构定义
        /// </summary>
        public class BagStruct
        {
            /// <summary>
            /// 字节顺序约定 0--高字节在前,低字节在后,1--高字节在后,低字节在前
            /// </summary>
            public int ByteOrder
            {
                set;
                get;
            }
            /// <summary>
            /// 包头所占字节数
            /// </summary>
            public BagItemPosition Head
            {
                set;
                get;
            }
            /// <summary>
            /// 命令字段所占字节数
            /// </summary>
            public BagItemPosition Cmd
            {
                set;
                get;
            }
            /// <summary>
            /// 除实际数据包中数据长度及实际数据以外的其他数据项所占字节数
            /// </summary>
            public BagItemPosition Other
            {
                set;
                get;
            }
    
            /// <summary>
            /// 数据字段长度项所占字节数
            /// </summary>
            public BagItemPosition DataLen
            {
                set;
                get;
            }
    
            /// <summary>
            /// 实际数据所占字节数---可变的,可以根据实际数据包由DataLen计算所得
            /// </summary>
            public int RealDataPos//开始位置
            {
                set;
                get;
            }
    
            /// <summary>
            /// 校验位所占字节数
            /// </summary>
            public int VerifyLen
            {
                set;
                get;
            }
    
            /// <summary>
            /// 包尾所占字节数
            /// </summary>
            public int EndLen
            {
                set;
                get;
            }
        }
        /// <summary>
        /// 定义数据包中每项的开始位置及所占字节数
        /// </summary>
        public class BagItemPosition
        {
            /// <summary>
            /// 开始位置
            /// </summary>
            public int StartPosition
            {
                set;
                get;
            }
            /// <summary>
            /// 所占字节数
            /// </summary>
            public int Length
            {
                set;
                get;
            }
        }
    
        /// <summary>
        /// 接收包的结构内容
        /// </summary>
        public class BagItemContent
        {
            /// <summary>
            /// 包头
            /// </summary>
            public string Head
            {
                set;
                get;
            }
    
            /// <summary>
            /// 命令字段
            /// </summary>
            public string Cmd
            {
                set;
                get;
            }
    
            /// <summary>
            /// 除实际数据包中数据长度及实际数据以外的其他数据项
            /// </summary>
            public string Other
            {
                set;
                get;
            }
    
            /// <summary>
            /// 数据字段长度项
            /// </summary>
            public string DataLen
            {
                set;
                get;
            }
    
            /// <summary>
            /// 实际数据
            /// </summary>
            public string RealData
            {
                set;
                get;
            }
    
            /// <summary>
            /// 校验位
            /// </summary>
            public string Verify
            {
                set;
                get;
            }
    
            /// <summary>
            /// 包尾
            /// </summary>
            public string End
            {
                set;
                get;
            }
        }   
    
        
    }

    转载地址:https://www.cnblogs.com/TBW-Superhero/p/6839545.html

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO.Ports;using System.Threading;using LogSpace;
    namespace SerialPortSpace{    public class SerialPortFun    {        /// <summary>        /// 串口及串口缓存数据        /// </summary>        public static List<ComPort> LstComPort = new List<ComPort>();
            /// <summary>        /// 是否在进行串口结束操作        /// </summary>        public static bool PortIsCloseing = false;
            /// <summary>        /// 初始化串口,并返回当前串口的结构        /// </summary>        /// <param name="Port"></param>        /// <param name="PortNo"></param>        /// <param name="BaudRate"></param>        /// <param name="ReciveData"></param>        public static ComPort InitSerialPort(SerialPort Port, string PortNo, int BaudRate, BagStruct CurBagStruct, string StartStr, string EndStr, string PortNameDesc, string PortRemark)        {            Port.PortName = PortNo;            Port.BaudRate = BaudRate;            Port.DataBits = 8;            Port.Parity = Parity.None;            Port.StopBits = StopBits.One;            Port.NewLine = " ";            Port.WriteTimeout = 5000;            Port.ReadTimeout = 5000;            Port.Handshake = Handshake.None;            Port.ReceivedBytesThreshold = 1;            Port.RtsEnable = true;            Port.DataReceived += Port_DataReceived;//定义接收数据事件
                ComPort PortItem = new ComPort();            PortItem.Port = Port;            PortItem.PortRealName = PortNameDesc;            PortItem.PortDesc = PortRemark;            PortItem.PortIsRcving = false;            PortItem.LastRebackTime = DateTime.Now;            PortItem.RcvBag = CurBagStruct;            PortItem.StartStr = StartStr;            PortItem.EndStr = EndStr;            PortItem.SendOrder = new List<string>();
                PortItem.RcvData = string.Empty;            PortItem.RcvLst = new List<PortReciveDataItem>();            if (LstComPort.Count(c => c.Port == Port) > 0)            {                LstComPort.RemoveAll(c => c.Port == Port);            }            LstComPort.Add(PortItem);            return PortItem;        }        /// <summary>        /// 定义数据包中每项的开始位置及所占字节数        /// </summary>        /// <param name="StartPosition"></param>        /// <param name="Length"></param>        /// <returns></returns>        public static BagItemPosition SetBagItemPosition(int StartPosition, int Length)        {            BagItemPosition Item = new BagItemPosition();            Item.StartPosition = StartPosition;            Item.Length = Length;            return Item;        }
            /// <summary>        /// 定义返回数据包结构        /// </summary>        /// <param name="ByteOrder">字节顺序约定 0--高字节在前,低字节在后,1--高字节在后,低字节在前</param>        /// <param name="HeadItem">包头所占字节数</param>        /// <param name="HeadItem">命令所占字节数</param>        /// <param name="OthItem">其他位总共占字节数</param>        /// <param name="DataLenItem">数据长度位所占字节数</param>        /// <param name="VerItem">校验位所占字节数</param>        /// <param name="EndItem">包尾所占字节数</param>        /// <returns></returns>        public static BagStruct SetBagStruct(int ByteOrder, BagItemPosition HeadItem, BagItemPosition CmdItem, BagItemPosition OthItem, BagItemPosition DataLenItem, int RealDataItem, int VerItem, int EndItem)        {            BagStruct CurRcvBagStruct = new BagStruct();            CurRcvBagStruct.ByteOrder = ByteOrder;            CurRcvBagStruct.Head = HeadItem;            CurRcvBagStruct.Cmd = CmdItem;            CurRcvBagStruct.Other = OthItem;            CurRcvBagStruct.DataLen = DataLenItem;            CurRcvBagStruct.RealDataPos = RealDataItem;            CurRcvBagStruct.VerifyLen = VerItem;            CurRcvBagStruct.EndLen = EndItem;            return CurRcvBagStruct;        }
            /// <summary>        /// 打开串口        /// </summary>        /// <param name="PortName"></param>        public static void OpenSerialPort(SerialPort Port)        {            if (!Port.IsOpen)            {                Port.Open();            }        }               /// <summary>        /// 发送串口数据        /// </summary>        /// <param name="Port"></param>        /// <param name="Data"></param>        public static bool SetPortData(SerialPort Port, string Data)        {            bool CurSendFlag = false;            if (Port.IsOpen)            {                byte[] buf = strToHexByte(Data);                Port.Write(buf, 0, buf.Length);                CurSendFlag = true;            }            return CurSendFlag;        }
            #region 接收串口应答包
            /// <summary>        /// 接收串口应答包        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        public static void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)        {            if (PortIsCloseing)            {                return;            }            SerialPort port = sender as SerialPort;            DateTime CurTime = DateTime.Now;            string RcvData = string.Empty;            if (LstComPort != null)            {                if (LstComPort.Count(c => c.Port.PortName == port.PortName) > 0)                {                    ComPort comPort = LstComPort.Find(c => c.Port.PortName == port.PortName);                    try                    {                        Log.WriteLogToLocal(CurTime + "接收前" + comPort.PortRealName + "数据包临时数据: " + comPort.RcvData + " ------------------------ ", "Log\IBO_LOG", comPort.PortDesc + "_Receive");                        RcvData = comPort.RcvData;                        comPort.PortIsRcving = true;//正在接收串口数据                        StringBuilder CurRcvData = new StringBuilder();                        if (port.IsOpen && port.BytesToRead != 0)                        {                            while (port.BytesToRead != 0)                            {                                byte[] recvBytes = new byte[port.BytesToRead];                                int bytes = port.Read(recvBytes, 0, recvBytes.Length);                                if (recvBytes.Length != 0)                                {                                    foreach (byte b in recvBytes)                                    {                                        CurRcvData.Append(b.ToString("X2") + " ");                                    }                                }                                //Thread.Sleep(20);                            }                            Log.WriteLogToLocal(CurTime + "接收" + comPort.PortRealName + "原始数据: " + CurRcvData + " ------------------------ ", "Log\IBO_LOG", comPort.PortDesc + "_Receive");                            RcvData += CurRcvData;                            CurRcvData.Clear();                            //接收到的数据进行处理,并存储在串口对应的接收队列中                            //SerialPortFun.DealPortData(comPort, RcvData, CurTime);                            SerialPortFun.ConcatFullBag(comPort, comPort.RcvBag, RcvData, CurTime);                            comPort.LastRebackTime = CurTime;                        }                    }                    catch (Exception ex)                    {                        Log.WriteLogToLocal(CurTime + "接收" + comPort.PortRealName + "串口数据(" + RcvData + ")错误:(" + ex.Message+")"+ex.StackTrace + " ", "Log\IBO_LOG\ErrorLog", comPort.PortDesc + "_Receive");                    }                    finally                    {                        comPort.PortIsRcving = false;//接收串口数据完毕                    }                }            }        }
            #endregion        /// <summary>        /// 接收到的数据进行处理,并存储在串口对应的接收队列中        /// </summary>        /// <param name="port"></param>        /// <param name="Struct"></param>        /// <param name="CurRcvData"></param>        /// <param name="CurTime"></param>        public static void ConcatFullBag(ComPort port, BagStruct Struct, string CurRcvData, DateTime CurTime)        {            Log.WriteLogToLocal(CurTime + "数据包处理" + port.PortRealName + "原始数据: " + CurRcvData + " ------------------------ ", "Log\IBO_LOG", port.PortDesc + "_Receive");            string temp = CurRcvData;            while (true)            {                //校验包头,包尾                if (!temp.StartsWith(port.StartStr))                {                    int index = temp.IndexOf(port.StartStr);                    if (index == -1)                        temp = "";                    else                        temp = temp.Remove(0, index);                }                if (temp.Length > 0)                {                    int NoDataBagLen = Struct.Head.Length + Struct.Cmd.Length + Struct.Other.Length + Struct.DataLen.Length + Struct.VerifyLen + Struct.EndLen;                    int BagDataLen = 0;                    if (temp.Length > (Struct.DataLen.StartPosition * 3 + Struct.DataLen.Length * 3))                    {                        #region 获取数据包的业务数据长度                        BagDataLen = GetBagDataLen(Struct, temp);                        //string CurDataLen = "";                        //string CurDataLenOrg = temp.Substring(Struct.DataLen.StartPosition * 3, Struct.DataLen.Length * 3);                        //if (Struct.ByteOrder == 1)//高字节在后,低字节在前                        //{                        //    CurDataLen = ReverseStr(CurDataLenOrg, 2);                        //    BagDataLen = Convert.ToInt32(CurDataLen, 16);//16进制                        //}                        //else                        //{                        //    CurDataLen = CurDataLenOrg;                        //    BagDataLen = Convert.ToInt32(CurDataLen, 10);//华气特殊 10进制                        //}                        #endregion                    }                    if (BagDataLen > 0 && temp.Length / 3 >= NoDataBagLen + BagDataLen)                    {                        string FullBag = temp.Substring(0, (NoDataBagLen + BagDataLen) * 3);                        BagItemContent CurBagItem = new BagItemContent();                        CurBagItem.Head = FullBag.Substring(Struct.Head.StartPosition * 3, Struct.Head.Length * 3).Replace(" ", "");                        CurBagItem.Cmd = FullBag.Substring(Struct.Cmd.StartPosition * 3, Struct.Cmd.Length * 3).Replace(" ", "");                        CurBagItem.Other = FullBag.Substring(Struct.Other.StartPosition * 3, Struct.Other.Length * 3).Replace(" ", "");                        CurBagItem.DataLen = FullBag.Substring(Struct.DataLen.StartPosition * 3, Struct.DataLen.Length * 3).Replace(" ", "");                        CurBagItem.RealData = FullBag.Substring(Struct.RealDataPos * 3, BagDataLen * 3);                        CurBagItem.Verify = FullBag.Substring(FullBag.Length - (Struct.VerifyLen + Struct.EndLen) * 3, Struct.VerifyLen * 3).Replace(" ", "");                        CurBagItem.End = FullBag.Substring(FullBag.Length - Struct.EndLen * 3, Struct.EndLen * 3).Replace(" ", "");                        if (Struct.ByteOrder == 1)//高字节在后,低字节在前                        {                            CurBagItem.Head = Struct.Head.Length <= 1 ? CurBagItem.Head : ReverseStr(CurBagItem.Head, 2);                            CurBagItem.Cmd = (Struct.Cmd.Length <= 1 ? CurBagItem.Cmd : ReverseStr(CurBagItem.Cmd, 2));                            CurBagItem.DataLen = Struct.DataLen.Length <= 1 ? CurBagItem.DataLen : ReverseStr(CurBagItem.DataLen, 2);                            //CurBagItem.RealData,CurBagItem.Other需根据具体情况解析暂不反转                            //CurBagItem.RealData = RealDataLen <= 1 ? CurBagItem.RealData : ReverseStr(CurBagItem.RealData, 2);                            //CurBagItem.Other = Struct.Other.Length <= 1 ? CurBagItem.Other : ReverseStr(CurBagItem.Other, 2);                            CurBagItem.Verify = Struct.VerifyLen <= 1 ? CurBagItem.Verify : ReverseStr(CurBagItem.Verify, 2);                            CurBagItem.End = Struct.EndLen <= 1 ? CurBagItem.End : ReverseStr(CurBagItem.End, 2);                        }                        PortReciveDataItem NewItem = new PortReciveDataItem();                        NewItem.ReciveTime = CurTime;                        NewItem.ReciveDataItem = CurBagItem;                        NewItem.ReciveDataStr = FullBag;                        port.RcvLst.Add(NewItem);                        Log.WriteLogToLocal(CurTime + "加入" + port.PortRealName + "完整数据包: " + FullBag + " ------------------------ ", "Log\IBO_LOG", port.PortDesc + "_Receive");                        temp = temp.Remove(0, FullBag.Length);                        if (temp.Length <= 0)                        {                            port.RcvData = "";                            break;                        }                       // port.RcvData = temp.Substring((NoDataBagLen + BagDataLen) * 3);//剩余字符放入下个数据包                    }                    else                    {                        port.RcvData = CurRcvData;//不是完整包,等待完整数据                        break;                    }                }                else                {                    //丢弃不符合的串口数据                    port.RcvData = "";                    Log.WriteLogToLocal(CurTime + "丢弃" + port.PortRealName + "原始数据: " + CurRcvData + " ------------------------ ", "Log\IBO_LOG", port.PortDesc + "_Receive");                    break;                }            }        }                /// <summary>        /// 获取包长度        /// </summary>        /// <param name="Struct"></param>        /// <param name="AllBagData"></param>        /// <returns></returns>        public static int GetBagDataLen(BagStruct Struct, string AllBagData)        {            int BagDataLen = 0;            string CurDataLen = "";            AllBagData = AllBagData.Replace(" ", "");            string CurDataLenOrg = AllBagData.Substring(Struct.DataLen.StartPosition * 2, Struct.DataLen.Length * 2);            if (Struct.ByteOrder == 1)//高字节在后,低字节在前            {                CurDataLen = ReverseStr(CurDataLenOrg, 2);                BagDataLen = Convert.ToInt32(CurDataLen, 16);//16进制  需改成通用            }            else            {                CurDataLen = CurDataLenOrg;                BagDataLen = Convert.ToInt32(CurDataLen, 10);//华气特殊 10进制            }            return BagDataLen;        }                /// <summary>        /// 校验数据包        /// </summary>        /// <param name="BagStr"></param>        /// <returns></returns>        public static bool CheckBag(string BagHead, string BagEnd, BagStruct Struct, string BagStr, out int RealDataLen)        {            bool IsRight = true;            RealDataLen = 0;            BagStr = BagStr.Replace(" ", "");            //校验包头,包尾            if (!(BagStr.StartsWith(BagHead) && BagStr.EndsWith(BagEnd)))            {                IsRight = IsRight && false;            }
                #region 校验包总长度            int CurTotalBagLen = Struct.Head.Length + Struct.Cmd.Length + Struct.Other.Length + Struct.DataLen.Length + Struct.VerifyLen + Struct.EndLen;            if (BagStr.Length < Struct.DataLen.StartPosition + Struct.DataLen.Length)            {                IsRight = IsRight && false;            }            else            {                string CurDataLen = "";                string CurDataLenOrg = BagStr.Substring(Struct.DataLen.StartPosition * 2, Struct.DataLen.Length * 2);                if (Struct.ByteOrder == 1)//高字节在后,低字节在前                {                    CurDataLen = ReverseStr(CurDataLenOrg, 2);                    //for (int i = Struct.DataLen.Length; i > 0; i--)                    //{                    //    CurDataLen += CurDataLenOrg.Substring((i - 1) * 2, 2);                    //}                    RealDataLen = Convert.ToInt32(CurDataLen, 16);                }                else                {                    CurDataLen = CurDataLenOrg;                    RealDataLen = Convert.ToInt32(CurDataLen, 10);//华气特殊                }                CurTotalBagLen += RealDataLen;                if (BagStr.Length / 2 != CurTotalBagLen)                {                    IsRight = IsRight && false;                }            }            #endregion
                return IsRight;        }
            /// <summary>        /// 反转字符串        /// </summary>        /// <param name="Str"></param>        /// <param name="Len"></param>        /// <returns></returns>        public static string ReverseStr(string Str, int Len)        {            Str = Str.Replace(" ", "");            string NewStr = "";            List<string> ls = new List<string>();            for (int i = 0; i < Str.Length; i += Len)            {                ls.Add(Str.Substring(i, Len)); // 两两截取            }            ls.Reverse();// 两两反转            foreach (string item in ls)            {                NewStr += item;            }            return NewStr;        }
            /// <summary>           /// 16进制字符串转字节数组           /// </summary>           /// <param name="hexString"></param>           /// <returns></returns>           public static byte[] strToHexByte(string hexString)        {            hexString = hexString.Replace(" ", "");            if ((hexString.Length % 2) != 0)                hexString += " ";            byte[] returnBytes = new byte[hexString.Length / 2];            for (int i = 0; i < returnBytes.Length; i++)                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Trim(), 16);            return returnBytes;        }    }}

  • 相关阅读:
    -bash: fork: Cannot allocate memory 问题的处理
    Docker top 命令
    docker常见问题修复方法
    The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
    What's the difference between encoding and charset?
    hexcode of é î Latin-1 Supplement
    炉石Advanced rulebook
    炉石bug反馈
    Sidecar pattern
    SQL JOIN
  • 原文地址:https://www.cnblogs.com/sdxlz666/p/10495496.html
Copyright © 2011-2022 走看看