我是靠谱客的博主 鲜艳小懒虫,最近开发中收集的这篇文章主要介绍Modbus-RTU报文举例-0x03功能码,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Modbus协议是一种已广泛应用于当今工业控制领域的通用通讯协议,通过此协议,控制器相互之间、或控制器经由网络可以和其它设备之间进行通信。Modbus协议使用的是主从通讯技术,即由主设备主动查询和操作从设备。一般将主控设备方所使用的协议称为Modbus Master,从设备方使用的协议称为Modbus Slave。其通信遵循以下的过程:

● 主设备向从设备发送请求

 ● 从设备分析并处理主设备的请求,然后向主设备发送结果

● 如果出现任何差错,从设备将返回一个异常功能码

Modbus-RTU串行传输的物理层是RS-485或RS-232,Modbus协议的报文(或帧)的基本格式是:表头+功能码+数据区+校验码。使用RTU模式,每一帧消息发送至少要以3.5个字符时间的停顿间隔,在最后一个传输字符之后,一个至少3.5个字符时间的停顿标定了消息的结束。

举例:Modbus 03功能码数据帧解析

主站请求帧:

从站地址

功能码

起始地址

寄存器数量

CRC校验

1字节

1字节

2字节

2字节

2字节

从站响应帧:

从站地址

功能码

读取的字节数

寄存器值

CRC校验

1字节

1字节

1字节

2*N字节

2字节

功能码:0x03 读取一个或多个保持寄存器

①模拟量输出读取(一个)

功能:读取当前AO(寄存器)通道1位模拟量输出值

主站请求:发送数据(HEX)01 03 00 00 00 01 84 0A

解释:01 从站地址

          03 功能码,读取AO

          00 00 起始地址,从AO寄存器第一位开始读

          00 01 要读取的寄存器数量,即读取一个寄存器的值

          84 0A 16位CRC校验

从站响应:接收数据(HEX)01 03 02 10 D2 35 D9

解释:01 从站地址

          03 功能码,读取AO

          02 后面所读取数据的字节数,一个寄存器即2个字节

         10 D2 转换成十进制=4306,即读取到的模拟量的值为4306

         35 D9 16位CRC校验

②模拟量输出读取(多个)

功能:读取当前AO(寄存器)通道4位模拟量输出值

主站请求:发送数据(HEX)01 03 00 00 00 04 44 09

解释:01 从站地址

          03 功能码,读取AO

         00 00 起始地址,从AO寄存器第一位开始读

         00 04 要读取的寄存器数量,即读取4个寄存器的值

        44 09 16位CRC校验

从站响应:接收数据(HEX)01 03 08 10 D2 10 D2 10 D2 10 D2 F5 30

解释:01 从站地址

         03 功能码,读取AO

         08 后面所读取数据的字节数,4个寄存器即8个字节

         10 D2 转换成十进制=4306,即读取到的模拟量的值为4306

         10 D2 转换成十进制=4306,即读取到的模拟量的值为4306

         10 D2 转换成十进制=4306,即读取到的模拟量的值为4306

        10 D2 转换成十进制=4306,即读取到的模拟量的值为4306

        F5 30 16位CRC校验

代码实现如下:

void Modbus03H(uint8_t *pMbBuf,uint8_t u8MbBufLEN)   /*上位机读取指令*/
{
    uint16_t u16Add=0;    /*起始地址*/         
    uint16_t u16Num=0;   /*要读取的寄存器个数 */
    uint16_t u16Cnt=0;    /*数据个数 */
    if(u8MbBufLEN != 8)   /*判断接收数组长度,03功能码8个字节 */
    {
        /*Send ErrCode  发送故障码程序*/;
        return;
    }
    /*要读取寄存器的地址,将收到数组3、4位合并,得到寄存器起始地址*/
    u16Add = pMbBuff[2]<<8 | pMbBuf[3];        
    /*读取字节个数,将收到数组5、6位合并,得到读取的寄存器数量*/
    u16Num = pMbBuf[4]<<8 | pMbBuf[5];         
    MdobusTxCnt=0;     /*要发送的数据个数*/
    ModbusBuf[MdobusTxCnt ++] = pMbBuf[0];    /*发送接收到数组的第1位,即地址码*/
    ModbusBuf[MdobusTxCnt ++] = pMbBuf[1];    /*发送接收到数组的第2位,即功能码*/
    ModbusBuf[MdobusTxCnt ++] = u16Num*2;     /*返回发送数据后面数据的字节个数,一个寄存器有2个字节*/
    for(u16Cnt=0;u16Cnt<u16Num;u16Cnt++)
    {
         /*Send Data 发送相应报文程序*/
    }
        u16Reg++;       /*寄存器地址后移一位*/
        MdobusTxCnt+= 2;            /*发送的数据后移两个字节*/
    }
        CRCSendBuf(ModbusBuf,MdobusTxCnt);  /*CRC计算程序网上有很多例程,发送校验位*/ 
}

最后

以上就是鲜艳小懒虫为你收集整理的Modbus-RTU报文举例-0x03功能码的全部内容,希望文章能够帮你解决Modbus-RTU报文举例-0x03功能码所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部