电子产业一站式赋能平台

PCB联盟网

搜索
查看: 59|回复: 0
收起左侧

freeModbus移植后,控制点位错位

[复制链接]
匿名  发表于 2024-12-9 18:14:00 |阅读模式
本位基于modbus_RTU模式在modbus协议标准文件“GBT 19582.1-2008 基于Modbus协议的工业自动化网络规范  第1部分:Modbus应用协议”中描述了有关地址部分。为了兼容人类世界和计算机世界的区别做了说明:

明确表示人类世界的1号位,对应机器世界中的0号地址。文件下面还进行了举例说明

接下来实际使用中考察一下你对这个理解够不够深刻1,我们以05号指令来举例

首先在应答函数指针数组中定义了写单个线圈的函数,接收到对应指令时,自动调用对应的函数,我们具体来看下这个写单个线圈函数。

实现函数定义在mbfunccoils.c文件中,函数我做了备注其中上位机发来的地址经过这个函数做了+1处理,对应上了我们人类世界的编号规则。然后调用eMBRegCoilsCB()函数,写入对应的缓冲区加下来看看eMBRegCoilsCB()函数

根据提示,这个函数需要我们自己来实现。到这个函数传入的编码就是从1开始的编码了。而这个函数在demo中没有实现。如果你很走运从网上找到一个下面这样的实现:

这个函数的功能我做了相应的备注。其他我不多做介绍,重点看下和地址有关的部分。这个实现就使用了官方备注里的xMBUtilSetBits()函数,这个函数就是把一个字节的数据转化成一位数据,写入缓冲区。我们来看下这个函数

这个函数的说明很明显,传入的参数偏移地址从0开始下面总结一下调用关系:eMBFuncWriteCoil()->eMBFuncWriteCoil()->xMBUtilSetBits()。还记得一开始eMBFuncWriteCoil()函数中freeModbus已经对这个地址进行了+1。而xMBUtilSetBits()又需要从0偏移地址开始。这就需要在eMBRegCoilsCB()这个我们自实现的函数中对这个地址进行-1,即REG_COILS_START不能从0开始,应该从1开始。然后再调用xMBUtilSetBits()函数。如果这里没有-1,会导致缓存区数据和实际要控制的位发生移位。本来是要控制1号位的,变成了控制2号位。高级语音的世界里采用各种规则方便程序的打包和移植,而在低级语音里,想移植一套系统真不是那么容易的事,有时候不得不深入研究源码。个人总结:freeModbus也是为了遵循协议,对机器地址进行了+1转换成了正常人类(非程序员)习惯的编码规则。而如果不需要人机交互,在纯代码的世界里,这个+1显得十分的没有必要,一不小心就带了一个比较隐蔽的bug。仅此抛砖引玉。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表