modbus源代码_开源一套MODBUS主机代码(带讲解分析)

最近有用到modbus主机部分,网上搜索了一圈,没找到好用的现成的开源代码。之前用过freemodbus,只有从机的源代码是免费的,其他的都需要商业授权。既然这样,那就自己动手,丰衣足食……自己编写个modbus的主机代码,并且开源出来。

modbus就不多介绍了,是工业上常用的通信协议。在物理层, Modbus 串行链路系统可以使用不同的物理接口(RS485、 RS232)。最常用的是RS485 两线制接口。

modbus又是一个主从协议:同一时刻,在总线上只能有一个主机,其他作为从机。并且从机不会主动发数据,都是主机给从机发一条,从机才会回复一条。所以主机的发送和接收也是不同步进行的。如下流程:

主机发送——》等待从机应答——》接收到从机应答——》应答处理——》回到初始状态

以上的主要流程请记好,也是编写modbus主机代码的指导方针。下面再看下modbus是如何区分一帧一帧的数据的(这里只是介绍RTU模式的,ASSCII暂不做讨论)。如下图所示,帧1与帧2之间要至少有3.5个字符的时间,我们把它简称为3.5T。意思也就是在收到数据直到总线上空闲超出了3.5t,就意味着这一帧数据接收完成了。我们就可以把刚才收到的一帧进行CRC计算解析看一帧数据接收是否正确。

86f412c37db835545b92eab3a9b92a5e.png

实际上除了如上规定的帧与帧之间必须间隔3.5T外,在一帧内字符字符之间要小于1.5T。如下图所示:

9893fee4b40d65cc1750463c8437b25d.png

但是在实际运行测试中,这种字符之间超1.5T的情况概率很小,即便出现也能在CRC校验时把错误的帧过滤掉。所以我编写的modbus主机并没有进行字符之间是否超过1.5T的校验。而只做了3.5T的帧区分。

至此基本概念介绍完了,先看下我编写的modbus主机的主要状态流程图:

8d7928e707ad66120a400257b6074615.png

如上图所示,对应代码中定义的如下状态,状态的切换也是modbus主机的主要核心机制:

typedef enum { MBH_STATE_IDLE=0X00, MBH_STATE_TX, MBH_STATE_TX_END, MBH_STATE_RX, MBH_STATE_RX_CHECK, MBH_STATE_EXEC, MBH_STATE_REC_ERR, //接收错误状态 MBH_STATE_TIMES_ERR, //传输 }mb_host_state;

这篇文章主要针对代码的核心思想进行分析,处理细节在这里不做陈述,请自己参考源码,下面就针对核心的一个个状态进行讨论:

MODBUS主机空闲状态(MBH_STATE_IDLE)

这个很好理解,在一上电后就会进入到空闲状态。当对接收数据处理完或者读写从机错误次数达到最大值得时候也会回到这个初始状态。只有状态处于IDLE时才能发起新的一轮对从机的读写。

MODBUS主机发送状态(MBH_STATE_TX)

从状态切换图可以看得出来,当主机需要对从机进行读写的时候就会首先进入TX状态,该状态下回打开串口TX中断,然后通过发送中断把一帧数据发送完成。

MODBUS发送完成(MBH_STATE_TX_END)

当一帧数据发送完成时就会进入到TX_END状态。这时候主机发给从机的命令已经完成了,就等待从机的应答了。打开串口接收中断切换到下一个状态去

MODBUS发送完成(MBH_STATE_RX)

进入到RX状态下,会完成对从机回应的一帧数据的接收,都是在串口接收中断中处理。如果3.5T超时了就证明接收一帧完成,切换到下一个状态进行校验处理

MODBUS发送完成(MBH_STATE_RX_CHECK)

在rx check状态下主要完成对接收一帧数据的合法性和CRC进行计算,看接收是否正确。如果接收正确了,就进入到回调处理。如果校验错误就进入到接收错误状态。

MODBUS回调处理(MBH_STATE_EXEC)

不管是对主机的读还是写,从机都会回复。在该状态下根据从机回复的不同功能码就会执行不同的回调函数。执行完回调再次回到初始的IDLE状态,这样主机对从机的一次读或者一次写就完成了。

MODBUS接收错误(MBH_STATE_REC_ERR)

当接收校验错误的时候就会进入到该状态,在该状态下会对错误的次数进行计数。如果连续错误次数超过了最大值,就进入到超过错误次数状态。如果还没达到最大错误次数,就重新回到tx状态,重头再执行一遍对从机的读写动作。

MODBUS超错误次数(MBH_STATE_REC_ERR)

经过几次对从机的读写操作都失败以后就进入到该状态,在该状态下执行超错误次数回调,之后回到最初的IDLE状态等待下一次的读写操作。

最后是对源码文件目录进行一个大概的说明,整个modbus主机代码如下构成:

ba09997fdfc58e7b2f21fea6f5d1df17.png
  • mb_crc.c/h 这个没啥解释的,主要放CRC计算部分的代码
  • mb_hook.c/h 该文件中存放回调函数接口,所有用户的回调处理都在这里添加。这个需要用户自己添加
  • mb_port.c/h 这个也是需要用户自己修改的文件,针对使用的不同的MCU平台进行移植,主要移植工作就是串口初始化、串口tx、rx中断开启,定时器初始化、定时器开始停止接口
  • mb_host.c/h 核心处理部分代码,不建议用户修改,上面所述的状态机切换处理全部在该文件中完成。用户层最终调用的API接口也在该文件中定义。如下:
 void mbh_init(uint32_t baud,uint8_t parity); int8_t mbh_send(uint8_t add,uint8_t cmd,uint8_t *data,uint8_t data_len); void mbh_poll(void);  void mbh_timer3T5Isr(void);  void mbh_uartRxIsr(void);  void mbh_uartTxIsr(void); 

最后就是源码地址:https://github.com/Derrick45/modbus-host

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要下载单片机Modbus源代码,首先需要了解你使用的单片机型号和开发环境。然后,通过以下步骤可以下载源代码: 1. 在互联网上搜索单片机Modbus源代码。可以使用搜索引擎输入关键词,如“单片机+Modbus+源代码”,然后浏览搜索结果。 2. 查找可靠和适合你单片机型号的源代码。建议选择来自可信赖的网站、官方网站、开源社区或知名开发者分享的源代码。 3. 确认源代码是适用于你所使用的单片机型号和开发环境。不同的单片机型号可能有不同的指令集和外设接口,因此源代码必须相匹配。 4. 点击下载链接或复制源代码,并保存到本地计算机。通常,源代码会以压缩文件(如.zip或.tar.gz)的形式提供,你需要解压缩文件。 5. 使用单片机开发工具打开源代码。根据开发环境的要求,导入、打开或创建新项目,然后将源代码添加到项目中。 6. 根据源代码中的说明,配置并编译项目。通常,源代码文件中会包含使用说明或文档,以帮助你进行初始化、配置和编译。 7. 调试和验证源代码。根据你的需求和目标,进行调试、测试和修改代码,以确保它适用于你的应用场景。 请注意,单片机Modbus源代码通常会提供一系列功能,用于实现Modbus通信协议的客户端或服务器。下载源代码后,你可能需要根据自己的需求和硬件设置进行适当的修改和配置。此外,如果你在下载和使用源代码过程中遇到问题,应该查阅相关的文档、资料或寻求帮助,确保正确运行和使用源代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值