/************************************************************************/
/*  “文件包含”处理                                                       */
/************************************************************************/
#include "modbus_slave.h"
//#include "bsp_dma.h"
//#include "bsp_time.h"
//#include "bsp_usart.h"
//#include "crc16.h"

/************************************************************************/
/*  全局变量定义                                                         */
/************************************************************************/
Modbus_Slave_t modbus_slave = {0};
uint16_t test_hold_reg[3] = {0};// 03  06 10 功能码使用
uint8_t test_led[15] = {0};// 01 05  功能码使用
uint8_t test_adc[5] = {0x66, 0x77};// 04  功能码使用
/************************************************************************/
/*  函数声明                                                             */
/************************************************************************/
static void MODBUS_SLAVE_FunctionCodeHandle(void);
static void MODBUS_SLAVE_01H(void);// 01功能码通过修改test_led[15]数组的值
static void MODBUS_SLAVE_02H(void);// 02功能码通过函数MODBUS_SLAVE_BSP_GetKeyState 返回值
static void MODBUS_SLAVE_03H(void);// 03功能码通过读取test_hold_reg[3]数组的值
static void MODBUS_SLAVE_04H(void);// 04功能码通过读取test_adc[5]数组的值
static void MODBUS_SLAVE_05H(void);// 05功能码通过修改test_led[15]数组的值
static void MODBUS_SLAVE_06H(void);// 06功能码通过修改test_hold_reg[3]数组的值
static void MODBUS_SLAVE_10H(void);// 10功能码通过修改多个test_hold_reg[3]数组的值
static void MODBUS_SLAVE_0FH(void);// 0F功能码通过修改多个test_led[15]数组的值
void MODBUS_SLAVE_SendAckErr(uint8_t ErrCode);

extern uint8_t usart1_rx_buffer[1024];
extern uint16_t usart1_rx_counter;
extern uint8_t receive_ok_flag, receive_counter;
//Modbus主程序
void MODBUS_SLAVE_Pool(void)
{
    uBit16 addr;
    uint32_t crc1;

    if (modbus_slave.recv_len < 4)  /* 接收到的数据小于4个字节就认为错误 */
    {
        printf("error1\n");
    }

    /* 计算CRC校验和 */
		crc_data_reset();
    crc1 = crc8_block_calculate((uint8_t *)modbus_slave.rx_buf, modbus_slave.recv_len);
    //printf("crc1 0x%04x\n",crc1);
    if (crc1 != 0)
    {
        printf("error2\n");
    }

    /* 站地址 (1字节） */
    addr = modbus_slave.rx_buf[0];                /* 第1字节 站号 */

    if (addr != SADDR485)                 /* 判断主机发送的命令地址是否符合 */
    {
        printf("error3\n");
    }

    //功能码处理
    MODBUS_SLAVE_FunctionCodeHandle();


    receive_counter = 0;
    receive_ok_flag = 0;
    modbus_slave.recv_len = 0;
}

//Modbus功能码处理
static void MODBUS_SLAVE_FunctionCodeHandle(void)
{
    switch (modbus_slave.rx_buf[1])             /* 第2个字节 功能码 */
    {
        case 0x01:  /* 读取线圈状态（此例程用led代替）*/
            MODBUS_SLAVE_01H();
            break;

        case 0x02:  /* 读取输入状态（按键状态）*/
            MODBUS_SLAVE_02H();
            break;

        case 0x03:  /* 读取保持寄存器*/
            MODBUS_SLAVE_03H();
            break;

        case 0x04:  /* 读取输入寄存器（ADC的值）*/
            MODBUS_SLAVE_04H();
            break;

        case 0x05:  /* 强制单线圈（设置led）*/
            MODBUS_SLAVE_05H();
            break;

        case 0x06:  /* 写单个保存寄存器*/
            MODBUS_SLAVE_06H();
            break;

        case 0x10:  /* 写多个保存寄存器*/
            MODBUS_SLAVE_10H();
            break;

        case 0x0F:  /* 写多个线圈寄存器*/
            MODBUS_SLAVE_0FH();
            break;

        default:
            modbus_slave.RTU_response_code = RSP_ERR_CMD;
            MODBUS_SLAVE_SendAckErr(modbus_slave.RTU_response_code);    /* 告诉主机命令错误 */
            break;
    }
}


