⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modbus.txt

📁 基于ARM2131实现的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 + -