Initial commit: my SECS2 project
This commit is contained in:
294
usr/protocol/proto_Modbus.c
Normal file
294
usr/protocol/proto_Modbus.c
Normal file
@@ -0,0 +1,294 @@
|
||||
#include "proto_Modbus.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "bsp_Uart.h"
|
||||
|
||||
u16 ModbusCrc16(u8 *pData, u16 Len)
|
||||
{
|
||||
u16 CRC_16 = 0xffff;
|
||||
u16 i;
|
||||
while(Len--)
|
||||
{
|
||||
CRC_16 = CRC_16^(*pData++);
|
||||
for(i=0; i++<8; )
|
||||
{
|
||||
if(CRC_16&0x0001)
|
||||
{
|
||||
CRC_16 = (CRC_16>>1)^0xa001;
|
||||
}
|
||||
else
|
||||
{
|
||||
CRC_16>>=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CRC_16;
|
||||
}
|
||||
|
||||
/******************************************
|
||||
* <20><><EFBFBD><EFBFBD>: Float2u16
|
||||
* <20><><EFBFBD><EFBFBD>: <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD>16<31><36><EFBFBD><EFBFBD>16λ
|
||||
* <20><><EFBFBD><EFBFBD>: FloatData : Ҫת<D2AA><D7AA><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD>
|
||||
HorL : <20><><EFBFBD>ظ<EFBFBD>16λ<36><CEBB><EFBFBD>ǵ<EFBFBD>16λ
|
||||
* <20><><EFBFBD><EFBFBD>: <20><><EFBFBD>ض<EFBFBD>Ӧ<EFBFBD>ĸ<EFBFBD>16λ<36><CEBB><EFBFBD>ǵ<EFBFBD>16λ
|
||||
* <20><><EFBFBD><EFBFBD>: <20><>
|
||||
******************************************/
|
||||
u16 FloatTOu16(float FloatData,u8 HorL)
|
||||
{
|
||||
u16 Temp = 0XFFFF;
|
||||
if(HorL == U16_DATA_L)
|
||||
{
|
||||
Temp = *((u32 *)&FloatData) & 0x0000ffff;
|
||||
}
|
||||
else if(HorL == U16_DATA_H)
|
||||
{
|
||||
Temp = ((*((u32 *)&FloatData)) >> 16) & 0x0000ffff;
|
||||
}
|
||||
return Temp;
|
||||
}
|
||||
|
||||
/******************************************
|
||||
* <20><><EFBFBD><EFBFBD>: u32TOu16
|
||||
* <20><><EFBFBD><EFBFBD>: <20><>ȡu32<33>ĸ<EFBFBD>16<31><36><EFBFBD><EFBFBD>16λ
|
||||
* <20><><EFBFBD><EFBFBD>: u32Data : Ҫת<D2AA><D7AA><EFBFBD><EFBFBD>u32
|
||||
HorL : <20><><EFBFBD>ظ<EFBFBD>16λ<36><CEBB><EFBFBD>ǵ<EFBFBD>16λ
|
||||
* <20><><EFBFBD><EFBFBD>: <20><><EFBFBD>ض<EFBFBD>Ӧ<EFBFBD>ĸ<EFBFBD>16λ<36><CEBB><EFBFBD>ǵ<EFBFBD>16λ
|
||||
* <20><><EFBFBD><EFBFBD>: <20><>
|
||||
******************************************/
|
||||
u16 u32TOu16(u32 u32Data,u8 HorL)
|
||||
{
|
||||
u16 Temp = 0XFFFF;
|
||||
if(HorL == U16_DATA_L)
|
||||
{
|
||||
Temp = u32Data & 0x0000ffff;
|
||||
}
|
||||
else if(HorL == U16_DATA_H)
|
||||
{
|
||||
Temp = (u32Data >> 16) & 0x0000ffff;
|
||||
}
|
||||
return Temp;
|
||||
}
|
||||
|
||||
void u32TOu8(u32 u32Data,u8 *pData,u8 Endian)
|
||||
{
|
||||
if(BIG_ENDIAN == Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 4;i++)
|
||||
{
|
||||
pData[i] = (u32Data >> (8 * (3 - i))) & 0xff;
|
||||
}
|
||||
}
|
||||
else if(LITTLE_ENDIAN == Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 4;i++)
|
||||
{
|
||||
pData[i] = (u32Data >> (8 * i)) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void u16TOu8(u16 u16Data,u8 *pData,u8 Endian)
|
||||
{
|
||||
if(BIG_ENDIAN == Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 2;i++)
|
||||
{
|
||||
pData[i] = (u16Data >> (8 * (1 - i))) & 0xff;
|
||||
}
|
||||
}
|
||||
else if(LITTLE_ENDIAN == Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 2;i++)
|
||||
{
|
||||
pData[i] = (u16Data >> (8 * i)) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float u32TOFloat(u32 u32Data,u8 HorL)
|
||||
{
|
||||
float Temp = 0;
|
||||
Temp = *((float *)&u32Data);
|
||||
return Temp;
|
||||
}
|
||||
|
||||
/*<2A><>u8Endian<61><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p_u8Dataת<61><D7AA>Ϊ<EFBFBD><CEAA>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>С<EFBFBD><D0A1><EFBFBD><EFBFBD>*/
|
||||
u32 u8TOu32(u8 *p_u8Data,u8 u8Endian)
|
||||
{
|
||||
u32 Temp = 0;
|
||||
if(BIG_ENDIAN == u8Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 4;i++)
|
||||
{
|
||||
Temp |= p_u8Data[i] << ((3 - i) * 8);
|
||||
}
|
||||
}
|
||||
else if(LITTLE_ENDIAN == u8Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 4;i++)
|
||||
{
|
||||
Temp |= p_u8Data[i] << (i * 8);
|
||||
}
|
||||
}
|
||||
return Temp;
|
||||
}
|
||||
|
||||
/*<2A><>u8Endian<61><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p_u8Dataת<61><D7AA>Ϊ<EFBFBD><CEAA>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>С<EFBFBD><D0A1><EFBFBD><EFBFBD>*/
|
||||
u16 u8TOu16(u8 *p_u8Data,u8 u8Endian)
|
||||
{
|
||||
u32 Temp = 0;
|
||||
if(BIG_ENDIAN == u8Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 2;i++)
|
||||
{
|
||||
Temp |= p_u8Data[i] << ((1 - i) * 8);
|
||||
}
|
||||
}
|
||||
else if(LITTLE_ENDIAN == u8Endian)
|
||||
{
|
||||
for(u8 i = 0;i < 2;i++)
|
||||
{
|
||||
Temp |= p_u8Data[i] << (i * 8);
|
||||
}
|
||||
}
|
||||
return Temp;
|
||||
}
|
||||
|
||||
|
||||
/*<2A>ֽڶ<D6BD><DAB6><EFBFBD>ת<EFBFBD><D7AA>*/
|
||||
u32 u32_EndianConv(u32 Data)
|
||||
{
|
||||
u32 TempData = 0;
|
||||
TempData = (((Data >> 0 ) & 0xff) << 24)
|
||||
| (((Data >> 8 ) & 0xff) << 16)
|
||||
| (((Data >> 16) & 0xff) << 8 )
|
||||
| (((Data >> 24) & 0xff) << 0 );
|
||||
return TempData;
|
||||
}
|
||||
|
||||
/*<2A>ֽڶ<D6BD><DAB6><EFBFBD>ת<EFBFBD><D7AA>*/
|
||||
u16 u16_EndianConv(u16 Data)
|
||||
{
|
||||
u16 TempData = 0;
|
||||
TempData = (((Data >> 0) & 0xff) << 8)
|
||||
| (((Data >> 8) & 0xff) << 0);
|
||||
return TempData;
|
||||
}
|
||||
|
||||
|
||||
/******************************************
|
||||
* <20><><EFBFBD><EFBFBD>: ModbusReadData
|
||||
* <20><><EFBFBD><EFBFBD>: MODBUS<55><53><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* <20><><EFBFBD><EFBFBD>: Id :MODBUS<55>ӻ<EFBFBD><D3BB><EFBFBD>ַ
|
||||
* Addr :д<><D0B4><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD>ʼ<EFBFBD><CABC>ַ
|
||||
* Num :д<>ļĴ<C4BC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* UsartSendBuffer :<3A><><EFBFBD>ڷ<EFBFBD><DAB7>ͺ<EFBFBD><CDBA><EFBFBD>
|
||||
* <20><><EFBFBD><EFBFBD>: <20><>
|
||||
* <20><><EFBFBD><EFBFBD>: <20><>
|
||||
******************************************/
|
||||
void ModbusReadData(u8 Id,u16 Addr,u16 Num,void (*UsartSendBuffer)(u8 *,u16 ))
|
||||
{
|
||||
u8 Tx[8];
|
||||
u16 CRC16;
|
||||
Tx[0] = Id;
|
||||
Tx[1] = 0x03;
|
||||
Tx[2] = (Addr >> 8) & 0xff;
|
||||
Tx[3] = Addr & 0xff;
|
||||
Tx[4] = (Num >> 8) & 0xff;
|
||||
Tx[5] = Num & 0xff;
|
||||
CRC16 = ModbusCrc16(Tx,6);
|
||||
Tx[6] = CRC16 & 0xff;
|
||||
Tx[7] = (CRC16 >> 8) & 0xff;
|
||||
UsartSendBuffer(Tx,8);
|
||||
}
|
||||
|
||||
/******************************************
|
||||
* <20><><EFBFBD><EFBFBD>: ModbusWriteMultipleData
|
||||
* <20><><EFBFBD><EFBFBD>: MODBUSд<53><D0B4><EFBFBD><EFBFBD>
|
||||
* <20><><EFBFBD><EFBFBD>: Id :MODBUS<55>ӻ<EFBFBD><D3BB><EFBFBD>ַ
|
||||
* Addr :д<><D0B4><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD>ʼ<EFBFBD><CABC>ַ
|
||||
* Num :д<>ļĴ<C4BC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* Data :д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* UsartSendBuffer :<3A><><EFBFBD>ڷ<EFBFBD><DAB7>ͺ<EFBFBD><CDBA><EFBFBD>
|
||||
* <20><><EFBFBD><EFBFBD>: <20><>
|
||||
* <20><><EFBFBD><EFBFBD>: <20><>
|
||||
******************************************/
|
||||
void ModbusWriteMultipleData(u8 ID,u16 Addr,u16 Num,u16 *Data,void (*UsartSendBuffer)(u8 *,u16 ))
|
||||
{
|
||||
u8 Tx[50],i;
|
||||
u16 CRC16;
|
||||
Tx[0] = ID;
|
||||
Tx[1] = 0x10;
|
||||
Tx[2] = (Addr >> 8) & 0xff;
|
||||
Tx[3] = Addr & 0xff;
|
||||
Tx[4] = (Num >> 8) & 0xff;
|
||||
Tx[5] = Num & 0xff;
|
||||
Tx[6] = Num * 2;
|
||||
for(i = 0;i < Tx[6]/2;i++)
|
||||
{
|
||||
Tx[7 + 2 * i] = (Data[i] >> 8) & 0xff;
|
||||
Tx[8 + 2 * i] = Data[i] & 0xff;
|
||||
}
|
||||
CRC16 = ModbusCrc16(Tx,7 + 2 * i);
|
||||
Tx[7 + 2 * i] = CRC16 & 0xff;
|
||||
Tx[8 + 2 * i] = (CRC16 >> 8) & 0xff;
|
||||
UsartSendBuffer(Tx,9 + 2 * i);
|
||||
}
|
||||
|
||||
void ModbusyWriteOnlData(u8 ID,u16 Addr,u16 Value,void (*UsartSendBuffer)(u8 *,u16 ))
|
||||
{
|
||||
u8 Tx[8];
|
||||
u16 CRC16;
|
||||
Tx[0] = ID;
|
||||
Tx[1] = 0x06;
|
||||
Tx[2] = (Addr >> 8) & 0xff;
|
||||
Tx[3] = Addr & 0xff;
|
||||
Tx[4] = (Value >> 8) & 0xff;
|
||||
Tx[5] = Value & 0xff;
|
||||
CRC16 = ModbusCrc16(Tx,6);
|
||||
Tx[6] = CRC16 & 0xff;
|
||||
Tx[7] = (CRC16 >> 8) & 0xff;
|
||||
UsartSendBuffer(Tx,8);
|
||||
}
|
||||
|
||||
|
||||
//01 10 00 02 00 01 02 12 34 CRC
|
||||
//ID Func StartAddress RegNumber wDataAddress
|
||||
u8 ModbusAnalysis(ModbusAnalysisData_t *pModbus, u8 *pData, u16 len)
|
||||
{
|
||||
u16 CRC_16;
|
||||
u16 TempU16;
|
||||
|
||||
if(NULL == pModbus) return 0;
|
||||
if(len < 8) return 0;
|
||||
|
||||
CRC_16 = ModbusCrc16(pData, len-2);
|
||||
TempU16 = *(pData+len-1);
|
||||
TempU16 <<= 8;
|
||||
TempU16 |= *(pData+len-2);
|
||||
if(TempU16 != CRC_16) return 0;
|
||||
|
||||
pModbus->ID = *pData;
|
||||
pModbus->Func = *(pData+1);
|
||||
|
||||
pModbus->StartAddress = (*(pData+2))<<8;
|
||||
pModbus->StartAddress |= *(pData+3);
|
||||
|
||||
/*<2A><><EFBFBD><EFBFBD>дһ<D0B4><D2BB><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>*/
|
||||
if(0x06 == pModbus->Func)
|
||||
{
|
||||
pModbus->wDataAddress = pData+4;
|
||||
}
|
||||
else if(0x10 == pModbus->Func) /*д<><D0B4><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>*/
|
||||
{
|
||||
pModbus->RegNumber = (*(pData+4))<<8;
|
||||
pModbus->RegNumber |= *(pData+5);
|
||||
pModbus->wDataAddress = pData+7;
|
||||
}
|
||||
else
|
||||
{
|
||||
pModbus->RegNumber = (*(pData+4))<<8;
|
||||
pModbus->RegNumber |= *(pData+5);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user