//将两字节转换为16位
uBit16 MODBUS_SLAVE_BEBufToUint16(uBit8 *_pBuf)
{
    return (((uBit16)_pBuf[0] << 8) | _pBuf[1]);
}


//串口发送
void MODBUS_SLAVE_UartSend(uBit8 *buf, uBit16 len, uBit8 crc_l, uBit8 crc_h)
{
    // 发送数据缓冲区中的数据
    for (uint16_t i = 0; i < len; i++)
    {
        while (usart_flag_get(USART1, USART_TDBE_FLAG) == RESET); // 等待发送缓冲区为空

        usart_data_transmit(USART1, buf[i]); // 发送当前字节
    }

    // 发送CRC校验值
    while (usart_flag_get(USART1, USART_TDBE_FLAG) == RESET); // 等待发送缓冲区为空

    usart_data_transmit(USART1, crc_l); // 发送CRC低字节

    while (usart_flag_get(USART1, USART_TDBE_FLAG) == RESET); // 等待发送缓冲区为空

    usart_data_transmit(USART1, crc_h); // 发送CRC高字节

    // 等待所有数据发送完成
    while (usart_flag_get(USART1, USART_TDC_FLAG) == RESET);
}


//发送加crc
void MODBUS_SLAVE_SendWithCRC(uint8_t *buf, uint8_t len)
{
    uint16_t crc;
    uint8_t crc_h, crc_l;
    crc_data_reset();
    crc = crc8_block_calculate(buf, len);
    //printf("\n0x%04x\n",crc);
    crc_l = (uint8_t)(crc & 0xff);
    crc_h = crc >> 8;
    MODBUS_SLAVE_UartSend(buf, len, crc_l, crc_h);
}


//发送错误应答  ErrCode : 错误代码
void MODBUS_SLAVE_SendAckErr(uint8_t ErrCode)
{
    modbus_slave.send_len = 0;

    modbus_slave.tx_buf[modbus_slave.send_len++] = modbus_slave.rx_buf[0];          /* 485地址 */
    modbus_slave.tx_buf[modbus_slave.send_len++] = modbus_slave.rx_buf[1] | 0x80;   /* 异常的功能码 */
    modbus_slave.tx_buf[modbus_slave.send_len++] = ErrCode;                      /* 错误代码(01,02,03,04) */

    MODBUS_SLAVE_SendWithCRC(modbus_slave.tx_buf, modbus_slave.send_len);
}

//判断LED指示灯是否已经点亮
uint8_t MODBUS_SLAVE_BSPIsLedOn(uint8_t num)
{
    if (num == 1)
    {
        if (test_led[0])
        {
            return 1;
        }

        return 0;
    }
    else if (num == 2)
    {
        if (test_led[1])
        {
            return 1;
        }

        return 0;
    }
    else if (num == 3)
    {
        if (test_led[2])
        {
            return 1;
        }

        return 0;
    }
    else if (num == 4)
    {
        if (test_led[3])
        {
            return 1;
        }

        return 0;
    }

    return 0;
}


//读线圈状态功能码 01H
static void MODBUS_SLAVE_01H(void)
{
    uBit16 reg;
    uBit16 num;
    uBit16 i;
    uBit16 m;
    uBit8 status[10];

    modbus_slave.RTU_response_code = RSP_OK;

    if (modbus_slave.recv_len != 8)
    {
        modbus_slave.RTU_response_code = RSP_ERR_VALUE; // 数据值域错误
        return;
    }

    reg = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[2]);   // 寄存器号
    num = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[4]);   // 寄存器个数

    m = (num + 7) / 8;

    if ((reg >= REG_D01) && (num > 0) && (reg + num <= REG_DXX + 1))
    {
        for (i = 0; i < m; i++)
        {
            status[i] = 0;
        }

        for (i = 0; i < num; i++)
        {
            if (MODBUS_SLAVE_BSPIsLedOn(i + 1 + reg - REG_D01)) // 读LED的状态，写入状态寄存器的每一位
            {
                status[i / 8] |= (1 << (i % 8));
            }
        }
    }
    else
    {
        modbus_slave.RTU_response_code = RSP_ERR_REG_ADDR;  // 寄存器地址错误
    }

    if (modbus_slave.RTU_response_code == RSP_OK)   // 正确应答
    {
        modbus_slave.send_len = 0;
        modbus_slave.tx_buf[modbus_slave.send_len++] = modbus_slave.rx_buf[0];
        modbus_slave.tx_buf[modbus_slave.send_len++] = modbus_slave.rx_buf[1];
        modbus_slave.tx_buf[modbus_slave.send_len++] = m;   // 返回字节数

        for (i = 0; i < m; i++)
        {
            modbus_slave.tx_buf[modbus_slave.send_len++] = status[i];
        }

        MODBUS_SLAVE_SendWithCRC(modbus_slave.tx_buf, modbus_slave.send_len);
    }
    else
    {
        MODBUS_SLAVE_SendAckErr(modbus_slave.RTU_response_code);    // 告诉主机命令错误
    }
}


