Files
CHJ/user/Protocol/MODBUS.c

191 lines
6.0 KiB
C
Raw Normal View History

2026-03-20 21:16:58 +08:00
#include "../main/SystemInclude.h"
u8 isOldProtocol;
__MB_Buf_TypeDef MBBuf;
/******************************************************************************/
u16 ModBusCRC(u8 *Data_Array , u8 DataLength) //<2F><>ȡ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); //<2F><><EFBFBD><EFBFBD>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; //<2F><><EFBFBD><EFBFBD>ִ<EFBFBD>д<EFBFBD><D0B4><EFBFBD>
MBBuf.RxPointer[2] = 1; //<2F>ֽڳ<D6BD><DAB3><EFBFBD>1
MBBuf.RxPointer[3] = ErrorCode; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD><CFB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E8B1B8>֧<EFBFBD>ִ˹<D6B4><CBB9><EFBFBD>
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<75><73><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD>
void ModBusDataProcessing(void)
{
MBBuf.BusError = 0;
switch(MBBuf.RxPointer[1])
{
case READ_HOLDING_REGISTERS: //0x03 <20><>ȡ<EFBFBD><C8A1><EFBFBD>ּĴ<D6BC><C4B4><EFBFBD>---------------------------------------------
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;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5>ֽ<EFBFBD><D6BD><EFBFBD>
MBBuf.TxdLen += 4;
MBBuf.Index = 3;
ModBusReadMultiByte();//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
break;
case PRESET_SINGLE_REGISTER: //0x06 дԤ<D0B4>õ<EFBFBD><C3B5>Ĵ<EFBFBD><C4B4><EFBFBD>---------------------------------------------
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; // <20><><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>ʼ
ModBusWriteMultiByte();//д<><D0B4><EFBFBD><EFBFBD>
break;
case PRESET_MULTIPLE_REGISTERS : //0x010 дԤ<D0B4>ö<EFBFBD><C3B6>Ĵ<EFBFBD><C4B4><EFBFBD>----------------------------------------
//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;
//׼<><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MBBuf.RxPointer[1] = 0x10;
MBBuf.TxdLen = 7;
MBBuf.Index = 7;
ModBusWriteMultiByte();//д<><D0B4><EFBFBD><EFBFBD>
break;
case ERROR_TEST : //0x08 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-------------------------------------------------------------
if (MBBuf.RxPointer[0] != 0x00) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǹ㲥<C7B9><E3B2A5>ַ <20><><EFBFBD>ظ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ
break;
default: //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δʶ<CEB4><CAB6>-----------------------------------------------------------------------
MBBuf.BusError = ILLEGAL_FUNCTION;
break;
}
if(MBBuf.BusError != 0) ModBusErrorInfo(MBBuf.BusError);
//<2F><EFBFBD><E3B2A5>ַ <20><>Ĭ
if(MBBuf.RxPointer[0] == 0x00) {
MBBuf.TxdLen = 0;
return;
}
if(MBBuf.TxdLen == 0) return;
ComputeTxdDataCRC();
memmove( (char *)MBBuf.TxPointer, (char *)MBBuf.RxPointer, MBBuf.TxdLen);
}
/******************************************************************************/
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ModbusЭ<73><D0AD>֡
u8 ModBusProtocolDetection(void)
{
u16 CRCTempRX, CRCTempCX;
MBBuf.TxdLen = 0;
if(MBBuf.RxdLen < 5) return 0;
// <20>жϵ<D0B6>ַ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
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); // <20><><EFBFBD><EFBFBD>CRC
if(CRCTempRX != CRCTempCX) return 0; // CRC<52><43><EFBFBD><EFBFBD>
else return 1;
}
/******************************************************************************/
//Modbus<75><73><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EBB4A6>
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();
}