嵌入式开发之Modbus-RTU协议解析

背景

        在工作中,经常要对接各种传感器,总线接口的,模拟量的,各种各样都有。当前主流一些的还是基于Modbus-RTU实现的对接协议,使用RS485总线进行交互。最近接触业务多了经常会有前端发过来需求,都是问客户Modbus协议支持不支持,问能不能做,原则上资源匹配了原子弹也可以搞,每个角色不是传话筒,即使是传话也不能单向传输,没有场景的问题都是扯淡。我的脾气还是比较火爆的,平时工作事情也多,遇到这样问题我基本都不太想回答。在这里对这个情况做个简单的说明,首先Modbus协议呢,大致上是分为两类,一类是Modbus-TCP,一类是Modbus-RTU。大部分传感器都是基于Modbus-RTU规约实现的,这个是软件层面的。交互的介质是什么,最初项目紧急时我们还通过4G实现Modbus-RTU协议,当然了这是个权宜之计,还可以通过RS232总线实现,大部分都是基于RS485总线实现。比如客户只问能不能对接Modbus规约的传感器,这个问题没有场景,没有条件的限定,比如我说可以做,但是我们设备只支持RS485总线,客户的传感器要走RS232总线,这种情况下就得外挂RS485转RS232总线的转换器才能搞,大概率是不同意现场这么玩的。硬件的交互途径一定是要匹配的,这个是基础,然后就是规约是不是Modbus-RTU的,我们设备当前支持Modbus-RTU,如果要是Modbus-TCP的,那我们就要改代码来实现,这个就要有工作量,谁来承担这部分成本,如果客户可以接收定制,那没问题。我们可以开发出来满足百分之八十场景的应用程序,但不可能开发出来百分之百满足客户应用场景的产品。

        这里重点要说的是基于RS485总线的Modbus-RTU协议,当前传感器场景有很多,定义的规约五花八门,Modbus协议是一个国际通用的标准,只是限定了规约的格式和交互的一些方式,但没有限定寄存器的定义,厂家根据自家传感器的特性来定义这一部分,如果都按照标准来,这个问题也不是很大,这里还有个问题,就是这些开发传感器的厂家的开发人员是否理解什么是大端,什么是小端?这个大小端是由什么决定的?在编码实现时,怎么考虑大小端的问题?有关大小端的定义不在这里讨论了,有兴趣可以去看看那个吃鸡蛋的问题,据说还引发了战争。Modbus规约里的内容是以大端的方式实现的,现有的arm处理器基本都是默认的小端模式

        背景讲的有点多,该写点实在的。

需求

  • 基于RS485总线,实现Modbus-RTU传感器对接;
  • 串口的通讯参数可以根据传感器配置自行修改,参数包括波特率,校验位等;
  • 支持配置Modbus-RTU的从机地址;
  • 支持传感器库,从库中添加传感器到采集列表中;
  • 支持不改动代码的情况,手动添加传感器;

技术难点

        基于串口来实现串口参数的配置,这个问题不大,我们设备中的驱动程序跟应用层代码是分离的,底层在做驱动时不考虑应用层怎么用,只管将底层的功能全部提供接口给应用层,基于这个我们串口对应用提供的初始化函数中有串口波特率,串口校验方式的配置,配置后调用初始化函数即可实现配置,在应用时也可以根据不同的需求多次调用不同的配置来实现不同的参数的串口。

        传感器库是我们在设备中集成了一个数据库,这个库里是一个积累的工作,将我们产品对接验证过的传感器,添加到库里,客户如果需要已经适配过的传感器,通过配置手段将库中的传感器调出来使用即可。

        最难的一点就是通过配置参数来实现不同传感器的添加,基于Modbus-RTU的传感器,从实现上来讲先看一下下面截图,关于Modbus协议的定义:

        对于Modbus协议TCP和RTU的区别在于地址域和差错校验,这部分区别我们暂时不管,我们就说基于Modbus-RTU怎么实现无代码适配不同的传感器。不同厂家的传感器区别在于功能码和数据。功能码的种类有限,这个实现可以配置即可,在添加传感器时提供一个功能码选项,来实现不同功能码的选择。传感器数据大部分是在保持寄存器和输入寄存器中,一般都是读取传感器数据,读取的话读取多个寄存器,读保持寄存器的功能码为0x03,读取时的PDU格式定义如下图:

读取输入寄存器的功能码为0x04,读取时的PDU格式定义如下图:

        实现手动添加不同厂家传感器的关键是两部分内容,上面第一项就是功能码可配置,有些厂家把内容放到了保持寄存器有些厂家则放到了输入寄存器,要跟厂家的实现来做配置。第二项比较难,就是寄存器的基址和寄存器数据的格式,基址一般是一个两字节的数,地址从0x0000到0xFFFF,这个数据格式必须是大端模式,也就是发送数据时高位字节在前,地位字节在后。寄存器内部数据格式的处理是比较麻烦的,不是所有传感器厂家都能理解Modbus协议到底是个啥,按照逻辑内部的数据都是按照大端模式定义,数据一般就分为几类,无符号短整型(2个字节),有符号短整型(2个字节),无符号长整型(4个字节),有符号长整型(4个字节),单精度浮点型(4个字节),双精度浮点型(8个字节),字符型(每个字符占一个字节,总空间根据长度来确定),2个字节长度的按照规约,一个寄存器就可以,按照大端模式就可以处理了。超过两个字节的是否还按照大端模式处理呢?这是一个问题,大部分厂家都按照自己的想法实现了,严格来讲不管是寄存器内部的数据还是多个寄存器的数据都应该按照大端来实现。针对不按照逻辑来搞的怎么处理呢?我们不可能要求传感器厂家按照国际标准来重新编码实现,向内看齐,多从自身找问题的解决方法,可能是这个世界解决争端的一个大智慧。根据以往项目经验的统计,加上个人人工智能的分析处理,总结出来以下数据类型,看下图:

        只要厂家的传感器没跳出来这个统计的范畴,都可以通过配置参数来实现传感器数据的采集。

        我们产品中都集成了这个处理逻辑,具体产品信息看下面链接,低功耗RTU低成本物联网采集终端

    在嵌入式开发中,串行数据的接收,解析和发送是使用最多的。如果能够掌握好生产关系,然后再根据生产关系建立自己的代码处理流程将能够应对大部分嵌入式开发过程中的问题。这个Modbus协议解析处理的流程就可以根据生产关系中讲的逻辑来实现,后面抽时间可以单独写一篇。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值