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;
                }
            }
        }