#include "../main/SystemInclude.h" u8 isOldProtocol; __MB_Buf_TypeDef MBBuf; /******************************************************************************/ u16 ModBusCRC(u8 *Data_Array , u8 DataLength) //获取CRC { u32 i, j; u16 CRCTemp; CRCTemp = 0xffff; for(i = 0; i<=DataLength; i++) { CRCTemp = CRCTemp ^ Data_Array[i]; for(j=0; j<=7; j++) { if((CRCTemp & 0x0001)==0x0001) { CRCTemp >>= 1; CRCTemp ^= 0xa001; } else CRCTemp >>= 1; } } return CRCTemp; } /******************************************************************************/ void ComputeTxdDataCRC(void) { tempL.Word[0] = ModBusCRC(MBBuf.RxPointer, MBBuf.TxdLen-2); //计算CRC MBBuf.RxPointer[MBBuf.TxdLen] = tempL.Byte[1]; MBBuf.RxPointer[MBBuf.TxdLen-1] = tempL.Byte[0]; MBBuf.TxdLen++; } /******************************************************************************/ void ModBusErrorInfo(u8 ErrorCode) { MBBuf.RxPointer[1] |= 0x80; //返回执行错误 MBBuf.RxPointer[2] = 1; //字节长度1 MBBuf.RxPointer[3] = ErrorCode; //返回详细错误代码:功能码错误 本设备不支持此功能 MBBuf.TxdLen = 5; } /******************************************************************************/ void ModBusReadMultiByte(void) { if(MBBuf.StartAddr < INT_PARAMETER_PROTOCOL) UserReadDataProtocol(); else InternalReadParameterProtocol(); } /******************************************************************************/ void ModBusWriteMultiByte(void) { if(MBBuf.StartAddr < INT_PARAMETER_PROTOCOL) UserWriteDataProtocol(); else InternalWriteParameterProtocol(); } /******************************************************************************/ //ModBus数据处理 void ModBusDataProcessing(void) { MBBuf.BusError = 0; switch(MBBuf.RxPointer[1]) { case READ_HOLDING_REGISTERS: //0x03 读取保持寄存器--------------------------------------------- MBBuf.StartAddr = ((u16)MBBuf.RxPointer[2] << 8) | (u16)MBBuf.RxPointer[3]; MBBuf.ByteNumber = ((u16)MBBuf.RxPointer[4] << 8) | (u16)MBBuf.RxPointer[5]; if(MBBuf.ByteNumber > ENABLE_REG_MAX) { MBBuf.BusError = SLAVE_DEVICE_FAILURE; break; } MBBuf.ByteNumber <<= 1; MBBuf.TxdLen = MBBuf.ByteNumber; MBBuf.RxPointer[2] = MBBuf.TxdLen;//返回数据的字节数 MBBuf.TxdLen += 4; MBBuf.Index = 3; ModBusReadMultiByte();//读操作 break; case PRESET_SINGLE_REGISTER: //0x06 写预置单寄存器--------------------------------------------- MBBuf.StartAddr = MBBuf.StartAddr = ((u16)MBBuf.RxPointer[2] << 8) | (u16)MBBuf.RxPointer[3]; MBBuf.EndAddr = MBBuf.StartAddr + 1; MBBuf.TxdLen = 7; MBBuf.ByteNumber = 2; MBBuf.Index = 4; // 接收到的数据有效起始 ModBusWriteMultiByte();//写操作 break; case PRESET_MULTIPLE_REGISTERS : //0x010 写预置多寄存器---------------------------------------- //if(RxdIndex < 11) return; MBBuf.StartAddr = ((u16)MBBuf.RxPointer[2] << 8) | (u16)MBBuf.RxPointer[3]; MBBuf.ByteNumber = ((u16)MBBuf.RxPointer[4] << 8) | (u16)MBBuf.RxPointer[5]; if(MBBuf.ByteNumber > ENABLE_REG_MAX) { MBBuf.BusError = SLAVE_DEVICE_FAILURE; break; } MBBuf.EndAddr = MBBuf.StartAddr + MBBuf.ByteNumber; MBBuf.ByteNumber <<= 1; //准备返回数据 MBBuf.RxPointer[1] = 0x10; MBBuf.TxdLen = 7; MBBuf.Index = 7; ModBusWriteMultiByte();//写操作 break; case ERROR_TEST : //0x08 错误诊断------------------------------------------------------------- if (MBBuf.RxPointer[0] != 0x00) //如果不是广播地址 则回复 否则静默 break; default: //功能码未识别----------------------------------------------------------------------- MBBuf.BusError = ILLEGAL_FUNCTION; break; } if(MBBuf.BusError != 0) ModBusErrorInfo(MBBuf.BusError); //广播地址 静默 if(MBBuf.RxPointer[0] == 0x00) { MBBuf.TxdLen = 0; return; } if(MBBuf.TxdLen == 0) return; ComputeTxdDataCRC(); memmove( (char *)MBBuf.TxPointer, (char *)MBBuf.RxPointer, MBBuf.TxdLen); } /******************************************************************************/ //检测是否符合Modbus协议帧 u8 ModBusProtocolDetection(void) { u16 CRCTempRX, CRCTempCX; MBBuf.TxdLen = 0; if(MBBuf.RxdLen < 5) return 0; // 判断地址是否错误 if(MBBuf.RxPointer[0] == localAddress) goto DetecteNext; else if(MBBuf.RxPointer[0] == 0) goto DetecteNext; else return 0; DetecteNext: //tempL.Byte[1] = MBBuf.RxPointer[MBBuf.RxdLen-1]; //tempL.Byte[0] = MBBuf.RxPointer[MBBuf.RxdLen-2]; //CRCTempRX = tempL.Word[0]; CRCTempRX = ((u16)MBBuf.RxPointer[MBBuf.RxdLen-1] << 8) | (u16)MBBuf.RxPointer[MBBuf.RxdLen-2]; CRCTempCX = ModBusCRC(MBBuf.RxPointer, MBBuf.RxdLen-3); // 计算CRC if(CRCTempRX != CRCTempCX) return 0; // CRC错误 else return 1; } /******************************************************************************/ //Modbus变量指针处理 u8 ModbusVariablePointerProcess(void) { if(MBBuf.ByteNumber >= MBBuf.DataByte) MBBuf.ByteNumber -= MBBuf.DataByte; else return 1; if(MBBuf.ByteNumber < 2) return 1; MBBuf.DataByte >>= 1; MBBuf.StartAddr += MBBuf.DataByte; return 0; } /******************************************************************************/ u8 ModbusVariablePointerDec(void) { if(MBBuf.ByteNumber < MBBuf.DataByte + 2) { MBBuf.ByteNumber = 0; return 1; } MBBuf.ByteNumber -= MBBuf.DataByte; MBBuf.DataByte >>= 1; MBBuf.StartAddr += MBBuf.DataByte; return 0; } ///******************************************************************************/ void CopyDataAndJudgeComplete(void) { u32 I; for(I=1; I<= MBBuf.DataByte; I++) MBBuf.RxPointer[MBBuf.Index++] = tempL.Byte[MBBuf.DataByte-I]; ModbusVariablePointerDec(); }