using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO.Ports; namespace Mesnac.Equip.OMRON.HostLink { /// /// 串口工厂类 /// public class SerialPortFactory { #region 单例实现 private static SerialPortFactory _instance = null; //串口工厂实例 private SerialPort _mainSerialPort = null; //主串口对象 private string _recivedResultMsg = String.Empty; //串口接收结果字符串 private string _lastRecivedMsg = String.Empty; //保存最后一次接收的完整信息 private string _stationNum = "00"; //站号 private string _portName = "COM1"; //端口号 private int _baudRate = 9600; //波特率 private Parity _parity = Parity.Even; //校验位 private int _dataBits = 7; //数据位 private StopBits _stopBits = StopBits.Two; //停止位 private int _buffSize = 1024; //缓冲区大小 private SerialPortFactory(string stationNum, string portName, int baudRate, string parity, int dataBits, string stopBits, int buffSize) { this._stationNum = stationNum; this._portName = portName; this._baudRate = baudRate; this._parity = ConvertToParity(parity); this._dataBits = dataBits; this._stopBits = ConvertToStopBits(stopBits); this._buffSize = buffSize; this._mainSerialPort = new SerialPort(); this._mainSerialPort.PortName = this._portName; this._mainSerialPort.BaudRate = this._baudRate; this._mainSerialPort.Parity = this._parity; this._mainSerialPort.DataBits = this._dataBits; this._mainSerialPort.StopBits = this._stopBits; this._mainSerialPort.ReadBufferSize = this._buffSize; this._mainSerialPort.WriteBufferSize = this._buffSize; this._mainSerialPort.ReceivedBytesThreshold = 1; this._mainSerialPort.Handshake = Handshake.None; //this._mainSerialPort.DataReceived += new SerialDataReceivedEventHandler(_mainSerialPort_DataReceived); } /// /// 获取串口工厂实例 /// /// 站号 /// 端口号 /// 波特率 /// 校验位 /// 数据位 /// 停止位 /// 缓冲区大小 /// 返回串口工厂实例 public static SerialPortFactory GetInstance(string stationNum, string portName, int baudRate, string parity, int dataBits, string stopBits, int buffSize) { if (_instance == null) { _instance = new SerialPortFactory(stationNum, portName, baudRate, parity, dataBits, stopBits, buffSize); } return _instance; } /// /// 主串口对象 /// public SerialPort MainSerialPort { get { return this._mainSerialPort; } } /// /// 最后一次接收的完整信息 /// public string RecivedResultMsg { get { return _recivedResultMsg; } } #endregion #region 从串口读取数据 /// /// 从串口读取数据 /// /// 块号 /// 起始地址 /// 长度 /// 数据缓冲区 /// 返回结果吗 public string Read(int block, int start, int len, out int[] buff) { lock (this) { if (this._mainSerialPort.IsOpen) { this._mainSerialPort.DiscardOutBuffer(); start = block + start; string WriteBit = String.Format("@{0}RD{1}", this._stationNum, this.FillZero(start.ToString(), 4)); WriteBit += this.FillZero(len.ToString(), 4); this._mainSerialPort.Write(FCS(WriteBit)); System.Threading.Thread.Sleep(2); string temp1 = this._mainSerialPort.ReadExisting(); this._mainSerialPort.DiscardOutBuffer(); this._recivedResultMsg += temp1; while (String.IsNullOrEmpty(temp1) || temp1.Substring(temp1.Length - 1, 1) != "\r") { temp1 = this._mainSerialPort.ReadExisting(); this._recivedResultMsg += temp1; this._mainSerialPort.DiscardOutBuffer(); System.Threading.Thread.Sleep(2); } this._lastRecivedMsg = this._recivedResultMsg; this._recivedResultMsg = String.Empty; if (String.IsNullOrEmpty(this._recivedResultMsg) && !String.IsNullOrEmpty(this._lastRecivedMsg)) { buff = new int[len]; for (int i = 0; i < len; i++) { if (this._lastRecivedMsg.Length > 7 + i * 4) { string temp = ToDEC(this._lastRecivedMsg.Substring(7 + i * 4, 4));//this.HEX2DEC( buff[i] = 0; if ((block >= 3016 && block <= 3023) || block==3005) { int.TryParse(this.HEX2DEC(temp),out buff[i]); } else int.TryParse(temp, out buff[i]); } else { break; } } return GetReturnCode(this._lastRecivedMsg); } buff = new int[] { 0 }; return String.Empty; } else { buff = new int[] { 0 }; return "COM is Not Open!"; } } } #endregion #region 向串口写数据 /// /// 向串口写数据 /// /// 块号 /// 起始地址 /// 要写入的数 /// 返回结果码 public string Write(int block, int start, int[] buff) { lock (this) { if (this._mainSerialPort.IsOpen) { this._mainSerialPort.DiscardOutBuffer(); //string WriteBit = null; //WriteBit = "@00WD0000" + DEC2HEX(TextBox_DEC.Text); start = block + start; string WriteBit = String.Format("@{0}WD{1}", this._stationNum, this.FillZero(start.ToString(), 4)); for (int i = 0; i < buff.Length; i++) { WriteBit += DectoBCD(buff[i].ToString());//DEC2HEX( } this._mainSerialPort.Write(FCS(WriteBit)); System.Threading.Thread.Sleep(2); string temp1 = this._mainSerialPort.ReadExisting(); this._mainSerialPort.DiscardOutBuffer(); this._recivedResultMsg += temp1; while (String.IsNullOrEmpty(temp1) || temp1.Substring(temp1.Length - 1, 1) != "\r") { temp1 = this._mainSerialPort.ReadExisting(); this._recivedResultMsg += temp1; this._mainSerialPort.DiscardOutBuffer(); System.Threading.Thread.Sleep(1); } this._lastRecivedMsg = this._recivedResultMsg; this._recivedResultMsg = String.Empty; return GetReturnCode(this._lastRecivedMsg); } else { return "COM is Not Open!"; } } } #endregion #region 辅助方法 #region 获取响应码 /// /// 获取响应码 /// /// 响应字符串 /// 获取响应码 public string GetReturnCode(string responseStr) { if (!String.IsNullOrEmpty(responseStr) && responseStr.Length >= 7) { return responseStr.Substring(5, 2); } return String.Empty; } #endregion #region "按字符串位数补0" /// /// 按字符串位数补0 /// /// 字符串 /// 字符长度 /// public string FillZero(string CharTxt, int CharLen) { if (CharTxt.Length < CharLen) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < CharLen - CharTxt.Length; i++) { sb.Append("0"); } sb.Append(CharTxt); return sb.ToString(); } else { return CharTxt; } } #endregion #region 对指令及数据的字符串进行最终FCS运算,并添加“*CR” /// /// 对指令及数据的字符串进行最终FCS运算,并添加“*CR” /// /// 要进行FCS运算的字符串 /// 返回经过FCS运算后的结果 public string FCS(string Str) //对指令及数据的字符串进行最终FCS运算,并添加“*CR” { char[] chararraytemp = Str.ToCharArray(); int fcs = 0; foreach (char chartemp in chararraytemp) { fcs = fcs ^ Convert.ToInt16(chartemp); //对字符进行ASC转换,并进行异或运算 } string fcstohex = String.Format("{0:X2}", (uint)System.Convert.ToUInt32(fcs)); string result = Str + fcstohex + "*" + Convert.ToChar(13); return result; } #endregion #region 十进制转十六进制 /// /// 十进制转十六进制 /// /// 十进制字符串 /// 返回对应的十六进制字符串 public string DEC2HEX(string ox) { uint ux = 0; if (uint.TryParse(ox, out ux)) { string strHex = String.Format("{0:X4}", ux); //转换为16禁止,{0:X4}大写4位;{0:x4}小写4位 return strHex; } else { return ox; } } #endregion #region 十六进制转十进制 /// /// 十六进制转十进制 /// /// 十六进制字符串 /// 返回对应的十进制字符串 public string HEX2DEC(string ox) { uint test; test = System.Convert.ToUInt32(ox, 16); //转换为10禁止 return test.ToString(); } #endregion #region 类型转换 /// /// 校验位类型转换 /// /// /// private Parity ConvertToParity(string strParity) { Parity result = Parity.None; switch (strParity) { case "None": result = Parity.None; break; case "Odd": result = Parity.Odd; break; case "Even": result = Parity.Even; break; case "Mark": result = Parity.Mark; break; case "Space": result = Parity.Space; break; default: result = Parity.None; break; } return result; } /// /// 停止位类型转换 /// /// /// private StopBits ConvertToStopBits(string strStopBits) { StopBits result = StopBits.None; switch (strStopBits) { case "None": result = StopBits.None; break; case "1": result = StopBits.One; break; case "1.5": result = StopBits.OnePointFive; break; case "2": result = StopBits.Two; break; default: result = StopBits.None; break; } return result; } string DectoBCD(string Dec) { //if (Dec.Length > 4) //{ // return DEC2HEX(Dec); //} //else //{ // string retValue = string.Empty; // for (int j = 0; j < Dec.Length; j++) // { // string bv = string.Empty; // int[] bitValue = ParseBinaryValue(Convert.ToInt32(Dec.Substring(Dec.Length - 1 - j, 1)), 4); // for (int i = 0; i < 4; i++) // { // bv += bitValue[i]; // } // retValue = GetValues(bv)[0] + retValue; // } // return retValue.PadLeft(4, '0'); //} return Dec.PadLeft(4, '0'); } /// /// 解析二进制位 /// /// 要解析的变量 /// 解析的长度 /// 返回解析的二进制值数组 public int[] ParseBinaryValue(int x, int len) { int[] result = new int[len]; int b = 1; for (int i = len - 1; i >= 0; i--) { result[i] = (x & b) == 0 ? 0 : 1; b = b << 1; } return result; } /// /// 二进制转化为十进制 /// /// /// /// public object[] GetValues(string valvestates) { object[] returnvalue = { Convert.ToInt32(valvestates, 2) }; return returnvalue; } public string ToDEC(string ox) { //int dec = Convert.ToInt32(ox, 16); //if (dec.ToString().Length > 4) // return dec.ToString(); //else return ox; } #endregion #endregion } }