/// <summary> /// Modbus读保持寄存器发送主机代码03H /// </summary> public static void timer2Action_SendFc03(byte address, ushort start, ushort registers, FrmMain fm) { if (fm.button1.Text == "关闭串口") { if (SendCount == 0) { if (frameDelayType == false) { SendCount = 1; } else { SendCount = 0; } ModbusRTU.BuildMessage(address, 0x03, start, registers, ref TxBuf); ReadLenth = 2 * ModbusNumRegister + 5;//酱紫使用帧延时模式时只需要计算一次 fm.serialPort1.ReceivedBytesThreshold = ReadLenth; } if (ModbusTimeOut == 0) { if (frameDelayType == false) { SendCommand.SendBytes(TxBuf, TxBuf.Length, fm); ModbusTimeOut = 1; fm.timer1.Enabled = true; SendCount = 0; } else { // byte[] Txtest = new byte[1]; Txtest[0] = TxBuf[SendCount++]; SendCommand.SendOneByte(Txtest, fm); if (SendCount >= TxBuf.Length) {//定时器1用来做帧延时,定时器2做Modbus超时 ModbusTimeOut = 1; fm.timer1.Enabled = true; SendCount = 0; } } } if (SerialRecOk == 1) { ModbusTimeOut = 0; SerialRecOk = 0; SendCount = 0; fm.timer1.Enabled = false; } } else { fm.timer2.Enabled = false; fm.timer1.Enabled = false; } }
/// <summary> /// 处理响应程序 /// </summary> public static void DisposeResponse(byte functionCode, ushort registers, ref ushort[] returnValues, ref byte[] responseData, ushort responseDataLength, ref string CommMessage) { if (functionCode == 0x03) { // byte[] response = new byte[5 + 2 * registers]; if (ModbusRTU.CheckResponse(responseData, responseDataLength)) { if (responseData[1] > 0x80)//属于不正常响应 { ModbusRTU.AbnormalResult((byte)responseData[2], ref CommMessage); // return false; } else { CommMessage = "正常"; for (int i = 0; i < (responseDataLength - 5) / 2; i++) { returnValues[i] = responseData[2 * i + 3]; returnValues[i] <<= 8; returnValues[i] += responseData[2 * i + 4]; } // return true; } } else//CRC错误 { CommMessage = "CRC错误"; /* * //CRC错误也读数出来,避免显示0值 * for (int i = 0; i < (responseData.Length - 5) / 2; i++) * { * returnValues[i] = responseData[2 * i + 3]; * returnValues[i] <<= 8; * returnValues[i] += responseData[2 * i + 4]; * } * */ // return false; } } if (functionCode == 0x10) { if (ModbusRTU.CheckResponse(responseData, responseDataLength)) { if (responseData[1] > 0x80)//属于不正常响应 { ModbusRTU.AbnormalResult((byte)responseData[2], ref CommMessage); // return false; } else { CommMessage = "正常"; for (int i = 0; i < (responseDataLength - 4) / 4; i++) {//返回起始地址和寄存器数量共4个字节,此处先减少为2,因为申请内存的问题 returnValues[i] = responseData[2 * i + 2]; returnValues[i] <<= 8; returnValues[i] += responseData[2 * i + 3]; } // return true; } } else//CRC错误 { CommMessage = "CRC错误"; /* * //CRC错误也读数出来,避免显示0值 * for (int i = 0; i < (responseData.Length - 5) / 2; i++) * { * returnValues[i] = responseData[2 * i + 3]; * returnValues[i] <<= 8; * returnValues[i] += responseData[2 * i + 4]; * } * */ // return false; } } }
/// <summary> /// Modbus写保持寄存器发送主机代码10H /// </summary> public static void timer2Action_SendFc10(byte address, ushort start, ushort registers, ushort[] values, FrmMain fm) { if (fm.button1.Text == "关闭串口") {//此处使用动态内存,当使用帧延时发送时会导致每次都算一遍数据 byte[] message = new byte[9 + 2 * registers]; message[6] = (byte)(registers * 2); //字节计数,寄存器数量*2 message[6] = (byte)(registers * 2); //保存的数据(需写入的数据) for (int i = 0; i < registers; i++) { message[7 + 2 * i] = (byte)(values[i] >> 8); message[8 + 2 * i] = (byte)(values[i]); } ModbusRTU.BuildMessage(address, 0x10, start, registers, ref message); ReadLenth = 8; fm.serialPort1.ReceivedBytesThreshold = ReadLenth; if (SendCount == 0) { if (frameDelayType == false) { SendCount = 1; } else { SendCount = 0; } } if (ModbusTimeOut == 0) { if (frameDelayType == false) { SendCommand.SendBytes(message, message.Length, fm); ModbusTimeOut = 1; fm.timer1.Enabled = true; SendCount = 0; } else { // byte[] Txtest = new byte[1]; Txtest[0] = message[SendCount++]; SendCommand.SendOneByte(Txtest, fm); if (SendCount >= message.Length) {//定时器1用来做帧延时,定时器2做Modbus超时 ModbusTimeOut = 1; fm.timer1.Enabled = true; SendCount = 0; } } } if (SerialRecOk == 1) { ModbusTimeOut = 0; SerialRecOk = 0; SendCount = 0; fm.timer1.Enabled = false; } } else { fm.timer2.Enabled = false; fm.timer1.Enabled = false; } }