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

📄 mb_pfunction.c

📁 Modbus协议主从协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
				Response->ExceptionCode = 0x00;
			}
			else
				Response->ExceptionCode = 0x04;
		}
		else
			Response->ExceptionCode = 0x02;
	}
	else
		Response->ExceptionCode = 0x03;
}
#endif

/****************************************************************************************/
// 函数名称:FReadDiscreteInputs
// 输入参数:Response
// 输出参数:无
// 功能描述:处理读离散输入指令02
/***************************************************************************************/
#if READ_DIS_INPUT_EN >0
void FReadDiscreteInputs(PDU_RESPONSE *Response)
{
	uint8 * PDUPtr;
	uint16 StAddr ,Quantity;
	// 从请求PDU中提取相关参数
	PDUPtr = Response->PDUDataPtr;
	StAddr = PDUPtr[1]<<8|PDUPtr[2];
	Quantity =  PDUPtr[3]<<8|PDUPtr[4];
	
	Response->PDUByteLength = 2 + Quantity/8+((Quantity%8)?1:0) ;	// 正常返回的数据长度
	
	if((Quantity>=0x001)&&(Quantity<=0x07d0))
	{
		if((StAddr<END_DISC_INPUT_ADDR)&&((StAddr+Quantity)<=END_DISC_INPUT_ADDR))
		{			
			if(ReadDiscreteInputs(PDUPtr+2,StAddr,Quantity))
			{
				*(PDUPtr+1) = Quantity/8+(Quantity%8)?1:0;	// 字节数
				Response->ExceptionCode = 0x00;
			}
			else
				Response->ExceptionCode = 0x04;
		}
		else
			Response->ExceptionCode = 0x02;
	}
	else
		Response->ExceptionCode = 0x03;
}
#endif

/****************************************************************************************/
// 函数名称:FReadHoldingReg
// 输入参数:Response
// 输出参数:无
// 功能描述:处理读保持寄存器指令03
/****************************************************************************************/
#if READ_HOLD_REG_EN >0
void FReadHoldingReg(PDU_RESPONSE *Response)
{
	uint8 * PDUPtr;
	uint16 StAddr ,Quantity;
	// 从请求PDU中提取相关参数
	PDUPtr = Response->PDUDataPtr;
	StAddr = PDUPtr[1]<<8|PDUPtr[2];
	Quantity =  PDUPtr[3]<<8|PDUPtr[4];
	
	Response->PDUByteLength = 2 + Quantity*2 ;	// 正常返回的数据长度
	
	if((Quantity>=0x001)&&(Quantity<=0x007d))
	{
		if((StAddr<END_HOLDING_REG_ADDR)&&((StAddr+Quantity)<=END_HOLDING_REG_ADDR))
		{			
			if(ReadHoldingReg(PDUPtr+2,StAddr,Quantity))
			{
				*(PDUPtr+1) = Quantity*2;
				Response->ExceptionCode = 0x00;
			}
			else
				Response->ExceptionCode = 0x04;
		}
		else
			Response->ExceptionCode = 0x02;
	}
	else
		Response->ExceptionCode = 0x03;
}
#endif

/****************************************************************************************/
// 函数名称:FReadInputReg
// 输入参数:Response
// 输出参数:无
// 功能描述:处理读输入寄存器指令04
/****************************************************************************************/
#if READ_INPUT_REG_EN >0
void FReadInputReg(PDU_RESPONSE *Response)
{
	uint8 * PDUPtr;
	uint16 StAddr ,Quantity;
	// 从请求PDU中提取相关参数
	PDUPtr = Response->PDUDataPtr;
	StAddr = PDUPtr[1]<<8|PDUPtr[2];
	Quantity =  PDUPtr[3]<<8|PDUPtr[4];
	
	Response->PDUByteLength = 2 + Quantity*2 ;	// 正常返回的数据长度
	
	if((Quantity>=0x001)&&(Quantity<=0x007d))
	{
		if((StAddr<END_INPUT_REG_ADDR) && ((StAddr+Quantity)<=END_INPUT_REG_ADDR))
		{			
			if(ReadInputReg(PDUPtr+2,StAddr,Quantity))
			{
				*(PDUPtr+1) = Quantity*2;
				Response->ExceptionCode = 0x00;
			}
			else
				Response->ExceptionCode = 0x04;
		}
		else
			Response->ExceptionCode = 0x02;
	}
	else
		Response->ExceptionCode = 0x03;
}
#endif

