📄 modbus.txt
字号:
#include "config.h"
#include "Modbus.H"
#include "Initializes.H"
#include "Founction.H"
#include "Interrupt_service.H"
#include "RS485.H"
//=================================================================================================
// MODBUS Function codes descriptions
//=================================================================================================
//===============================================================================================
//Glable variable used for Modbus
//==============================================================================================
//-------------------------------------------------------------------------
//The addres of the current slaver device
//
uint8 ADDRESS;
//---------------------------------------------------------------
//The Client frame
//
MODBUS_CLIENT_FRAME_I ClientFrameReceive, ClientFrame;
//---------------------------------------------------------------------------
//The parameter frame block
//
MODBUS_PARAMETER_I ModBusParameter;
//--------------------------------------------------------------------------
//flags
//
uint8 DataCount, DataLength;
uint8 FlagLocal, FlagOver;
uint16 CRC;
uint8 FlagExecute;
//================================================================================================
// The CRC caculate
//================================================================================================
void CalculateCRC( uint8 datum )
{
uint32 i, temp;
// CRC = 0xFFFF;
CRC = CRC ^ datum;
for( i=0; i<8; i++ )
{
temp = CRC&0x0001;
CRC >>= 1;
if( temp ) CRC = CRC ^ 0xA001;
}
}
//=================================================================================================
// according to the function number to Response to the master modbus
//=================================================================================================
void ResponseToReadHoldRegisters( void )
{
}
//-------------------------------------------------------------------------------------------------
// Response to ReadInputRegisters 04
void ResponseToReadInputRegisters( void )
{
uint32 i, j;
uint16 AddressStart, AddressEnd, number;
AddressStart = ClientFrame.ReadInputRegisters.Start*2;
number = ClientFrame.ReadInputRegisters.Number;
AddressEnd = AddressStart + number*2;
// Prevent from Outsideing
if( AddressEnd>MAX_PARAMETER_LENGTH )
{
AddressEnd = MAX_PARAMETER_LENGTH;
number = (AddressEnd-AddressStart)/2;
}
//-------------------------------------------
//-------------------------------------------
UART0_Buffer[0] = ClientFrame.ReadInputRegisters.Address;
UART0_Buffer[1] = ClientFrame.ReadInputRegisters.Function;
UART0_Buffer[2] = number*2;
//-------------------------------------------
j = 3;
for( i=AddressStart; i<AddressEnd; i+=2 ) // Little endian to Big endian
{
UART0_Buffer[j++] = ModBusParameter.ParaAddress[i+1];
UART0_Buffer[j++] = ModBusParameter.ParaAddress[i ];
}
CRC = 0xFFFF;
for( i=0; i<(number*2+3); i++ ) CalculateCRC( UART0_Buffer[i] );
UART0_Buffer[j++] = CRC; //CRC低位
UART0_Buffer[j++] = CRC>>8; //CRC高位 为了和上位机打断模式符合
UART0SendString( number*2+5 );
}
//-------------------------------------------------------------------------------------------------
// Response to WriteSingleRegister
void ResponseToWriteSingleRegister( void )
{
}
//-------------------------------------------------------------------------------------------------
// Response to WriteSingleCoil
void ResponseToWriteSingleCoil( void )
{
uint32 i;
//
UART0_Buffer[0] = ClientFrame.WriteSingleCoil.Address;
UART0_Buffer[1] = ClientFrame.WriteSingleCoil.Function;
UART0_Buffer[2] = ClientFrame.WriteSingleCoil.Start>>8;
UART0_Buffer[3] = ClientFrame.WriteSingleCoil.Start;
UART0_Buffer[4] = ClientFrame.WriteSingleCoil.Value>>8;
UART0_Buffer[5] = ClientFrame.WriteSingleCoil.Value;
CRC = 0xFFFF;
for( i=0; i<6; i++ ) CalculateCRC( UART0_Buffer[i] );
UART0_Buffer[6] = CRC; //
UART0_Buffer[7] = CRC>>8;
UART0SendString( 8 );
CRC = 0;
CRC = UART0_Buffer[6];
CRC <<= 8;
CRC |= UART0_Buffer[7];
if( (ClientFrame.WriteSingleCoil.Start==0x05) && (CRC == ClientFrame.WriteSingleCoil.CRC) )
{
}
}
//=================================================================================================
// Response ,if the slaver receive message from the master, over and correctly
//=================================================================================================
void Modbus_Response( void )
{
uint16 value;
uint16 i;
IO1CLR |= Modbus_LED2; //Modbus_LED2发送指示灯点亮
FlagLocal= 0;
FlagOver = 0;
//---------------------------------------
// CRC check
CRC = 0xFFFF;
for( i=0; i<DataLength-2; i++ ) CalculateCRC( ClientFrameReceive.ClientBuffer[i] );
// Endian change
value = ClientFrameReceive.ClientBuffer[DataLength-1];
ClientFrameReceive.ClientBuffer[DataLength-1] = ClientFrameReceive.ClientBuffer[DataLength-2];
ClientFrameReceive.ClientBuffer[DataLength-2] = value;
value = ClientFrameReceive.ClientBuffer[DataLength-2];
value <<= 8 ;
value |= ClientFrameReceive.ClientBuffer[DataLength-1];
if( CRC==value )
{
FlagExecute = 1;
ClientFrame = ClientFrameReceive;
//-----------------------------------
// Change Big endian to Little endian
switch( ClientFrame.ReadHoldRegisters.Function )
{
// Read Coils :
case MODBUS_ReadCoils:
// Read Holding Registers :
case MODBUS_ReadHoldRegisters:
// Read Input Registers : The temperature
case MODBUS_ReadInputRegisters:
// Write Single Register :
case MODBUS_WriteSingleRegister:
// Write Single Coil :
case MODBUS_WriteSingleCoil:
ClientFrame.ReadCoil.Start = EndianChangeU16( ClientFrame.ReadCoil.Start );
ClientFrame.ReadCoil.Number = EndianChangeU16( ClientFrame.ReadCoil.Number );
break;
}
}
if( FlagExecute )
{
FlagExecute = 0;
switch( ClientFrame.ReadHoldRegisters.Function )
{
// Read Holding Registers :
case MODBUS_ReadHoldRegisters:
// ResponseToReadHoldRegisters( );
break;
// Read Input Registers : The temperature
case MODBUS_ReadInputRegisters:
ResponseToReadInputRegisters( );
break;
// Write Single Register
case MODBUS_WriteSingleRegister:
// ResponseToWriteSingleRegister( );
break;
// Write Single Coil :
case MODBUS_WriteSingleCoil:
ResponseToWriteSingleCoil( );
break;
}
}
IO1SET |= Modbus_LED2; //Modbus_LED2发送指示灯熄灭
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -