using NModbus; using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BPASmartClient.Modbus { public class ModbusRTU { #region 参数配置 private static IModbusMaster master; private static IModbusSerialMaster serialMaster; private static ModbusFactory factory; private static SerialPort port; //写线圈或写寄存器数组 private bool[] coilsBuffer; private ushort[] registerBuffer; //功能码 private string functionCode; //串口参数 private string portName; private int baudRate; private Parity parity; private int dataBits; private StopBits stopBits; #endregion #region 串口配置 /// /// 串口参数获取 /// /// public void InitSerialPortParameter(string protName, int bauRate, string currentParity, int dataBits, string currentStopBits) { switch (currentParity) { case "奇": parity = Parity.Odd; break; case "偶": parity = Parity.Even; break; case "无": parity = Parity.None; break; default: break; } switch (currentStopBits) { case "1": stopBits = StopBits.One; break; case "2": stopBits = StopBits.Two; break; default: break; } port = new SerialPort(portName, baudRate, parity, dataBits, stopBits); //master = factory.CreateMaster() } #endregion #region 串口收/发 public async void ExecuteFunctionRecive(string functionCode, byte slaveAddress, ushort startAddress, ushort numberOfPoints) { try { if (port.IsOpen == false) { port.Open(); } if (functionCode != null) { switch (functionCode) { case "01 Read Coils"://读取单个线圈 try { coilsBuffer = master.ReadCoils(slaveAddress, startAddress, numberOfPoints); } catch (Exception) { //MessageBox.Show(e.Message); break; } break; case "02 Read DisCrete Inputs"://读取输入线圈/离散量线圈 try { coilsBuffer = master.ReadInputs(slaveAddress, startAddress, numberOfPoints); } catch (Exception) { break; } break; case "03 Read Holding Registers"://读取保持寄存 try { registerBuffer = master.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints); } catch (Exception) { break; } break; case "04 Read Input Registers"://读取输入寄存器 try { registerBuffer = master.ReadInputRegisters(slaveAddress, startAddress, numberOfPoints); } catch (Exception) { break; } break; default: break; } } port.Close(); } catch (Exception ex) { port.Close(); } } public async void ExecuteFunctionSend(string data, byte slaveAddress, ushort startAddress) { try { if (port.IsOpen == false) { port.Open(); } if (functionCode != null) { switch (functionCode) { case "05 Write Single Coil"://写单个线圈 SetWriteParametes(data,true); await master.WriteSingleCoilAsync(slaveAddress, startAddress, coilsBuffer[0]); break; case "06 Write Single Registers"://写单个输入线圈/离散量线圈 SetWriteParametes(data,true); await master.WriteSingleRegisterAsync(slaveAddress, startAddress, registerBuffer[0]); break; case "0F Write Multiple Coils"://写一组线圈 SetWriteParametes(data); await master.WriteMultipleCoilsAsync(slaveAddress, startAddress, coilsBuffer); break; case "10 Write Multiple Registers"://写一组保持寄存器 SetWriteParametes(data); await master.WriteMultipleRegistersAsync(slaveAddress, startAddress, registerBuffer); break; default: break; } } port.Close(); } catch (Exception ex) { port.Close(); } } #endregion /// /// 设置写参数 /// private void SetWriteParametes(string data,bool isParametes =false) { //判断是否写线圈 if (isParametes) { string[] strarr = data.Split(' '); coilsBuffer = new bool[strarr.Length]; //转化为bool数组 for (int i = 0; i < strarr.Length; i++) { // strarr[i] == "0" ? coilsBuffer[i] = false : coilsBuffer[i] = true; if (strarr[i] == "0") { coilsBuffer[i] = false; } else { coilsBuffer[i] = true; } } } else { //转化ushort数组 string[] strarr = data.Split(' '); registerBuffer = new ushort[strarr.Length]; for (int i = 0; i < strarr.Length; i++) { registerBuffer[i] = ushort.Parse(strarr[i]); } } } } }