uC/Modbus 用户手册——第五节 uC/Modbus-S

目录

5.00 uC/Modbus-S,访问应用数据

5.01 uC/Modbus-S,MB_CoilRd()

5.02 uC/Modbus-S,MB_CoilWr()

5.03 uC/Modbus-S,MB_DIRd()

5.04 uC/Modbus-S,MB_InRegRd()

5.05 uC/Modbus-S,MB_InRegRdFP()

5.06 uC/Modbus-S,MB_HoldingRegRd()

5.07 uC/Modbus-S,MB_HoldingRegRdFP()

5.08 uC/Modbus-S,MB_HoldingRegWr()

5.09 uC/Modbus-S,MB_HoldingRegWrFP()

5.10 uC/Modbus-S, MB_FileRd()

5.11 uC/Modbus-S,MB_FileWr()


5.00 uC/Modbus-S,访问应用数据

uC/Modbus-S通过mb_data.c中定义的接口函数访问应用数据。具体来说,就是uC/Modbus-S调用该文件提供的函数来读写线圈、整型、浮点值,等等。由您决定如何访问您的数据。可以使用表、函数,switch语句等。在本节中提供了一些示例。这种灵活性允许在读写数据时执行代码。

必须以如下函数书写代码:

MB_CoilRd()

MB_CoilWr()

MB_DIRd()

MB_InRegRd()

MB_InRegRdFP()

MB_HoldingRegRd()

MB_HoldingRegRdFP()

MB_HoldingRegWr()

MB_HoldingRegWrFP()

MB_FileRd()

MB_FileWr()

5.01 uC/Modbus-S,MB_CoilRd()

当Modbus主机发送功能码1时会调用MB_CoilRd()。MB_CoilRd()返回一个线圈的值。MB_CoilRd()只应被uC/Modbus调用。

原型

CPU_BOOLEAN MB_CoilRd (CPU_INT16U  coil, CPU_INT16U *perr)

参数

coil

希望读取的线圈号,数值可以是0-65535(取决于您的产品)。由您决定哪一个线圈分配到您产品的哪一个变量。

perr

指针,指向一个包含错误代码的变量,错误代码取决于调用结果。例如需要返回如下代码:

如果指定的线圈是一个有效的线圈,并可以通过代码访问该线圈的值,返回MODBUS_ERR_NONE。

如果作为参数的线圈号在您的产品中是无效的线圈返回MODBUS_ERR_RANGE。

返回值

MB_CoilRd()返回指定线圈当前的值(TRUE或FALSE)。如果指定的是无效线圈,应当返回FALSE。

注意事项/警告

当产品中mb_cfg.h文件的MODBUS_CFG_FC01_EN设置为DEF_ENABLED时使能代码。

调用方

mbs_core.c中的MBS_FC01_CoilRd()

示例

该示例中,产品拥有163个线圈,其中160个线圈放置在AppCoilTbl[]表中,其他3个线圈实际上是变量,我们将其视为线圈,以允许Modbus主服务器读取这些值的状态。前160个线圈分配的线圈号为0-159。线圈号200,201和202分别对应以下应用变量:AppStatus, AppRunning和AppLED。

CPU_INT08U  AppCoilTbl[20];
CPU_BOOLEAN AppStatus;
CPU_BOOLEAN AppRunning;
CPU_BOOLEAN AppLED;

CPU_BOOLEAN MB_CoilRd (CPU_INT16U coil, CPU_INT16U *perr)
{
    CPU_INT08U ix;
    CPU_INT08U bit_nbr;
   
    *perr = MODBUS_ERR_NONE;
    if (coil < 20 * sizeof(CPU_INT08U)) {
        ix      = coil / 8;
        bit_nbr = coil % 8;
        if (AppCoilTbl[ix] & (1 << bit_nbr)) {
            return (TRUE);
        } else {
            return (FALSE);
        }
        return (val);
    } else {
        switch (coil) {
            case 200:
                return (AppStatus);
            case 201:
                return (AppRunning);
            case 202:
                return (AppLED);
            default:
                *perr = MODBUS_ERR_RANGE;
                return (0);
        }
    }
}

​​​​​​​5.02 uC/Modbus-S,MB_CoilWr()

当Modbus主机发送功能码5和功能码15命令时调用MB_CoilWr()。MB_CoilWr()更改单个线圈的值。MB_CoilWr()只能被uC/Modbus调用。

原型

void MB_CoilWr (CPU_INT16U   coil,

                            CPU_BOOLEAN  coil_val;

                            CPU_INT16U  *perr)

