创建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 = ;
Port.Parity = Parity.None;
Port.StopBits = StopBits.One;
Port.NewLine = "\r\n";
Port.WriteTimeout = ;
Port.ReadTimeout = ;
Port.Handshake = Handshake.None;
Port.ReceivedBytesThreshold = ;
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) > )
{
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, , 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) > )
{
ComPort comPort = LstComPort.Find(c => c.Port.PortName == port.PortName);
try
{
Log.WriteLogToLocal(CurTime + "接收前" + comPort.PortRealName + "数据包临时数据:\r\n" + comPort.RcvData + "\r\n------------------------\r\n", "Log\\IBO_LOG", comPort.PortDesc + "_Receive");
RcvData = comPort.RcvData;
comPort.PortIsRcving = true;//正在接收串口数据
StringBuilder CurRcvData = new StringBuilder();
if (port.IsOpen && port.BytesToRead != )
{
while (port.BytesToRead != )
{
byte[] recvBytes = new byte[port.BytesToRead];
int bytes = port.Read(recvBytes, , recvBytes.Length);
if (recvBytes.Length != )
{
foreach (byte b in recvBytes)
{
CurRcvData.Append(b.ToString("X2") + " ");
}
}
//Thread.Sleep(20);
}
Log.WriteLogToLocal(CurTime + "接收" + comPort.PortRealName + "原始数据:\r\n" + CurRcvData + "\r\n------------------------\r\n", "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 + "\r\n", "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 + "原始数据:\r\n" + CurRcvData + "\r\n------------------------\r\n", "Log\\IBO_LOG", port.PortDesc + "_Receive");
string temp = CurRcvData;
while (true)
{
//校验包头,包尾
if (!temp.StartsWith(port.StartStr))
{
int index = temp.IndexOf(port.StartStr);
if (index == -)
temp = "";
else
temp = temp.Remove(, index);
}
if (temp.Length > )
{
int NoDataBagLen = Struct.Head.Length + Struct.Cmd.Length + Struct.Other.Length + Struct.DataLen.Length + Struct.VerifyLen + Struct.EndLen;
int BagDataLen = ;
if (temp.Length > (Struct.DataLen.StartPosition * + Struct.DataLen.Length * ))
{
#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 > && temp.Length / >= NoDataBagLen + BagDataLen)
{
string FullBag = temp.Substring(, (NoDataBagLen + BagDataLen) * );
BagItemContent CurBagItem = new BagItemContent();
CurBagItem.Head = FullBag.Substring(Struct.Head.StartPosition * , Struct.Head.Length * ).Replace(" ", "");
CurBagItem.Cmd = FullBag.Substring(Struct.Cmd.StartPosition * , Struct.Cmd.Length * ).Replace(" ", "");
CurBagItem.Other = FullBag.Substring(Struct.Other.StartPosition * , Struct.Other.Length * ).Replace(" ", "");
CurBagItem.DataLen = FullBag.Substring(Struct.DataLen.StartPosition * , Struct.DataLen.Length * ).Replace(" ", "");
CurBagItem.RealData = FullBag.Substring(Struct.RealDataPos * , BagDataLen * );
CurBagItem.Verify = FullBag.Substring(FullBag.Length - (Struct.VerifyLen + Struct.EndLen) * , Struct.VerifyLen * ).Replace(" ", "");
CurBagItem.End = FullBag.Substring(FullBag.Length - Struct.EndLen * , Struct.EndLen * ).Replace(" ", "");
if (Struct.ByteOrder == )//高字节在后,低字节在前
{
CurBagItem.Head = Struct.Head.Length <= ? CurBagItem.Head : ReverseStr(CurBagItem.Head, );
CurBagItem.Cmd = (Struct.Cmd.Length <= ? CurBagItem.Cmd : ReverseStr(CurBagItem.Cmd, ));
CurBagItem.DataLen = Struct.DataLen.Length <= ? CurBagItem.DataLen : ReverseStr(CurBagItem.DataLen, );
//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 <= ? CurBagItem.Verify : ReverseStr(CurBagItem.Verify, );
CurBagItem.End = Struct.EndLen <= ? CurBagItem.End : ReverseStr(CurBagItem.End, );
}
PortReciveDataItem NewItem = new PortReciveDataItem();
NewItem.ReciveTime = CurTime;
NewItem.ReciveDataItem = CurBagItem;
NewItem.ReciveDataStr = FullBag;
port.RcvLst.Add(NewItem);
Log.WriteLogToLocal(CurTime + "加入" + port.PortRealName + "完整数据包:\r\n" + FullBag + "\r\n------------------------\r\n", "Log\\IBO_LOG", port.PortDesc + "_Receive");
temp = temp.Remove(, FullBag.Length);
if (temp.Length <= )
{
port.RcvData = "";
break;
}
// port.RcvData = temp.Substring((NoDataBagLen + BagDataLen) * 3);//剩余字符放入下个数据包
}
else
{
port.RcvData = CurRcvData;//不是完整包,等待完整数据
break;
}
}
else
{
//丢弃不符合的串口数据
port.RcvData = "";
Log.WriteLogToLocal(CurTime + "丢弃" + port.PortRealName + "原始数据:\r\n" + CurRcvData + "\r\n------------------------\r\n", "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 = ;
string CurDataLen = "";
AllBagData = AllBagData.Replace(" ", "");
string CurDataLenOrg = AllBagData.Substring(Struct.DataLen.StartPosition * , Struct.DataLen.Length * );
if (Struct.ByteOrder == )//高字节在后,低字节在前
{
CurDataLen = ReverseStr(CurDataLenOrg, );
BagDataLen = Convert.ToInt32(CurDataLen, );//16进制 需改成通用
}
else
{
CurDataLen = CurDataLenOrg;
BagDataLen = Convert.ToInt32(CurDataLen, );//华气特殊 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 = ;
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 * , Struct.DataLen.Length * );
if (Struct.ByteOrder == )//高字节在后,低字节在前
{
CurDataLen = ReverseStr(CurDataLenOrg, );
//for (int i = Struct.DataLen.Length; i > 0; i--)
//{
// CurDataLen += CurDataLenOrg.Substring((i - 1) * 2, 2);
//}
RealDataLen = Convert.ToInt32(CurDataLen, );
}
else
{
CurDataLen = CurDataLenOrg;
RealDataLen = Convert.ToInt32(CurDataLen, );//华气特殊
}
CurTotalBagLen += RealDataLen;
if (BagStr.Length / != 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 = ; 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 % ) != )
hexString += " ";
byte[] returnBytes = new byte[hexString.Length / ];
for (int i = ; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * , ).Trim(), );
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 = "\r\n";            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 + "数据包临时数据:\r\n" + comPort.RcvData + "\r\n------------------------\r\n", "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 + "原始数据:\r\n" + CurRcvData + "\r\n------------------------\r\n", "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 + "\r\n", "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 + "原始数据:\r\n" + CurRcvData + "\r\n------------------------\r\n", "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 + "完整数据包:\r\n" + FullBag + "\r\n------------------------\r\n", "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 + "原始数据:\r\n" + CurRcvData + "\r\n------------------------\r\n", "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;        }    }}

c# 串口SerialPort的更多相关文章

  1. C#串口SerialPort常用属性方法

    SerialPort(): //属性 .BaudRate;获取或设置波特率 .BytesToRead;得到 接收到数据的字节数 .BytesToWrites;得到送往串口的字节数 .DataBits; ...

  2. (转)C#串口SerialPort常用属性方法

    SerialPort(): //属性 .BaudRate;获取或设置波特率 .BytesToRead;得到 接收到数据的字节数 .BytesToWrites;得到送往串口的字节数 .DataBits; ...

  3. 使用Java进行串口SerialPort通讯

    1.准备工作        在进行串口连接通讯前,必须保证你当前操作电脑上有可用且闲置的串口.因为一般的电脑上只有一个或者两个串口,如COM1或COM2,但大多数情况下,这些串口可能会被其他的程序或者 ...

  4. C#串口serialPort操作

    现在大多数硬件设备均采用串口技术与计算机相连,因此串口的应用程序开发越来越普遍.例如,在计算机没有安装网卡的情况下,将本机上的一些信息数据 传输到另一台计算机上,那么利用串口通信就可以实现.运行本程序 ...

  5. C# 通过SerialPort简单调用串口

    问题 最近比较经常使用串口进行发送以及传输数据,但是笔者在刚开始接触SerialPort类时,对于Write之后去Read数据的时候,由于设备上面还没有返回数据,读取到的只能是空值.然而,再进行下一次 ...

  6. C# 串口接收数据中serialPort.close()死锁

    最近在做一个有关高铁模拟仓显示系统的客户端程序,在这个程序中要运用串口serialPort传输数据,因为每次接收数据结束后要更新UI界面,所以就用到了的Invoke,将更新UI的程序代码封装到一个方法 ...

  7. Visual studio之C# 串口通讯SerialPort

    背景 App需要串口进行通讯,在此做个记录和简要说明. 正文 添加命名空间 using System.IO.Ports; 实例化串口 SerialPort serialPortO = new Seri ...

  8. C#上位机制作之串口接受数据(利用接受事件)

    前面设计好了界面,现在就开始写代码了,首先定义一个串口对象.. SerialPort serialport = new SerialPort();//定义串口对象 添加串口扫描函数,扫描出来所有可用串 ...

  9. C# 对串口的操作

    初始化 串口 SerialPort sp = new SerialPort(); sp.PortName = BasicParameters.IniReadValue(strPath, "C ...

随机推荐

  1. 7.Flask文件上传

     1.1.上传文件和访问上传的文件 upload_file_demo.py from flask import Flask,request,render_template import os from ...

  2. 《前端之路》之 Cookie && localStorage && Session Storage 缓存相关

    08: Cookie && localStorage && Session Storage 缓存相关 客户端.前端 存储 一. 起 因 首先解释下为什么想来写这个关于前 ...

  3. LVS(二)NAT模型配置

    NAT配置模式 环境说明 LVS服务器(在eth0:0上设置VIP为:192.168.159.200/24) Eth0:192.168.159.133/24   GW:192.168.159.2 Et ...

  4. sql servse 查询当前库内表索引值

    PERCENT --a.id, THEN c.name ELSE '' END AS 表名, THEN a.name ELSE '' END AS 索引名称, d.name AS 列名, b.keyn ...

  5. 使用wepy开发微信小程序01——常用的组件

    1.axio.js 'use strict' import axios from 'axios' import wepyAxiosAdapter from 'wepy-plugin-axios/dis ...

  6. .NET Framework框架介绍

    1.内容 .net framework c#和.net关系 掌握C#中命名空间2..net 就是微软提供的一个开发平台 版本: vs2008 3.5 vs2010 4.0 vs2012 2013 20 ...

  7. Linux系统上安装MySQL(rpm)

    1.准备工作 从MySQL官网上分别下载mysql服务器端于客户端包. 如: MySQL-server-5.5.15-1.linux2.6.x86_64.rpm和MySQL-client-5.5.15 ...

  8. nginx系列6:nginx的进程结构

    nginx的进程结构 如下图: 通过ps –ef | grep nginx可以看到共有三个进程,一个master进程,两个worker进程. nginx是多进程结构,多进程结构设计是为了保证nginx ...

  9. Odoo的模块和应用程序的区别和使用

    一.模块(modules)和应用程序(application)的区别: 模块元件是Odoo应用程序的组成快.模块可以将新功能添加到Odoo,或改变现有功能.模块是一个包含名为__manifest__. ...

  10. ElasticSearch head 插件安装

    head 客户端可以很方便在上面创建索引,类型,文档,还有查询,使用它管理elasticsearch 提高效率. 在安装head 客户端之前必须安装node.js 环境,因为它是用node.js 编写 ...