//02读取输入状态
uint8_t MODBUS_SLAVE_BSP_GetKeyState(uint8_t _ucKeyID)
{
    return 1;//此处应该返回按键按下状态，这里模拟都为1
}

//读取输入状态功能码 02H
static void MODBUS_SLAVE_02H(void)
{
    uint16_t reg;
    uint16_t num;
    uint16_t i;
    uint16_t m;
    uint8_t status[10];

    modbus_slave.RTU_response_code = RSP_OK;

    if (modbus_slave.recv_len != 8)
    {
        modbus_slave.RTU_response_code = RSP_ERR_VALUE; /* 数据值域错误 */
        return;
    }

    reg = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[2]);   /* 寄存器号 */
    num = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[4]);   /* 寄存器个数 */

    m = (num + 7) / 8;

    if ((reg >= REG_T01) && (num > 0) && (reg + num <= REG_TXX + 1))
    {
        for (i = 0; i < m; i++)
        {
            status[i] = 0;
        }

        for (i = 0; i < num; i++)
        {
            if (MODBUS_SLAVE_BSP_GetKeyState(reg - REG_T01 + i))
            {
                status[i / 8] |= (1 << (i % 8));
            }
        }
    }
    else
    {
        modbus_slave.RTU_response_code = RSP_ERR_REG_ADDR;  /* 寄存器地址错误 */
    }

    if (modbus_slave.RTU_response_code == RSP_OK)   /* 正确应答 */
    {
        modbus_slave.send_len = 0;
        modbus_slave.tx_buf[modbus_slave.send_len++] = modbus_slave.rx_buf[0];
        modbus_slave.tx_buf[modbus_slave.send_len++] = modbus_slave.rx_buf[1];
        modbus_slave.tx_buf[modbus_slave.send_len++] = m;   /* 返回字节数 */

        for (i = 0; i < m; i++)
        {
            modbus_slave.tx_buf[modbus_slave.send_len++] = status[i];   /* T01-02状态 */
        }

        MODBUS_SLAVE_SendWithCRC(modbus_slave.tx_buf, modbus_slave.send_len);
    }
    else
    {
        MODBUS_SLAVE_SendAckErr(modbus_slave.RTU_response_code);    /* 告诉主机命令错误 */
    }
}

//读取保持寄存器的值
uint8_t MODBUS_SLAVE_ReadRegValue(uint16_t reg_addr, uint8_t *reg_value)
{
    uint16_t value;

    switch (reg_addr)   /* 判断寄存器地址 */
    {
        case SLAVE_REG_P01:
            value = test_hold_reg[0];
            break;

        case SLAVE_REG_P02:
            value = test_hold_reg[1];   /* 将寄存器值读出 */
            break;
        case SLAVE_REG_P03:
            value = test_hold_reg[1];   /* 将寄存器值读出 */
            break;
        case SLAVE_REG_P04:
            value = test_hold_reg[1];   /* 将寄存器值读出 */
            break;
        default:
            return 0;   /* 参数异常，返回 0 */
    }

    reg_value[0] = value >> 8;
    reg_value[1] = value;

    return 1;   /* 读取成功 */
}


//读取保持寄存器功能码 03H
static void MODBUS_SLAVE_03H(void)
{
    uint16_t reg;
    uint16_t num;
    uint16_t i;
    uint8_t reg_value[64];

    modbus_slave.RTU_response_code = RSP_OK;

    if (modbus_slave.recv_len != 8) /* 03H命令必须是8个字节 */
    {
        modbus_slave.RTU_response_code = RSP_ERR_VALUE; /* 数据值域错误 */
        goto err_ret;
    }

    reg = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[2]);   /* 寄存器号 */
    num = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[4]);   /* 寄存器个数 */

    if (num > sizeof(reg_value) / 2)
    {
        modbus_slave.RTU_response_code = RSP_ERR_VALUE; /* 数据值域错误 */
        goto err_ret;
    }

    for (i = 0; i < num; i++)
    {
        if (MODBUS_SLAVE_ReadRegValue(reg, &reg_value[2 * i]) == 0) /* 读出寄存器值放入reg_value */
        {
            modbus_slave.RTU_response_code = RSP_ERR_REG_ADDR;  /* 寄存器地址错误 */
            break;
        }

        reg++;
    }

err_ret:

    if (modbus_slave.RTU_response_code == RSP_OK)   /* 正确应答 */
    {
        modbus_slave.send_len = 0;
        modbus_slave.tx_buf[modbus_slave.send_len++] = modbus_slave.rx_buf[0];
        modbus_slave.tx_buf[modbus_slave.send_len++] = modbus_slave.rx_buf[1];
        modbus_slave.tx_buf[modbus_slave.send_len++] = num * 2; /* 返回字节数 */

        for (i = 0; i < num; i++)
        {
            modbus_slave.tx_buf[modbus_slave.send_len++] = reg_value[2*i];
            modbus_slave.tx_buf[modbus_slave.send_len++] = reg_value[2*i+1];
        }

        MODBUS_SLAVE_SendWithCRC(modbus_slave.tx_buf, modbus_slave.send_len);   /* 发送正确应答 */
    }
    else
    {
        MODBUS_SLAVE_SendAckErr(modbus_slave.RTU_response_code);    /* 发送错误应答 */
    }
}

//读取输入寄存器功能码 04H
static void MODBUS_SLAVE_04H(void)
{
    uint16_t reg;
    uint16_t num;
    uint16_t i;
    uint16_t status[10];

    memset(status, 0, 10);

    modbus_slave.RTU_response_code = RSP_OK;

    if (modbus_slave.recv_len != 8)
    {
        modbus_slave.RTU_response_code = RSP_ERR_VALUE; /* 数据值域错误 */
        goto err_ret;
    }

    reg = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[2]);   /* 寄存器号 */
    num = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[4]);   /* 寄存器个数 */

    if ((reg >= REG_A01) && (num > 0) && (reg + num <= REG_AXX + 1))
    {
        for (i = 0; i < num; i++)
        {
            switch (reg)
            {
                /* 测试参数 */
                case REG_A01:
                    status[i] = test_adc[0];
                    break;

                default:
                    status[i] = 0;
                    break;
            }

            reg++;
        }
    }
    else
    {
        modbus_slave.RTU_response_code = RSP_ERR_REG_ADDR;  /* 寄存器地址错误 */
    }

err_ret:

    if (modbus_slave.RTU_response_code == RSP_OK)   /* 正确应答 */
    {
        modbus_slave.send_len = 0;
        modbus_slave.tx_buf[modbus_slave.send_len++] = modbus_slave.rx_buf[0];
        modbus_slave.tx_buf[modbus_slave.send_len++] = modbus_slave.rx_buf[1];
        modbus_slave.tx_buf[modbus_slave.send_len++] = num * 2; /* 返回字节数 */

        for (i = 0; i < num; i++)
        {
            modbus_slave.tx_buf[modbus_slave.send_len++] = status[i] >> 8;
            modbus_slave.tx_buf[modbus_slave.send_len++] = status[i] & 0xFF;
        }

        MODBUS_SLAVE_SendWithCRC(modbus_slave.tx_buf, modbus_slave.send_len);
    }
    else
    {
        MODBUS_SLAVE_SendAckErr(modbus_slave.RTU_response_code);    /* 告诉主机命令错误 */
    }
}

//强制单线圈功能码 05H
static void MODBUS_SLAVE_05H(void)
{
    uint16_t reg;
    uint16_t value;

    modbus_slave.RTU_response_code = RSP_OK;

    if (modbus_slave.recv_len != 8)
    {
        modbus_slave.RTU_response_code = RSP_ERR_VALUE; /* 数据值域错误 */
        goto err_ret;
    }

    reg = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[2]);   /* 寄存器号 */
    value = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[4]); /* 数据 */

    if ((value>>8) != 0x00 && (value>>8) != 0xFF)
    {
        modbus_slave.RTU_response_code = RSP_ERR_VALUE; /* 数据值域错误 */
        goto err_ret;
    }

    //此处处理可以优化
    if (value>>8)//右移8位为0xFF 则值1 表示打开
        value = 1;
    else//右移8位为0x00 则值0 表示关闭
        value = 0;

    if (reg == REG_D01)
    {
        test_led[0] = value;//模拟LED状态
    }
    else if (reg == REG_D02)
    {
        test_led[1] = value;
    }
    else if (reg == REG_D03)
    {
        test_led[2] = value;
    }
    else if (reg == REG_D04)
    {
        test_led[3] = value;//模拟LED状态
    }
    else
    {
        modbus_slave.RTU_response_code = RSP_ERR_REG_ADDR;  /* 寄存器地址错误 */
    }

err_ret:

    if (modbus_slave.RTU_response_code == RSP_OK)   /* 正确应答 */
    {
        //此命令码应答报文与请求报文一致
        memcpy(modbus_slave.tx_buf, modbus_slave.rx_buf, modbus_slave.recv_len - 2);//不复制crc位
        modbus_slave.send_len = (modbus_slave.recv_len - 2);//不复制crc位
        MODBUS_SLAVE_SendWithCRC(modbus_slave.tx_buf, modbus_slave.send_len);
    }
    else
    {
        MODBUS_SLAVE_SendAckErr(modbus_slave.RTU_response_code);    /* 告诉主机命令错误 */
    }
}


//读取保持寄存器的值
uint8_t MODBUS_SLAVE_WriteRegValue(uint16_t reg_addr, uint16_t reg_value)
{
    switch (reg_addr)   /* 判断寄存器地址 */
    {
        case SLAVE_REG_P01:
            test_hold_reg[0] = reg_value;   /* 将值写入保存寄存器 */
            break;

        case SLAVE_REG_P02:
            test_hold_reg[1] = reg_value;   /* 将值写入保存寄存器 */
            break;

        default:
            return 0;   /* 参数异常，返回 0 */
    }

    return 1;   /* 读取成功 */
}

//写单个寄存器功能码 06H
static void MODBUS_SLAVE_06H(void)
{
    uint16_t reg;
    uint16_t value;

    modbus_slave.RTU_response_code = RSP_OK;

    if (modbus_slave.recv_len != 8)
    {
        modbus_slave.RTU_response_code = RSP_ERR_VALUE; /* 数据值域错误 */
        goto err_ret;
    }

    reg = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[2]);   /* 寄存器号 */
    value = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[4]); /* 寄存器值 */

    if (MODBUS_SLAVE_WriteRegValue(reg, value) == 1)    /* 该函数会把写入的值存入寄存器 */
    {
        ;
    }
    else
    {
        modbus_slave.RTU_response_code = RSP_ERR_REG_ADDR;  /* 寄存器地址错误 */
    }

err_ret:

    if (modbus_slave.RTU_response_code == RSP_OK)   /* 正确应答 */
    {
        //此命令码应答报文与请求报文一致
        memcpy(modbus_slave.tx_buf, modbus_slave.rx_buf, modbus_slave.recv_len - 2);//不复制crc位
        modbus_slave.send_len = (modbus_slave.recv_len - 2);//不复制crc位
        MODBUS_SLAVE_SendWithCRC(modbus_slave.tx_buf, modbus_slave.send_len);
    }
    else
    {
        MODBUS_SLAVE_SendAckErr(modbus_slave.RTU_response_code);    /* 告诉主机命令错误 */
    }
}

//写多个寄存器功能码 10H
static void MODBUS_SLAVE_10H(void)
{
    uint16_t reg_addr;
    uint16_t reg_num;
    uint8_t byte_num;
    uint8_t i;
    uint16_t value;

    modbus_slave.RTU_response_code = RSP_OK;

    if (modbus_slave.recv_len < 11)
    {
        modbus_slave.RTU_response_code = RSP_ERR_VALUE; /* 数据值域错误 */
        goto err_ret;
    }

    reg_addr = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[2]);  /* 寄存器号 */
    reg_num = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[4]);   /* 寄存器个数 */
    byte_num = modbus_slave.rx_buf[6];  /* 后面的数据体字节数 */

    if (byte_num != 2 * reg_num)
    {
        ;
    }

    for (i = 0; i < reg_num; i++)
    {
        value = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[7 + 2 * i]); /* 寄存器值 */

        if (MODBUS_SLAVE_WriteRegValue(reg_addr + i, value) == 1)
        {
            ;
        }
        else
        {
            modbus_slave.RTU_response_code = RSP_ERR_REG_ADDR;  /* 寄存器地址错误 */
            break;
        }
    }

err_ret:

    if (modbus_slave.RTU_response_code == RSP_OK)   /* 正确应答 */
    {
        //此命令码应答报文与请求报文一致
        memcpy(modbus_slave.tx_buf, modbus_slave.rx_buf, 6);//不复制crc位
        modbus_slave.send_len = 6;//不复制crc位
        MODBUS_SLAVE_SendWithCRC(modbus_slave.tx_buf, modbus_slave.send_len);
    }
    else
    {
        MODBUS_SLAVE_SendAckErr(modbus_slave.RTU_response_code);    /* 告诉主机命令错误 */
    }
}

//写多个线圈
uint8_t MODBUS_SLAVE_BSPSetLed(uint8_t num, uint8_t value)
{
    static uint8_t last, last_flag;

    if (num / 8)
    {
        num = 8;
        last++;
    }
    else
    {
        num %= 8;
        last_flag = 1;
    }

    for (uint16_t i = 0; i < num; i++)
    {
        if (last_flag == 0)
        {
            test_led[i+((last - 1) * 8)] = (value & (0x01 << i)) >> i;
        }

        if (last_flag == 1)
        {
            test_led[i + (last * 8)] = (value & (0x01 << i)) >> i;
        }

    }

    if (last_flag)
    {
        last_flag = 0;
        last = 0;
    }

    return 0;
}

//写多个线圈功能码 0FH
static void MODBUS_SLAVE_0FH(void)
{
    uint16_t reg_num;
    uint8_t byte_num;
    uint8_t i;
    uint16_t value;

    modbus_slave.RTU_response_code = RSP_OK;

    if (modbus_slave.recv_len < 10)
    {
        modbus_slave.RTU_response_code = RSP_ERR_VALUE;         /* 数据值域错误 */
        goto err_ret;
    }

    reg_num = MODBUS_SLAVE_BEBufToUint16(&modbus_slave.rx_buf[4]);      /* 寄存器个数 */
    byte_num = modbus_slave.rx_buf[6];                  /* 后面的数据体字节数 */

    //判断寄存器数量与字节数是否对应
    if (reg_num % 8)//寄存器数量不是整数字节，需要+1之后比较
    {
        if (byte_num != ((reg_num / 8) + 1))
        {
            ;
        }
    }
    else//寄存器数量是整数字节直接进行比较
    {
        if (byte_num != (reg_num / 8))
        {
            ;
        }
    }

    for (i = 0; i < byte_num; i++)
    {
        value = modbus_slave.rx_buf[7 + i];/* 寄存器值 */
        MODBUS_SLAVE_BSPSetLed(reg_num, value);
        reg_num -= 8;
    }

err_ret:

    if (modbus_slave.RTU_response_code == RSP_OK)   /* 正确应答 */
    {
        //此命令码应答报文与请求报文一致
        memcpy(modbus_slave.tx_buf, modbus_slave.rx_buf, 6);//不复制crc位
        modbus_slave.send_len = 6;//不复制crc位
        MODBUS_SLAVE_SendWithCRC(modbus_slave.tx_buf, modbus_slave.send_len);
    }
    else
    {
        MODBUS_SLAVE_SendAckErr(modbus_slave.RTU_response_code);    /* 告诉主机命令错误 */
    }
}