/****************************************************************************************/
// 函数名称:FWriteSingleCoil
// 输入参数:Response
// 输出参数:无
// 功能描述:处理写单线圈指令05
/****************************************************************************************/
#if WRITE_SING_COIL_EN >0
void FWriteSingleCoil(PDU_RESPONSE *Response)
{
	uint8 * PDUPtr;
	uint16 OutputAddr ,OutputValue;
	// 从请求PDU中提取相关参数
	PDUPtr = Response->PDUDataPtr;
	OutputAddr = PDUPtr[1]<<8|PDUPtr[2];
	OutputValue =  PDUPtr[3]<<8|PDUPtr[4];
	
	Response->PDUByteLength = 5 ;	// 正常返回的数据长度
	
	if((OutputValue==0x0000)||(OutputValue==0xff00))
	{
		if( OutputAddr < END_COILS_ADDR )
		{			
			if(WriteSingleCoil(OutputAddr,OutputValue))
			{
				*(PDUPtr+1) = OutputAddr>>8;
				*(PDUPtr+2) = OutputAddr;
				*(PDUPtr+3)	= OutputValue>>8;
				*(PDUPtr+4)	= OutputValue;
				Response->ExceptionCode = 0x00;
			}
			else
				Response->ExceptionCode = 0x04;
		}
		else
			Response->ExceptionCode = 0x02;
	}
	else
		Response->ExceptionCode = 0x03;
}
#endif

/****************************************************************************************/
// 函数名称:FWriteSingleReg
// 输入参数:Response
// 输出参数:无
// 功能描述:处理写单线圈指令06
/****************************************************************************************/
#if WRITE_SING_REG_EN >0
void FWriteSingleReg(PDU_RESPONSE *Response)
{
	uint8 * PDUPtr;
	uint16 OutputAddr ,OutputValue;
	// 从请求PDU中提取相关参数
	PDUPtr = Response->PDUDataPtr;
	OutputAddr = PDUPtr[1]<<8|PDUPtr[2];
	OutputValue =  PDUPtr[3]<<8|PDUPtr[4];
	
	Response->PDUByteLength = 2 + 5 ;	// 正常返回的数据长度
	
	if(OutputValue<=0xffff)
	{
		if(OutputAddr<END_HOLDING_REG_ADDR)
		{			
			if(WriteHoldingReg(&PDUPtr[3],OutputAddr,1))
			{
				*(PDUPtr+1) = OutputAddr>>8;
				*(PDUPtr+2) = OutputAddr;
				*(PDUPtr+3)	= OutputValue>>8;
				*(PDUPtr+4)	= OutputValue;
				Response->ExceptionCode = 0x00;
			}
			else
				Response->ExceptionCode = 0x04;
		}
		else
			Response->ExceptionCode = 0x02;
	}
	else
		Response->ExceptionCode = 0x03;
}
#endif

/****************************************************************************************/
// 函数名称:FWriteMultipleCoils
// 输入参数:Response
// 输出参数:无
// 功能描述:处理写多线圈指令15
/****************************************************************************************/
#if WRITE_MULT_COIL_EN >0
void FWriteMultipleCoils(PDU_RESPONSE *Response)
{
	uint8 * PDUPtr;
	uint16 StAddr ,Quantity;
	uint8 	ByteCount;
	// 从请求PDU中提取相关参数
	PDUPtr = Response->PDUDataPtr;
	StAddr = PDUPtr[1]<<8|PDUPtr[2];
	Quantity =  PDUPtr[3]<<8|PDUPtr[4];
	ByteCount = PDUPtr[5];
	
	Response->PDUByteLength = 5 ;	// 正常返回的数据长度

	if((Quantity>=0x001)&&(Quantity<=0x07d0)&&(ByteCount==(Quantity/8+((Quantity%8)?1:0))))
	{
		if((StAddr<END_COILS_ADDR)&&((StAddr+Quantity)<=(END_COILS_ADDR+1)))
		{			
			if(WriteMultipleCoils(PDUPtr+6,StAddr,Quantity))
			{
				*(PDUPtr+1) = StAddr>>8;
				*(PDUPtr+2) = StAddr;
				*(PDUPtr+3) = Quantity>>8;
				*(PDUPtr+4) = Quantity;
				Response->ExceptionCode = 0x00;
			}
			else
				Response->ExceptionCode = 0x04;
		}
		else
			Response->ExceptionCode = 0x02;
	}
	else
		Response->ExceptionCode = 0x03;
}
#endif

/****************************************************************************************/
// 函数名称:FWriteMultipleReg
// 输入参数:Response
// 输出参数:无
// 功能描述:处理写多寄存器指令16
/****************************************************************************************/
#if WRITE_MULT_REG_EN >0
void FWriteMultipleReg(PDU_RESPONSE *Response)
{
	uint8 * PDUPtr;
	uint16 StAddr ,Quantity;
	uint8 	ByteCount;
	// 从请求PDU中提取相关参数
	PDUPtr = Response->PDUDataPtr;
	StAddr = PDUPtr[1]<<8|PDUPtr[2];
	Quantity =  PDUPtr[3]<<8|PDUPtr[4];
	ByteCount = PDUPtr[5];
	
	Response->PDUByteLength = 5 ;	// 正常返回的数据长度

	if((Quantity>=0x001)&&(Quantity<=0x007d)&&(ByteCount==(Quantity*2)))
	{
		if((StAddr<END_HOLDING_REG_ADDR) && ((StAddr+Quantity)<=(END_HOLDING_REG_ADDR+1)))
		{			
			if(WriteHoldingReg(PDUPtr+6,StAddr,Quantity))
			{
				*(PDUPtr+1) = StAddr>>8;
				*(PDUPtr+2) = StAddr;
				*(PDUPtr+3) = Quantity>>8;
				*(PDUPtr+4) = Quantity;
				Response->ExceptionCode = 0x00;
			}
			else
				Response->ExceptionCode = 0x04;
		}
		else
			Response->ExceptionCode = 0x02;
	}
	else
		Response->ExceptionCode = 0x03;
}
#endif