参数

coil

希望更改的线圈号,数值可以是0-65535(取决于您的产品)。由您决定哪一个线圈分配到您产品的哪一个变量。

coil_val

要写入线圈的值,可以是DEF_TRUE或DEF_FALSE。

perr

指针,指向一个包含错误代码的变量,错误代码取决于调用结果。例如需要返回如下代码:

如果指定的线圈是一个有效的线圈,并可以通过代码访问该线圈的值,返回MODBUS_ERR_NONE。

如果作为参数的线圈号在您的产品中是无效的线圈返回MODBUS_ERR_RANGE。

返回值

注意事项/警告

当产品中mb_cfg.h文件的MODBUS_CFG_FC05_EN或MODBUS_CFG_FC15_EN设置为DEF_ENABLED时使能代码。

调用方

mbs_core.c中的MBS_FC05_CoilWr()和MBS_FC15_CoilWrMultiple()。

示例

该示例中,产品拥有163个线圈,其中160个线圈放置在AppCoilTbl[]表中,其他3个线圈实际上是变量,我们将其视为线圈,以允许Modbus主服务器读取这些值的状态。前160个线圈分配的线圈号为0-159。线圈号200,201和202分别对应以下应用变量:AppStatus, AppRunning和AppLED。

CPU_INT08U  AppCoilTbl[20];
CPU_BOOLEAN AppStatus;
CPU_BOOLEAN AppRunning;
CPU_BOOLEAN AppLED;

void MB_CoilWr (CPU_INT16U coil, CPU_BOOLEAN coil_val, CPU_INT16U *perr)
{
    CPU_INT08U ix;
    CPU_INT08U bit_nbr;
    *perr = MODBUS_ERR_NONE;
    if (coil < 20 * sizeof(CPU_INT08U)) {
        ix      = coil / 8;
        bit_nbr = coil % 8;
        CPU_CRITICAL_ENTER();
        if (coil_val == TRUE) {
            AppCoilTbl[ix] |= (1 << bit_nbr);
        } else {
            AppCoilTbl[ix] &= ~(1 << bit_nbr);
        }
        CPU_CRITICAL_EXIT();
    } else {
        switch (coil) {
            case 200:
                AppStatus = coil_val;
                break;
            case 201:
                AppRunning = coil_val;
                break;
            case 202:
                AppLED = coil_val;
                break;
            default:
                *perr = MODBUS_ERR_RANGE;
                break;
        }
    }
}

​​​​​​​5.03 uC/Modbus-S,MB_DIRd()

当Modbus主机发送功能码2命令时调用MB_DIRd()。MB_DIRd()读取一个离散输入的值。MB_DIRd()仅被uC/Modbus调用。

原型

CPU_BOOLEAN MB_DIRd (CPU_INT16U   di,

                                              CPU_INT16U  *perr)

参数

di

希望读取的离散输入号,数值可以是0-65535(取决于您的产品)。由您决定哪一个离散输入分配到您产品的哪一个变量。

perr

指针,指向一个包含错误代码的变量,错误代码取决于调用结果。例如需要返回如下代码:

如果指定的离散输入是一个有效的离散输入,并可以通过代码访问该离散输入的值,返回MODBUS_ERR_NONE。

如果作为参数的离散输入号在您的产品中是无效的,返回MODBUS_ERR_RANGE。

返回值

MB_DIRd()返回指定离散输入的当前值(TRUE或FALSE)。如果指定一个无效的离散输入号,您需要返回FALSE。

注意事项/警告

产品中mb_cfg.h文件里的MODBUS_CFG_FC02_EN设置为DEF_ENABLED时使能代码。

调用方

mbs_core.c中的MBS_FC02_DIRd()

示例

本示例中,产品支持19个离散输入。其中16个离散量位于AppDITbl[]中,其他3个离散输入实际表示三个开关的状态,应用程序在以下三个变量中进行状态读写:AppSwStart, AppSwStop和AppSwReset。按下开关用TRUE表示,释放开关用FALSE表示。

您的系统工程师决定给3个开关分配的离散输入号为100,101和102,其他离散输入为103-118。

CPU_BOOLEAN AppDITbl[16];
CPU_BOOLEAN AppSwStart;
CPU_BOOLEAN AppSwStop;
CPU_BOOLEAN AppSwReset;

