📄 mb_pfunction.c
字号:
/****************************************Copyright (c)**************************************************
** 广州周立功单片机发展有限公司
** 研 究 所
** 产品一部
**
** http://www.zlgmcu.com
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: MB_PFunction.c
**创 建 人: 周立山
**最后修改日期: 2005年7月29日
**描 述: MODBUS RTU 协议栈
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 周立山
** 版 本: 1.0a
** 日 期: 2005年7月29日
** 描 述: 原始版本
**
**------------------------------------------------------------------------------------------------------
** 修改人:
** 版 本:
** 日 期:
** 描 述:
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include "config.h"
#include "modbus.h"
//**************************************************
// 函数名称:MB_GetDiscrete
// 输入参数:Address,线圈地址
// 输出参数:返回线圈值(0\1)
// 功能描述:获取离散值函数,访函数由用户编写
//**************************************************
uint8 MB_GetDiscrete(uint16 Address);
//**************************************************
// 函数名称:MB_GetCoils
// 输入参数:Address,线圈地址
// 输出参数:返回线圈值(0\1)
// 功能描述:获取线圈值函数,访函数由用户编写
//**************************************************
uint8 MB_GetCoils(uint16 Address);
//**************************************************
// 函数名称:MB_SetCoil
// 输入参数:Address,线圈地址
// CoilValue,线圈值(0\1)
// 输出参数:返回寄存器值
// 功能描述:设置线圈值函数,访函数由用户编写
//**************************************************
uint8 MB_SetCoil(uint16 Address,uint8 CoilValue);
//**************************************************
// 函数名称:MB_GetInputRegValue
// 输入参数:Address,寄存器地址
// 输出参数:返回寄存器值
// 功能描述:读输入寄存器值函数,访函数由用户编写
//**************************************************
uint16 MB_GetInputRegValue(uint16 Address);
//**************************************************
// 函数名称:MB_GetRegValue
// 输入参数:Address,寄存器地址
// 输出参数:返回寄存器值
// 功能描述:读保持寄存器值函数,访函数由用户编写
//**************************************************
uint16 MB_GetRegValue(uint16 Address);
//**************************************************
// 函数名称:MB_SetRegValue
// 输入参数:Address,寄存器地址
// Value,写入的值
// 输出参数:无
// 功能描述:写保持寄存器值函数,访函数由用户编写
//**************************************************
void MB_SetRegValue(uint16 Address,uint16 Value);
/****************************************************************************************/
// 函数名称:FReadCoils
// 输入参数:Response
// 输出参数:无
// 功能描述:处理读单线圈指令01
/***************************************************************************************/
void FReadCoils(PDU_RESPONSE *Response);
/****************************************************************************************/
// 函数名称:FReadDiscreteInputs
// 输入参数:Response
// 输出参数:无
// 功能描述:处理读离散输入指令02
/***************************************************************************************/
void FReadDiscreteInputs(PDU_RESPONSE *Response);
/****************************************************************************************/
// 函数名称:FReadHoldingReg
// 输入参数:Response
// 输出参数:无
// 功能描述:处理读保持寄存器指令03
/****************************************************************************************/
void FReadHoldingReg(PDU_RESPONSE *Response);
/****************************************************************************************/
// 函数名称:FReadInputReg
// 输入参数:Response
// 输出参数:无
// 功能描述:处理读输入寄存器指令04
/****************************************************************************************/
void FReadInputReg(PDU_RESPONSE *Response);
/****************************************************************************************/
// 函数名称:FWriteSingleCoil
// 输入参数:Response
// 输出参数:无
// 功能描述:处理写单线圈指令05
/****************************************************************************************/
void FWriteSingleCoil(PDU_RESPONSE *Response);
/****************************************************************************************/
// 函数名称:FWriteSingleReg
// 输入参数:Response
// 输出参数:无
// 功能描述:处理写单线圈指令06
/****************************************************************************************/
void FWriteSingleReg(PDU_RESPONSE *Response);
/****************************************************************************************/
// 函数名称:FWriteMultipleCoils
// 输入参数:Response
// 输出参数:无
// 功能描述:处理写多线圈指令15
/****************************************************************************************/
void FWriteMultipleCoils(PDU_RESPONSE *Response);
/****************************************************************************************/
// 函数名称:FWriteMultipleReg
// 输入参数:Response
// 输出参数:无
// 功能描述:处理写多寄存器指令16
/****************************************************************************************/
void FWriteMultipleReg(PDU_RESPONSE *Response);
/****************************************************************************************/
// 函数名称:FMaskWriteReg
// 输入参数:Response
// 输出参数:无
// 功能描述:处理屏蔽寄存器指令22
/****************************************************************************************/
void FMaskWriteReg(PDU_RESPONSE *Response);
/****************************************************************************************/
// 函数名称:FRWMultipleReg
// 输入参数:Response
// 输出参数:无
// 功能描述:处理读写多寄存器指令23
/****************************************************************************************/
void FRWMultipleReg(PDU_RESPONSE *Response);
void FTest(PDU_RESPONSE *Response){}
AT_CODE FUNCTION_ARRAY FCodeHandleArray[MAX_FUNCTION]={
#if READ_COILS_EN > 0
{0x01,FReadCoils}, // 读线圈
#endif
#if READ_DIS_INPUT_EN > 0
{0x02,FReadDiscreteInputs}, // 读离散量输入
#endif
#if READ_HOLD_REG_EN > 0
{0x03,FReadHoldingReg}, // 读保持寄存器
#endif
#if READ_INPUT_REG_EN > 0
{0x04,FReadInputReg}, // 读输入寄存器
#endif
#if WRITE_SING_COIL_EN > 0
{0x05,FWriteSingleCoil}, // 写单个线圈
#endif
#if WRITE_SING_REG_EN > 0
{0x06,FWriteSingleReg}, // 写单个寄存器
#endif
#if WRITE_MULT_COIL_EN > 0
{0x0f,FWriteMultipleCoils}, // 写多个线圈
#endif
#if WRITE_MULT_REG_EN > 0
{0x10,FWriteMultipleReg}, // 写多个寄存器
#endif
#if MASK_WRITE_REG_EN > 0
{0x16,FMaskWriteReg}, // 处理屏蔽寄存器指令
#endif
#if READ_WRITE_REG_EN > 0
{0x17,FRWMultipleReg}, // 读写多个寄存器
#endif
{0x00,FTest} // 测试功能代码
};
#if READ_DIS_INPUT_EN
//************************************************************************************
// 函数名称:ReadDiscreteInputs
// 输入参数:CoilsDataPtr,存放离散输入数据指针
// StAddr,离散的起始地址
// Quantity,离散的数量
// 输出参数:正常返回TRUE,出错返回FALSE。
// 功能描述:读离散输入操作函数
//************************************************************************************
uint8 ReadDiscreteInputs(uint8 *CoilsDataPtr,uint16 StAddr ,uint16 Quantity)
{
uint8 *CoilsInByte;
uint8 offset;
uint16 i=0 ;
CoilsInByte = CoilsDataPtr;
while(i<Quantity)
{
*CoilsInByte = 0;
for(offset=0;offset<8;offset++,i++) // 将线圈值写入一个字节
{
if(i<Quantity)
{
*CoilsInByte |= MB_GetDiscrete(StAddr+i)<<offset;
}
}
CoilsInByte++;
}
return TRUE;
}
#endif
#if READ_COILS_EN
//************************************************************************************
// 函数名称:ReadCoils
// 输入参数:CoilsDataPtr,存放线圈数据指针
// StAddr,线圈的起始地址
// Quantity,线圈的数量
// 输出参数:正常返回TRUE,出错返回FALSE。
// 功能描述:读多线圈操作函数
//************************************************************************************
uint8 ReadCoils(uint8 *CoilsDataPtr,uint16 StAddr ,uint16 Quantity)
{
uint8 *CoilsInByte;
uint8 offset;
uint16 i=0 ;
CoilsInByte = CoilsDataPtr;
while(i<Quantity)
{
*CoilsInByte = 0;
for(offset=0;offset<8;offset++,i++) // 将线圈值写入一个字节
{
if(i<Quantity)
{
*CoilsInByte |= MB_GetCoils(StAddr+i)<<offset;
}
}
CoilsInByte++;
}
return TRUE;
}
#endif
#if WRITE_SING_COIL_EN
//************************************************************************************
// 函数名称:WriteSingleCoil
// 输入参数:DataPtr,数据指针,
// StAddr,寄存器起始地址
// Quantity,寄存器数量。
// 输出参数:正常返回TRUE,出错返回FALSE。
// 功能描述:写单线圈处理函数
//************************************************************************************
uint8 WriteSingleCoil(uint16 OutputAddr,uint16 OutputValue)
{
return MB_SetCoil(OutputAddr,(OutputValue==0xff00)?1:0);
}
#endif
#if WRITE_MULT_COIL_EN
//************************************************************************************
// 函数名称:WriteMultipleCoils
// 输入参数:DataPtr,数据指针,
// StAddr,寄存器起始地址
// Quantity,寄存器数量。
// 输出参数:正常返回TRUE,出错返回FALSE。
// 功能描述:写多线圈处理函数
//************************************************************************************
uint8 WriteMultipleCoils(uint8 *DataPtr,uint16 StAddr ,uint16 Quantity)
{
uint16 i;
uint8 CoilInByte;
for(i=0;i<Quantity;i++)
{
if((i%8)==0)
CoilInByte = *(DataPtr+(i/8));
if( FALSE == MB_SetCoil(StAddr+i,(CoilInByte>>(i%8))&0x01))
return FALSE;
}
return TRUE;
}
#endif
#if READ_INPUT_REG_EN
//************************************************************************************
// 函数名称:ReadInputReg
// 输入参数:DataPtr,数据指针,
// StAddr,寄存器起始地址
// Quantity,寄存器数量。
// 输出参数:正常返回TRUE,出错返回FALSE。
// 功能描述:读输入寄存器
//************************************************************************************
uint8 ReadInputReg(uint8 *DataPtr,uint16 StAddr ,uint16 Quantity)
{
uint8 i;
uint16 Value;
for(i=0;i<Quantity;i++)
{
Value = MB_GetInputRegValue(StAddr+i);
*(DataPtr+i*2) = (uint8)(Value>>8); // 先传高位
*(DataPtr+i*2+1) = (uint8)Value; // 后传低位
}
return TRUE;
}
#endif
#if (READ_HOLD_REG_EN | READ_WRITE_REG_EN)
//************************************************************************************
// 函数名称:ReadHoldingReg
// 输入参数:DataPtr,数据指针,16位数据高8位在低字节,低8位在高字节
// StAddr,寄存器起始地址
// Quantity,寄存器数量。
// 输出参数:正常返回TRUE,出错返回FALSE。
// 功能描述:读寄存器处理函数
//************************************************************************************
uint8 ReadHoldingReg(uint8 *DataPtr,uint16 StAddr ,uint16 Quantity)
{
uint8 i;
uint16 Value;
for(i=0;i<Quantity;i++)
{
Value = MB_GetRegValue(StAddr+i);
*(DataPtr+i*2) = (uint8)(Value>>8); // 先传高位
*(DataPtr+i*2+1) = (uint8)Value; // 后传低位
}
return TRUE;
}
#endif
#if (WRITE_SING_REG_EN | WRITE_MULT_REG_EN |\
MASK_WRITE_REG_EN | READ_WRITE_REG_EN )
//************************************************************************************
// 函数名称:WriteHoldingReg
// 输入参数:DataPtr,数据指针,16位数据高8位在低字节,低8位在高字节
// StAddr,寄存器起始地址
// Quantity,寄存器数量。
// 输出参数:正常返回TRUE,出错返回FALSE。
// 功能描述:写寄存器处理函数
//************************************************************************************
uint8 WriteHoldingReg(uint8 *KeepDataPtr,uint16 StAddr ,uint16 Quantity)
{
uint8 i;
uint16 Value;
for(i=0;i<Quantity;i++)
{
Value = (*(KeepDataPtr+i*2)<<8)|(*(KeepDataPtr+i*2+1));
MB_SetRegValue(StAddr+i,Value);
}
return TRUE;
}
#endif
/****************************************************************************************/
// 函数名称:FReadCoils
// 输入参数:Response,为PDU_RESPONSE类型的指针,PDU_RESPONSE:
// typedef struct __PDU_RESPONSE{
// uint8* PDUDataPtr; 请求数据指针,功能代码处理函数必需将处理的数据包存在该指针的开始位始
// uint8 PDUByteLength;请求数据数长度
// uint8 ExceptionCode;仅为输出错异常代码,正常操作设为0
// }PDU_RESPONSE
// 输出参数:无
// 功能描述:处理读多线圈指令01
/***************************************************************************************/
#if READ_COILS_EN >0
void FReadCoils(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_COILS_ADDR)&&((StAddr+Quantity)<=END_COILS_ADDR))
{
if(ReadCoils(PDUPtr+2,StAddr,Quantity))
{
*(PDUPtr+1) = Quantity/8+(Quantity%8)?1:0; // 字节数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -