zoukankan      html  css  js  c++  java
  • Modbus库开发笔记之七:Modbus其他辅助功能开发

    前面开发了各种应用,但是却一直没有提到一个问题,你就是对具体的数据进行读写操作。对于Modbus来说标准的数据有4种:线圈数据(地址:0000x)、输入状态量数据(地址:1000x)、保持寄存器数据(地址:4000x)和输入寄存器数据(地址:3000x)。我们通讯的目的就是为了对这些数据进行操作,可是我们前面的封装中并没有提到数据处理。事实上,也没办法考虑这一点,因为具体的应用数据千差万别,是没办法封装的。那我们怎么解决这一问题呢?接下来我们将解决这一类问题。

    1、数据处理函数的封装

    我们考虑到,不论是在RTU主站、RTU从站、TCP客户端、还是在TCP服务器对数据的处理本质上是一样的,只要具体应用的数据结构确定后处理方法也就确定了。鉴于此,我们采用的方法是定义弱化类型的函数。如下:

    /*获取想要读取的Coil量的值*/

    __weak void GetCoilStatus(uint16_t startAddress,uint16_t quantity,bool *statusList)

    {

      //如果需要Modbus TCP Server/RTU Slave应用中实现具体内容

    }

    /*获取想要读取的InputStatus量的值*/

    __weak void GetInputStatus(uint16_t startAddress,uint16_t quantity,bool *statusValue)

    {

      //如果需要Modbus TCP Server/RTU Slave应用中实现具体内容

    }

    /*获取想要读取的保持寄存器的值*/

    __weak void GetHoldingRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)

    {

      //如果需要Modbus TCP Server/RTU Slave应用中实现具体内容

    }

    /*获取想要读取的输入寄存器的值*/

    __weak void GetInputRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)

    {

      //如果需要Modbus TCP Server/RTU Slave应用中实现具体内容

    }

    /*设置单个线圈的值*/

    __weak void SetSingleCoil(uint16_t coilAddress,bool coilValue)

    {

      //如果需要Modbus TCP Server/RTU Slave应用中实现具体内容

    }

    /*设置单个寄存器的值*/

    __weak void SetSingleRegister(uint16_t registerAddress,uint16_t registerValue)

    {

      //如果需要Modbus TCP Server/RTU Slave应用中实现具体内容

    }

    /*设置多个线圈的值*/

    __weak void SetMultipleCoil(uint16_t startAddress,uint16_t quantity,bool *statusValue)

    {

      //如果需要Modbus TCP Server/RTU Slave应用中实现具体内容

    }

    /*设置多个寄存器的值*/

    __weak void SetMultipleRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)

    {

      //如果需要Modbus TCP Server/RTU Slave应用中实现具体内容

    }

    /*更新读回来的线圈状态*/

    __weak void UpdateCoilStatus(uint16_t startAddress,uint16_t quantity,bool *stateValue)

    {

      //在客户端(主站)应用中实现

    }

    /*更新读回来的输入状态值*/

    __weak void UpdateInputStatus(uint16_t startAddress,uint16_t quantity,bool *stateValue)

    {

      //在客户端(主站)应用中实现

    }

    /*更新读回来的线圈状态*/

    __weak void UpdateHoldingRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)

    {

      //在客户端(主站)应用中实现

    }

    /*更新读回来的线圈状态*/

    __weak void UpdateInputResgister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)

    {

      //在客户端(主站)应用中实现

    }

    在开发具体应用时,我们只需要在应用中实现对应的函数就可以使功能完整,至于具体的数据如何处理,就要看具体应用中的数据格式了。当然这些函数并非都需要实现,只需要根据自己的需要实现就可以了。

    2、关于大小端的问题

    提到数据通讯,有一个问题是没有办法回避的,那就是大小端的问题。对于Modbus协议来说,采用的是大端模式,就是低位地址存高位字节数据,高位地址存低位字节数据。

    在进行多字节数据通讯时,大小端的问题就明显了,比如一个浮点数在不同的系统中存储的顺序是有差别的,你读上来或者写下去的数据就会出现错误的解析。所以我们在处理数据报文时是必须考虑这一点的。

  • 相关阅读:
    多校省选模拟33 C
    省选测试47 T2宝石(P5401 [CTS2019]珍珠) 题解
    省选测试39
    省选测试38
    省选测试37
    自嗨测试赛4
    自嗨测试赛3
    自嗨测试赛2
    自嗨测试赛1
    树状数组 学习笔记
  • 原文地址:https://www.cnblogs.com/foxclever/p/7354201.html
Copyright © 2011-2022 走看看