CPU_BOOLEAN MB_DIRd (CPU_INT16U di, CPU_INT16U *perr)
{
    *perr = MODBUS_ERR_NONE;
    switch (di) {
        case 100:
            return (AppSwStart);
        case 101:
            return (AppSwStop);
        case 102:
            return (AppSwReset);
        case 103:

        case 104:

        case 105:

        case 106:

        case 107:

        case 108:

        case 109:

        case 110:

        case 111:

        case 112:

        case 113:

        case 114:

        case 115:

        case 116:

        case 117:

        case 118:
            return (AppDITbl[di – 103]);
        default:
            *perr = MODBUS_ERR_RANGE;
            return (FALSE);
    }
}

​​​​​​​5.04 uC/Modbus-S,MB_InRegRd()

当Modbus主机发送功能码4的命令的时候调用MB_InRegRd()。MB_InRegRd()读取一个输入寄存器的值。整型输入寄存器的编号是0-(MODBUS_CFG_FP_START_IX – 1)。可以通过MODBUS_CFG_FP_START_IX指定浮点寄存器的起始地址(参考5.05,MD_InRegRdFP())。MB_InRegRd()仅被uC/Modbus调用。

原型

CPU_INT16U MB_InRegRd (CPU_INT16U  reg,

                                               CPU_INT16U *perr)

参数

reg

希望读取的寄存器,数值可以是0至MODBUS_CFG_FP_START_IX-1(取决于您的产品)。由您决定为输入寄存器分配哪一个应用变量。需要注意,如果产品中没有浮点寄存器,但是有更多的输入寄存器,那么可以将MODBUS_CFG_FP_START_IX设置为65535。

perr

指针,指向一个包含错误代码的变量,错误代码取决于调用结果。例如需要返回如下代码:

如果指定的输入寄存器是有效的,并可以通过代码访问该输入寄存器的值,返回MODBUS_ERR_NONE。

如果作为参数的输入寄存器号在您的产品中是无效的,返回MODBUS_ERR_RANGE。

返回值

MB_InRegRd()以无符号整型返回指定的输入寄存器的值。当然,也可以返回有符号值,需要转换为CPU_INT16U。有符号值转换为CPU_INT16U时值不会变化。Modbus主机将收到正确额值,然后由Modbus主机正确检索有符号数。如果指定无效的输入寄存器地址,应该返回0。

注意事项/警告

当mb_cfg.h文件中的MODBUS_CFG_FC04_EN设置为DEF_ENABLED时使能代码。

调用方

mbs_core.c中的MBS_FC04_InRegRd()

示例

该示例中,产品有4个整型变量分配给输入寄存器。为这4个整型值分配的输入寄存器号为1000,1001,1002和1003。您应该注意到,我们禁用了中断访问变量。这是因为,假设CPU是8-bit CPU,访问16位值是非原子性的。

CPU_INT16S AppTemp;
CPU_INT16U AppCtr;
CPU_INT16S AppPres;
CPU_INT16U AppRxPktCtr;

CPU_INT16U MB_InRegRd (CPU_INT16U reg, CPU_INT16U *perr)
{
CPU_INT16U val;
    *perr = MODBUS_ERR_NONE;
    switch (reg) {
        case 1000:
             CPU_CRITICAL_ENTER();
             val = (CPU_INT16U)AppTemp;
             CPU_CRITICAL_EXIT();
             return (val);
        case 1001:
             CPU_CRITICAL_ENTER();
             val = AppCtr;
             CPU_CRITICAL_EXIT();
             return (val);
        case 1002:
             CPU_CRITICAL_ENTER();
             val = (CPU_INT16U)AppPres;
             CPU_CRITICAL_EXIT();
             return (val);
        case 1003:
             CPU_CRITICAL_ENTER();
             val = AppRxPktCtr;
             CPU_CRITICAL_EXIT();
             return (val);
        default:
             *perr = MODBUS_ERR_RANGE;
             return (0);
    }
}

​​​​​​​5.05 uC/Modbus-S,MB_InRegRdFP()

当Modbus主机发送功能码4的命令时调用MB_InRegRdFP()。MB_InRegRdFP()读取单个输入寄存器的值,但是会假设正在尝试读取一个浮点值。浮点输入寄存器编号为MODBUS_CFG_FP_START_IX到65535(如果浮点寄存器不需要那么多可以少一些)。可以通过MODBUS_CFG_FP_START_IX指定浮点寄存器的起始地址。MB_InRegRdFP()仅被uC/Modbus调用。

原型

CPU_FP32 MB_InRegRdFP (CPU_INT16U reg,

                                               CPU_INT16U *perr)

参数

reg

希望读取的寄存器,数值可以是MODBUS_CFG_FP_START_IX至65535(取决于您的产品)。由您决定为输入寄存器分配哪一个应用变量。需要注意,如果产品中没有浮点寄存器,但是有更多的输入寄存器,那么可以将MODBUS_CFG_FP_START_IX设置为65535。

perr

指针,指向一个包含错误代码的变量,错误代码取决于调用结果。例如需要返回如下代码:

如果指定的输入寄存器是一个有效的输入寄存器,并可以通过代码访问该输入寄存器的值,返回MODBUS_ERR_NONE。

如果作为参数的输入寄存器号在您的产品中是无效的,返回MODBUS_ERR_RANGE。

返回值

MB_InRegRdFP()读取指定的浮点输入寄存器的值,数组格式为32位IEEE-754无符号值。如果指定的输入寄存器无效,应该返回(CPU_FP32)0。

注意事项/警告

当mb_cfg.h文件中的MODBUS_CFG_FC04_EN设置为DEF_ENABLED且MODBUS_CFG_FP_EN设置为DEF_ENABLED时使能代码。

调用方

mbs_core.c中的MBS_FC04_InRegRd()。

示例

该示例中,产品有4个浮点型变量要分配给输入寄存器。为4个浮点值分配的Modbus输入寄存器号为MODBUS_CFG_FP_START_IX+0, MODBUS_CFG_FP_START_IX+1, MODBUS_CFG_FP_START_IX+2和MODBUS_CFG_FP_START_IX+3。您应该注意到,我们禁止中断访问这些变量,因为假设您的CPU不支持对32位浮点值的原子访问。

CPU_FP32 AppTempAir;
CPU_FP32 AppTempFuel;
CPU_FP32 AppPresAir;
CPU_FP32 AppPresFuel;

CPU_FP32 MB_InRegRdFP (CPU_INT16U reg, CPU_INT16U *perr)
{
    CPU_FP32 val;

    *perr = MODBUS_ERR_NONE;
    switch (reg) {
        case MODBUS_CFG_FP_START_IX + 0:
             CPU_CRITICAL_ENTER();
             val = AppTempAir;
             CPU_CRITICAL_EXIT();
             return (val);
        case MODBUS_CFG_FP_START_IX + 1:
             CPU_CRITICAL_ENTER();
             val = AppTempFuel;
             CPU_CRITICAL_EXIT();
             return (val);
        case MODBUS_CFG_FP_START_IX + 2:
             CPU_CRITICAL_ENTER();
             val = AppPresAir;
             CPU_CRITICAL_EXIT();
             return (val);
        case MODBUS_CFG_FP_START_IX + 3:
             CPU_CRITICAL_ENTER();
             val = AppPresFuel;
             CPU_CRITICAL_EXIT();
             return (val);
        default:
             *perr = MODBUS_ERR_RANGE;
             return ((CPU_FP32)0);
    }
}

​​​​​​​5.06 uC/Modbus-S,MB_HoldingRegRd()

当Modbus主机发送功能码3的命令时调用MB_HoldingRegRd()。MB_HoldingRegRd()读取单个保持寄存器的值。整型的保持寄存器编号为0至(MODBUS_CFG_FP_START_IX – 1)。可以通过MODBUS_FP_START_IX指定浮点寄存器的起始地址(参见5.07, MD_HoldingRegRdFP())。MB_HoldingRegRd()仅被uC/Modbus调用。

原型

CPU_INT16U MB_HoldingRegRd (CPU_INT16U reg,

                                                        CPU_INT16U *perr)

参数

reg

希望读取的保持寄存器,数值可以是0至(MODBUS_CFG_FP_START_IX-1)(取决于您的产品)。由您决定为保持寄存器分配哪一个应用变量。需要注意,如果产品中没有浮点寄存器,但是有更多的保持寄存器,那么可以将MODBUS_CFG_FP_START_IX设置为65535。

perr

指针,指向一个包含错误代码的变量,错误代码取决于调用结果。例如需要返回如下代码:

如果指定的保持寄存器是有效的保持寄存器并可以通过代码访问该保持寄存器的值,返回MODBUS_ERR_NONE。

如果作为参数的保持寄存器编号在您的产品中是无效的,返回MODBUS_ERR_RANGE。

返回值

MB_HoldingRegRd()按无符号值返回指定保持寄存器的值。当然,也可以返回有符号值,需要转换为CPU_INT16U。需要注意,将一个有符号值转换为CPU_INT16U,值是不会改变的。如果指定一个无效的保持寄存器,应该返回0。

注意事项/警告

当mb_cfg.h文件中的MODBUS_CFG_FC03_EN设置为DEF_ENABLED时使能代码。

调用方

mbs_core.c中的MBS_FC03_HoldingRegRd()

示例

该示例中,产品有4个整型变量需要分配给保持寄存器。4个变量分配的Modbus保持寄存器号为1000,1001,1002和1003。您应该注意到,我们禁止中断访问变量。这是因为,假设CPU是8-bit CPU,访问16位值是非原子性的。

CPU_INT16S AppTemp;
CPU_INT16U AppCtr;
CPU_INT16S AppPres;
CPU_INT16U AppRxPktCtr;

CPU_INT16U MB_HoldingRegRd (CPU_INT16U reg, CPU_INT16U *perr)
{
    CPU_INT16U val;
    *perr = MODBUS_ERR_NONE;
    switch (reg) {
        case 1000:
             CPU_CRITICAL_ENTER();
             val = (CPU_INT16U)AppTemp;
             CPU_CRITICAL_EXIT();
             return (val);
        case 1001:
             CPU_CRITICAL_ENTER();
             val = AppCtr;
             CPU_CRITICAL_EXIT();
             return (val);
        case 1002:
             CPU_CRITICAL_ENTER();
             val = (CPU_INT16U)AppPres;
             CPU_CRITICAL_EXIT();
             return (val);
        case 1003:
             CPU_CRITICAL_ENTER();
             val = AppRxPktCtr;
             CPU_CRITICAL_EXIT();
             return (val);
        default:
             *perr = MODBUS_ERR_RANGE;
             return (0);
    }
}

​​​​​​​5.07 uC/Modbus-S,MB_HoldingRegRdFP()

当Modbus主机发送功能码3的命令时调用MB_HoldingRegRdFP()。MB_HoldingRegRdFP()读取单个保持寄存器的,但是假设您这在尝试访问浮点变量,浮点型保持寄存器编号为MODBUS_CFG_FP_START_IX至65535(如果不需要这么多浮点寄存器可以少一些)。可以通过MODBUS_FP_START_IX指定浮点寄存器的起始地址。MB_HoldingRegRdFP()仅被uC/Modbus调用。

原型

CPU_FP32 MB_HoldingRegRdFP (CPU_INT16U  reg,

                                                         CPU_INT16U *perr)

参数

reg

希望读取的保持寄存器,数值可以是MODBUS_CFG_FP_START_IX至65535(取决于您的产品)。由您决定为保持寄存器分配哪一个应用变量。需要注意,如果产品中没有浮点寄存器,但是有更多的保持寄存器,那么可以将MODBUS_CFG_FP_START_IX设置为65535。

perr

指针,指向一个包含错误代码的变量,错误代码取决于调用结果。例如需要返回如下代码:

如果指定的保持寄存器是有效的保持寄存器,并可以通过代码访问该保持寄存器的值,返回MODBUS_ERR_NONE。

如果作为参数的保持寄存器编号在您的产品中是无效的,返回MODBUS_ERR_RANGE。

返回值

MB_HoldingRegRdFP()读取指定的浮点保持寄存器的值,数组格式为32位IEEE-754无符号值。如果指定的保持寄存器无效,应该返回(CPU_FP32)0。

注意事项/警告

当mb_cfg.h文件中的MODBUS_CFG_FC03_EN设置为DEF_ENABLED且MODBUS_CFG_FP_EN设置为DEF_ENABLED时使能代码。

保持寄存器和输入寄存器是完全不同的,可以分配给不同的变量。

调用方

mbs_core.c中的MBS_FC03_HoldingRegRd()

示例

该示例中,产品有4个浮点变量需要分配给保持寄存器。4个浮点值的Modbus保持寄存器编号为MODBUS_CFG_FP_START_IX+0, MODBUS_CFG_FP_START_IX+1, MODBUS_CFG_FP_START_IX+2和MODBUS_CFG_FP_START_IX+3。您应该注意到,我们禁止中断访问这些变量,因为假设您的CPU不支持对32位浮点值的原子访问。

CPU_FP32 AppTempAir;
CPU_FP32 AppTempFuel;
CPU_FP32 AppPresAir;
CPU_FP32 AppPresFuel;

CPU_FP32 MB_HoldingRegRdFP (CPU_INT16U reg, CPU_INT16U *err)
{
    CPU_FP32 val;

    *perr = MODBUS_ERR_NONE;
    switch (reg) {
        case MODBUS_CFG_FP_START_IX + 0:
             CPU_CRITICAL_ENTER();
             val = AppTempAir;
             CPU_CRITICAL_EXIT();
             return (val);
        case MODBUS_CFG_FP_START_IX + 1:
             CPU_CRITICAL_ENTER();
             val = AppTempFuel;
             CPU_CRITICAL_EXIT();
             return (val);
        case MODBUS_CFG_FP_START_IX + 2:
             CPU_CRITICAL_ENTER();
             val = AppPresAir;
             CPU_CRITICAL_EXIT();
             return (val);
        case MODBUS_CFG_FP_START_IX + 3:
             CPU_CRITICAL_ENTER();
             val = AppPresFuel;
             CPU_CRITICAL_EXIT();
             return (val);
        default:
             *perr = MODBUS_ERR_RANGE;
             return ((CPU_FP32)0);
    }
}

​​​​​​​5.08 uC/Modbus-S,MB_HoldingRegWr()

当Modbus主机发送功能码6和功能码16的命令时调用MB_HoldingRegWr()。MB_HoldingRegWr()写入一个保持寄存器值。整型的保持寄存器按从0到(MODBUS_CFG_FP_START_IX – 1)进行编号。可以通过MODBUS_CFG_FP_START_IX指定浮点型的起始地址(参见5.09,MD_HoldingRegWrFP())。MB_HoldingRegWr()仅被uC/Modbus调用。

原型

void MB_HoldingRegWr (CPU_INT16U  reg,

                                        CPU_INT16U  reg_val,

                                        CPU_INT16U *perr)

参数

reg

希望写入的保持寄存器,数值可以是0到MODBUS_CFG_FP_START_IX-1(取决于您的产品)。由您决定为保持寄存器分配哪一个应用变量。需要注意,如果产品中没有浮点寄存器,但是有更多的保持寄存器,那么可以将MODBUS_CFG_FP_START_IX设置为65535。

reg_val

指定保持寄存器的期望值,可以是0-65535。需要注意,您的产品中可以使用有符号16位整型值,但是此函数会暂时将其视为无符号值。但是,执行正确的应用,就可以使应用变量拥有正确的符号。

perr

指针,指向一个包含错误代码的变量,错误代码取决于调用结果。例如需要返回如下代码:

如果指定的保持寄存器是有效的保持寄存器并且可以通过代码访问该保持寄存器的值,返回MODBUS_ERR_NONE。

如果作为参数的保持寄存器编号在您的产品中是无效的,返回MODBUS_ERR_RANGE。

返回值

注意事项/警告

当mb_cfg.h文件中MODBUS_CFG_FC06_EN 设置为 DEF_ENABLED 或 MODBUS_CFG_FC16_EN 设置为 DEF_ENABLED时使能代码。

调用方

mbs_core.c 中的MBS_FC06_HoldingRegWr() 与 MBS_FC16_HoldingRegWr()。

示例

该示例中,我们的产品有2个整型值希望分配给保持寄存器。系统工程师将Modbus保持寄存器编号1004和1005分配给两个整型值。您应该注意到,我们禁止中断访问变量。如果您的CPU是8位CPU,16位值的数据访问不是原子性的。

CPU_INT16U AppCtr1;
CPU_INT16U AppCtr2;

void MB_HoldingRegWr (CPU_INT16U reg, CPU_INT16U reg_val, CPU_INT16U *err)
{
    *perr = MODBUS_ERR_NONE;
    switch (reg) {
        case 1004:
             CPU_CRITICAL_ENTER();
             AppCtr1 = reg_val;
             CPU_CRITICAL_EXIT();
             Break;
        case 1005:
             CPU_CRITICAL_ENTER();
             AppCtr = reg_val;
             CPU_CRITICAL_EXIT();
             break;
        default:
             *perr = MODBUS_ERR_RANGE;
             break;
    }
}

​​​​​​​5.09 uC/Modbus-S,MB_HoldingRegWrFP()

当Modbus主机发送功能码6和功能码16的命令时调用MB_HoldingRegWrFP()。MB_HoldingRegWrFP()写入一个浮点型保持寄存器值。浮点型的保持寄存器按从MODBUS_CFG_FP_START_IX至65535进行编号。也就是可以通过MODBUS_CFG_FP_START_IX指定浮点型的起始地址。MB_HoldingRegWrFP()仅被uC/Modbus调用。

原型

void MB_HoldingRegWrFP (CPU_INT16U  reg,

                                             CPU_FP32    reg_val,

                                             CPU_INT16U *perr)

参数

reg

希望写入的保持寄存器,数值可以是MODBUS_CFG_FP_START_IX至65535(取决于您的产品)。由您决定为浮点型保持寄存器分配哪一个应用变量。需要注意,如果产品中没有浮点型保持寄存器,但是有更多的整型保持寄存器,那么可以将MODBUS_CFG_FP_START_IX设置为65535。

reg_val

指定保持寄存器的期望值,可以是IEEE-754浮点值。

perr

指针,指向一个包含错误代码的变量,错误代码取决于调用结果。例如需要返回如下代码:

如果指定的浮点型保持寄存器是有效的并且可以通过代码访问该保持寄存器的值,返回MODBUS_ERR_NONE。

如果作为参数的浮点型保持寄存器编号在您的产品中是无效的,返回MODBUS_ERR_RANGE。

返回值

注意事项/警告

当mb_cfg.h文件中MODBUS_CFG_FC06_EN 设置为 DEF_ENABLED 或 MODBUS_CFG_FC16_EN 设置为 DEF_ENABLED时使能代码。

调用方

mbs_core.c 中的MBS_FC06_HoldingRegWr() 与 MBS_FC16_HoldingRegWr()。

示例

该示例中,我们的产品有2个浮点值希望分配给浮点型保持寄存器。系统工程师将Modbus浮点型保持寄存器编号MODBUS_CFG_FP_START_IX+0和MODBUS_CFG_FP_START_IX+1分配给两个浮点值。您应该注意到,我们禁止中断访问变量。以免您的CPU无法对浮点型数据进行原子访问。

CPU_FP32 AppDiameter;    /* Modbus Holding Register # MODBUS_CFG_FP_START_IX + 0 */
CPU_FP32 AppCircumference;
CPU_FP32 AppTempDegC;    /* Modbus Holding Register # MODBUS_CFG_FP_START_IX + 1 */
CPU_FP32 AppTempDegF;

void MB_HoldingRegWrFP (CPU_INT16U reg, CPU_FP32 reg_val, CPU_INT16U *perr)
{
    CPU_FP32 temp_val;
    *perr = MODBUS_ERR_NONE;
    switch (reg) {
        case MODBUS_CFG_FP_START_IX + 0:
            temp_val = reg_val * (CPU_FP32)3.141592654; /* Compute circumference */
            CPU_CRITICAL_ENTER();
            AppDiameter = reg_val;
            AppCircumference = temp_val;
            CPU_CRITICAL_EXIT();
            Break;
        case MODBUS_CFG_FP_START_IX + 1:
            /* C -> F Conversion */
            temp_val = reg_val * (CPU_FP32)1.8 + (CPU_FP32)32.0; 
            CPU_CRITICAL_ENTER();
            AppTempDegC = reg_val;
            AppTempDegF = temp_val;
            CPU_CRITICAL_EXIT();
            break;
        default:
            *perr = MODBUS_ERR_RANGE;
            break;
    }
}

以上示例中,在值发生变化时进行计算。

​​​​​​​5.10 uC/Modbus-S, MB_FileRd()

当Modbus主机发送功能码20的命令时调用MB_FileRd()。MB_FileRd()从文件读取一个整型值。正如Modbus规范中提到的,文件是一个包含记录的组织。每个文件最多可包含10000条记录(地址从0到9999)。您必须将File/Record/Ix “映射”到实际应用程序的相应数据。MB_FileRd()仅被uC/Modbus调用

原型

CPU_INT16U MB_FileRd (CPU_INT16U  file_nbr,

                                           CPU_INT16U  record_nbr,

                                           CPU_INT16U  ix,

                                           CPU_INT08U  record_len,

                                           CPU_INT16U *perr)

参数

file_nbr

所需文件的数量

record_nbr

文件中的所需记录,0-9999的数字

ix

指定记录中所需的条目

record_len

记录的总长度

perr

指向包含错误代码的变量的指针,错误代码取决于调用结果。代码可能需要返回以下错误代码:

MODBUS_ERR_NONE:指定的file/record/entry有效并且代码正在返回其当前值。

MODBUS_ERR_FILE:指定的file_nbr无效。

MODBUS_ERR_RECORD:指定文件中的record_nbr无效。

MODBUS_ERR_IX:指定record中的ix是无效索引。

返回值

MB_FileRd()将文件中元素的当前值以无符号值形式返回。当然,也可以返回“有符号”值,但这些值需要强制转换为CPU_INT16U。如果将有符号变量强制转换为CPU_INT16U,则该值将不会被更改。Modbus主将接收正确的值,并由Modbus主机正确恢复有符号数。如果检测到错误,您应该返回0。

注意事项/警告

当mb_cfg.h中的MODBUS_CFG_FC20_EN 设置为 DEF_ENABLED时使能代码。

调用方

mbs_core.c 中的MBS_FC20_FileRd()。

示例

该示例中,有2个文件,实现为一个16位整型数组。

#define APP_MAX_FILES          2
#define APP_FILE_MAX_RECORDS  10
#define APP_FILE_MAX_VALUES  100

CPU_INT16U AppFile[APP_MAX_FILES][APP_FILE_MAX_RECORDS][APP_FILE_MAX_VALUES];

CPU_INT16U MB_FileRd (CPU_INT16U file_nbr,
                      CPU_INT16U record_nbr,
                      CPU_INT16U ix,
                      CPU_INT08U record_len,
                      CPU_INT16U *perr)
{
    CPU_INT16U val;
    *perr = MODBUS_ERR_NONE;

   
    if (file_nbr >= APP_MAX_FILES) {
        *perr = MODBUS_ERR_FILE;
        return (0);
    }

   
    if (record_nbr >= APP_FILE_MAX_RECORDS) {
        *perr = MODBUS_ERR_RECORD;
        return (0);
    }
   

    if (ix >= APP_FILE_MAX_VALUES) {
        *perr = MODBUS_ERR_IX;
        return (0);
    }
    CPU_CRITICAL_ENTER();
    val = AppFile[file_nbr][record_nbr][ix];
    CPU_CRITICAL_EXIT();
    return (val);
}

​​​​​​​5.11 uC/Modbus-S,MB_FileWr()

当Modbus主机发送功能码21命令时调用MB_FileWr()。MB_FileWr()向文件中写入一个整型值。正如Modbus规范中提到的,文件是一组记录。每个文件可包含多达10000条记录(地址从0-9999)。您必须将File/Record/Ix映射到实际应用程序的相应数据。MB_FileWr()仅可以被uC/Modbus调用。

原型

void MB_FileWr (CPU_INT16U  file_nbr,

                           CPU_INT16U  record_nbr,

                           CPU_INT16U  ix,

                           CPU_INT08U  record_len,

                           CPU_INT16U  val,

                           CPU_INT16U *perr)

参数

file_nbr

所需文件的数量

record_nbr

文件中的所需记录,0-9999的数字

ix

指定记录中所需的条目

record_len

记录的总长度

val

要写入文件/记录的值

perr

指向包含错误代码的变量的指针,错误代码取决于调用结果。代码可能需要返回以下错误代码:

MODBUS_ERR_NONE:指定的file/record/entry有效并且代码正在返回其当前值。

MODBUS_ERR_FILE:指定的file_nbr无效。

MODBUS_ERR_RECORD:指定文件中的record_nbr无效。

MODBUS_ERR_IX:指定record中的ix是无效索引。

返回值

注意事项/警告

当mb_cfg.h中的MODBUS_FC21_EN 设置为 DEF_ENABLED时使能代码。

调用方

mbs_core.c 中的MBS_FC21_FileWr()

示例

该示例中,有2个文件,以16位整型数组实现。

#define APP_MAX_FILES 2
#define APP_FILE_MAX_RECORDS 10
#define APP_FILE_MAX_VALUES 100

CPU_INT16U AppFile[APP_MAX_FILES][APP_FILE_MAX_RECORDS][APP_FILE_MAX_VALUES];

CPU_INT16U MB_FileWr (CPU_INT16U file_nbr,
                      CPU_INT16U record_nbr,
                      CPU_INT16U ix,
                      CPU_INT08U record_len,
                      CPU_INT16U val,
                      CPU_INT16U *perr)
{
    *perr = MODBUS_ERR_NONE;

    if (file_nbr >= APP_MAX_FILES) {
        *perr = MODBUS_ERR_FILE;
        return;
    }

    if (record_nbr >= APP_FILE_MAX_RECORDS) {
        *perr = MODBUS_ERR_RECORD;
        return;
    }

    if (ix >= APP_FILE_MAX_VALUES) {
        *perr = MODBUS_ERR_IX;
        return;
    }
    CPU_CRITICAL_ENTER();
    AppFile[file_nbr][record_nbr][ix] = val;
    CPU_CRITICAL_EXIT();
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值