|
|
@@ -1,6 +1,6 @@ |
|
|
/** |
|
|
/** |
|
|
* @file modbus_fc.c |
|
|
* @file modbus_fc.c |
|
|
* @brief Modbus 功能码 01/03/05/0F/10 与异常应答实现 |
|
|
|
|
|
|
|
|
* @brief Modbus 功能码 01/03/06/0F/10 与异常应答实现 |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
#include "modbus_fc.h" |
|
|
#include "modbus_fc.h" |
|
|
@@ -23,6 +23,7 @@ static void AppendCrcAndSend(uint8_t *pdu, uint16_t pduLen); |
|
|
static void SendException(uint8_t funcCode, uint8_t exCode); |
|
|
static void SendException(uint8_t funcCode, uint8_t exCode); |
|
|
static void ReadCoils(const uint8_t *frame, uint16_t len); |
|
|
static void ReadCoils(const uint8_t *frame, uint16_t len); |
|
|
static void ReadHoldingRegs(const uint8_t *frame, uint16_t len); |
|
|
static void ReadHoldingRegs(const uint8_t *frame, uint16_t len); |
|
|
|
|
|
static void WriteSingleReg(const uint8_t *frame, uint16_t len); |
|
|
static void WriteMultiCoils(const uint8_t *frame, uint16_t len); |
|
|
static void WriteMultiCoils(const uint8_t *frame, uint16_t len); |
|
|
static void WriteMultiRegs(const uint8_t *frame, uint16_t len); |
|
|
static void WriteMultiRegs(const uint8_t *frame, uint16_t len); |
|
|
|
|
|
|
|
|
@@ -63,6 +64,10 @@ void ProcessRequest(const uint8_t *frame, uint16_t len) |
|
|
ReadHoldingRegs(frame, len); |
|
|
ReadHoldingRegs(frame, len); |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case WRITE_SINGLE_REG: |
|
|
|
|
|
WriteSingleReg(frame, len); |
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
case WRITE_MULTI_COILS: |
|
|
case WRITE_MULTI_COILS: |
|
|
WriteMultiCoils(frame, len); |
|
|
WriteMultiCoils(frame, len); |
|
|
break; |
|
|
break; |
|
|
@@ -188,6 +193,51 @@ static void ReadHoldingRegs(const uint8_t *frame, uint16_t len) |
|
|
AppendCrcAndSend(g_modbus_tx_buf, (uint16_t)(3U + byteCount)); |
|
|
AppendCrcAndSend(g_modbus_tx_buf, (uint16_t)(3U + byteCount)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*============================================================================*/ |
|
|
|
|
|
/* 功能码 06:写单个保持寄存器 */ |
|
|
|
|
|
/*============================================================================*/ |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @brief 处理写单个保持寄存器请求(0x06) |
|
|
|
|
|
* @param[in] frame 完整请求 ADU |
|
|
|
|
|
* @param[in] len 合法请求固定为 8 |
|
|
|
|
|
* |
|
|
|
|
|
* 读写都经 WriteHoldReg / ReadHoldReg,落在 g_hold_reg[]。 |
|
|
|
|
|
* 应答回显地址与写入值。 |
|
|
|
|
|
*/ |
|
|
|
|
|
static void WriteSingleReg(const uint8_t *frame, uint16_t len) |
|
|
|
|
|
{ |
|
|
|
|
|
uint16_t addr; |
|
|
|
|
|
uint16_t value; |
|
|
|
|
|
|
|
|
|
|
|
if (len != 8U) |
|
|
|
|
|
{ |
|
|
|
|
|
SendException(WRITE_SINGLE_REG, ILLEGAL_DATA_VALUE); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
addr = ReadU16Be(&frame[2]); |
|
|
|
|
|
value = ReadU16Be(&frame[4]); |
|
|
|
|
|
|
|
|
|
|
|
if (ModbusIsRegRangeValid(addr, 1U) == 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
SendException(WRITE_SINGLE_REG, ILLEGAL_DATA_ADDRESS); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
WriteHoldReg(addr, value); |
|
|
|
|
|
|
|
|
|
|
|
g_modbus_tx_buf[0] = frame[0]; |
|
|
|
|
|
g_modbus_tx_buf[1] = WRITE_SINGLE_REG; |
|
|
|
|
|
g_modbus_tx_buf[2] = frame[2]; |
|
|
|
|
|
g_modbus_tx_buf[3] = frame[3]; |
|
|
|
|
|
g_modbus_tx_buf[4] = frame[4]; |
|
|
|
|
|
g_modbus_tx_buf[5] = frame[5]; |
|
|
|
|
|
AppendCrcAndSend(g_modbus_tx_buf, 6U); |
|
|
|
|
|
|
|
|
|
|
|
PlsrParamBlockOnHoldWrite(addr, 1U); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/*============================================================================*/ |
|
|
/*============================================================================*/ |
|
|
/* 功能码 0F:写多个线圈 */ |
|
|
/* 功能码 0F:写多个线圈 */ |
|
|
/*============================================================================*/ |
|
|
/*============================================================================*/ |
|
|
|