public byte Disassemble_ReceivedADU() { if (IsMaster == true) { if (StationID != TxRxBuffer[0]) //站号错误不进行任何处理,立即返回(ACKTimeout定时器继续定时) { return((byte)ErrorStatus.ERR_Station); } ACKTimer.Enabled = false; //通过上面站号检测的说明是期望子节点发送来的响应帧,因而停止ACKTimeout倒计时。 TxRxStatus = TranmitingStatus.Idle; //总线状态置为空闲,允许发送其他帧(会不会放在本函数最后好,不然要是Modbus发送了其他的帧,并接收了返回的帧,上一次此处的处理还未完成怎么办?) if (RxLength < 5) { return((byte)ErrorStatus.ERR_BreakFrame); } TempWord.HByte = TxRxBuffer[RxLength - 2]; TempWord.LByte = TxRxBuffer[RxLength - 1]; if (TempWord.Word != CRCCaculation.CRC16(TxRxBuffer, (UInt16)(RxLength - 2))) { return((byte)ErrorStatus.ERR_CRCCode); //检测CRC是否错误 } FunctionCode = TxRxBuffer[1]; //记录功能码 switch (FunctionCode) { case (byte)ModbusFuncCode.WriteSingleCoil: case (byte)ModbusFuncCode.WriteCoils: case (byte)ModbusFuncCode.WriteRegs: case (byte)ModbusFuncCode.WriteSingleReg: TempWord.HByte = TxRxBuffer[2]; //检查地址是否正确 TempWord.LByte = TxRxBuffer[3]; if (TempWord.Word != Address) { return((byte)ErrorStatus.ERR_Address); } TempWord.HByte = TxRxBuffer[4]; //检查写入单元数量或写入的单个数据是否正确 TempWord.LByte = TxRxBuffer[5]; if (TempWord.Word != NumOrData) { return((byte)ErrorStatus.ERR_NumOrData); } ModbusWriteSuccessEvent(); //(事件引发)如果以上均正确,说明Modbus主向外写操作成功,引发“写成功”事件 break; case (byte)ModbusFuncCode.ReadCoils: case (byte)ModbusFuncCode.ReadDistrbuteBits: case (byte)ModbusFuncCode.ReadStorageRegs: case (byte)ModbusFuncCode.ReadInputRegs: DataByteNumber = TxRxBuffer[2]; DataStorage[TempControlIndex] = new byte[DataByteNumber]; for (byte i = 0; i < DataByteNumber; i++) { DataStorage[TempControlIndex][i] = TxRxBuffer[i + 3]; } ModbusReadSuccessEvent(); //(事件引发)如果以上均正确,说明Modbus主读输入寄存器成功,引发“读输入寄存器成功”事件 break; case ((byte)ModbusFuncCode.ReadCoils + 0x80): case ((byte)ModbusFuncCode.ReadDistrbuteBits + 0x80): case ((byte)ModbusFuncCode.ReadStorageRegs + 0x80): case ((byte)ModbusFuncCode.ReadInputRegs + 0x80): case ((byte)ModbusFuncCode.WriteSingleCoil + 0x80): case ((byte)ModbusFuncCode.WriteSingleReg + 0x80): case ((byte)ModbusFuncCode.WriteCoils + 0x80): case ((byte)ModbusFuncCode.WriteRegs + 0x80): ModbusReceiveExceptionEvent(); //(事件引发)接收到异常帧 return((byte)ErrorStatus.ERR_Response); default: return((byte)ErrorStatus.ERR_FunctionCode); //检测FunctionCode是否错误 } } else { //Slaver To Do... } return((byte)ErrorStatus.ERR_OK); }
public static void AssembleRequestADU(int ControlIndex, Boolean IsHighPriority, byte ID, byte FuncCode, UInt16 Addr, UInt16 NumCmdData, byte[] DataToTx) { byte[] TxFrame; //FunctionCode = FuncCode; NumOrData = NumCmdData; UInt16 DataByteNumber = 0; UInt16 Pointer = 0; switch (FuncCode) { case (byte)ModbusFuncCode.ReadCoils: case (byte)ModbusFuncCode.ReadDistrbuteBits: case (byte)ModbusFuncCode.ReadStorageRegs: case (byte)ModbusFuncCode.ReadInputRegs: case (byte)ModbusFuncCode.WriteSingleCoil: case (byte)ModbusFuncCode.WriteSingleReg: TxLength = 8; break; case (byte)ModbusFuncCode.WriteCoils: DataByteNumber = (UInt16)(NumCmdData / 8 + (NumCmdData % 8 == 0 ? 0 : 1)); TxLength = (UInt16)(9 + DataByteNumber); break; case (byte)ModbusFuncCode.WriteRegs: DataByteNumber = (UInt16)(2 * NumCmdData); TxLength = (UInt16)(9 + DataByteNumber); break; default: break; } TxFrame = new byte[TxLength]; TxFrame[0] = ID; TxFrame[1] = FuncCode; TempWord.Word = Addr; TxFrame[2] = TempWord.HByte; TxFrame[3] = TempWord.LByte; TempWord.Word = NumCmdData; TxFrame[4] = TempWord.HByte; TxFrame[5] = TempWord.LByte; Pointer = 6; if (DataByteNumber != 0) { TxFrame[Pointer++] = (byte)DataByteNumber;//填入字节数 for (UInt16 i = 0; i < DataByteNumber; i++) { TxFrame[Pointer++] = DataToTx[i];//bytes } } TempWord.Word = CRCCaculation.CRC16(TxFrame, Pointer); TxFrame[Pointer++] = TempWord.HByte; //crc code TxFrame[Pointer++] = TempWord.LByte; Pointer = 0; //为接收逻辑的使用复位 if (IsHighPriority == true) { if (HighPriorityTxBufferQueue.Count >= _DepthOfFIFO) { return; //禁止FIFO无节制扩大 } lock (HighPriorityTxBufferQueue) { lock (HPControlsIndexQueue) { HighPriorityTxBufferQueue.Enqueue(TxFrame); //高优先级的帧进高优先级FIFO HPControlsIndexQueue.Enqueue(ControlIndex); //高优先级帧所对应的控件索引进高优先级FIFO } } if (HighPriorityTxBufferQueue.Count != 0)//检查高优先级帧FIFO是否有数据,如果有则Ready标志位置位 { HighPriorityFrameRdy = true; } } else { if (LowPriorityTxBufferQueue.Count >= _DepthOfFIFO) { return; //禁止FIFO无节制扩大 } lock (LowPriorityTxBufferQueue) { lock (LPControlsIndexQueue) { LowPriorityTxBufferQueue.Enqueue(TxFrame); //低优先级的帧进低优先级FIFO LPControlsIndexQueue.Enqueue(ControlIndex); //低优先级帧所对应的控件索引进低优先级FIFO } } if (LowPriorityTxBufferQueue.Count != 0)//检查低优先级帧FIFO是否有数据,如果有则Ready标志位置位 { LowPriorityFrameRdy = true; } } }