/****************************************************************************************/
// 函数名称:FMaskWriteReg
// 输入参数:Response
// 输出参数:无
// 功能描述:处理屏蔽寄存器指令22
/****************************************************************************************/
#if MASK_WRITE_REG_EN >0
void FMaskWriteReg(PDU_RESPONSE *Response)
{
	uint16 RefeAddr,And_Mask,Or_Mask,RegValue;
	uint8  *PDUPtr;
	uint8  ValueInByte[2];		
	PDUPtr = Response->PDUDataPtr;
	RefeAddr = (PDUPtr[1]<<8)|(PDUPtr[2]);
	And_Mask = (PDUPtr[3]<<8)|(PDUPtr[4]);
	Or_Mask  = (PDUPtr[5]<<8)|(PDUPtr[6]);
	
	Response->PDUByteLength = 7;
	
	if(RefeAddr<END_HOLDING_REG_ADDR)
	{
		if(ReadHoldingReg(ValueInByte,RefeAddr,1))
		{	
			RegValue = (ValueInByte[0]<<8)|(ValueInByte[1]);
			RegValue = (RegValue & And_Mask)|(Or_Mask & (~And_Mask));
			ValueInByte[0] = RegValue >> 8;
			ValueInByte[1] = RegValue ;
			if(WriteHoldingReg(ValueInByte,RefeAddr,1))
			{
				*(PDUPtr+1) = RefeAddr>>8;
				*(PDUPtr+2) = RefeAddr;
				*(PDUPtr+3) = And_Mask>>8;
				*(PDUPtr+4) = And_Mask;
				*(PDUPtr+5) = Or_Mask>>8;
				*(PDUPtr+6) = Or_Mask;
				Response->ExceptionCode = 0x00;
			}
			else
				Response->ExceptionCode = 0x04;
		}
		else
			Response->ExceptionCode = 0x03;
	}
	else
		Response->ExceptionCode = 0x02;
}
#endif

/****************************************************************************************/
// 函数名称:FRWMultipleReg
// 输入参数:Response
// 输出参数:无
// 功能描述:处理读写多寄存器指令23
/****************************************************************************************/
#if READ_WRITE_REG_EN > 0
void FRWMultipleReg(PDU_RESPONSE *Response)
{
	uint16 ReadStaAddr,	ReadQuantity;
	uint16 WriteStaAddr,WriteQuantity;
	uint8  WriteBytes;
	uint8  *WriteValuePtr;
	uint8  *PDUPtr;
	PDUPtr = Response->PDUDataPtr;
	ReadStaAddr   = (PDUPtr[1]<<8)|(PDUPtr[2]);
	ReadQuantity  = (PDUPtr[3]<<8)|(PDUPtr[4]);
	WriteStaAddr  = (PDUPtr[5]<<8)|(PDUPtr[6]);
	WriteQuantity = (PDUPtr[7]<<8)|(PDUPtr[8]);
	WriteBytes    = PDUPtr[9];
	WriteValuePtr = &PDUPtr[10];

	Response->PDUByteLength = ReadQuantity*2 + 2;
	
	if((ReadQuantity>=0x001)&&(ReadQuantity<=0x007d)&&		// 读寄存器的数量是否在有效范围内
	   (WriteQuantity>=0x001)&&(WriteQuantity<=0x0079)&&	// 写寄存器的数量是否在有效范围内
	   (WriteBytes==(WriteQuantity*2)))						// 接收到的字节数是否与写入的寄存器数量一至
	{
		if((ReadStaAddr<END_HOLDING_REG_ADDR)&&((ReadStaAddr+ReadQuantity)<=END_HOLDING_REG_ADDR)&&
		   (WriteStaAddr<END_HOLDING_REG_ADDR)&&((WriteStaAddr+WriteQuantity)<=END_HOLDING_REG_ADDR))
		{
			if(WriteHoldingReg(WriteValuePtr,WriteStaAddr,WriteQuantity))	// 写寄存器
			{
			   if(ReadHoldingReg(PDUPtr+2,ReadStaAddr,ReadQuantity))		// 读寄存器
				{
					*(PDUPtr+1) = ReadQuantity*2;
					Response->ExceptionCode = 0x00;
				}
				else 
					Response->ExceptionCode = 0x04;
			}
			else
				Response->ExceptionCode = 0x04;
		}
		else
			Response->ExceptionCode = 0x02;
	}
	else
		Response->ExceptionCode = 0x03;
}
#endif












⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -