单片机程序中,Modbus功能码的回调函数如何编写--FreeModbus从站设计(10)

FreeModbus从站设计(10)-Modbus功能码的回调函数如何编写

关键词:FreeModbus CubeMX HAL库 串口 功能码

此系列的前面几篇文章,主要是阐述了用HAL库生成keil工程、如何将FreeModbus的代码加入keil工程、协议栈的初始化、串口和定时器接口函数的修改等内容,并整理了FreeModbus协议栈调与HAL库函数的调用关系,通过以上这些工作,Modbus的通路(串口和定时器)已经通了,下面就是数据的处理部分了。数据处理部分主要是对各个功能码的回调函数的编写。

以常用的读写保持寄存器的功能码(03、06、16)为例,阐述回调函数的编写方法。

1.回调函数的位置

第一个是回调函数被调用的地方,也就是回调函数在FreeModbus协议栈的哪些地方被使用。

保持寄存器的回调函数为:eMBRegHoldingCB()。被调用的位置如图1-图4所示。从几张图片可以看出,调用的位置都在mbfuncholding.c文件中,首先说明,在移植FreeModbus协议栈的时候,mbfuncholding.c文件中的代码是不需要修改的,孔丙火(微信公众号:孔丙火)这里只是为了更清晰地展示函数的调用关系,做一个简单的阐述。调用eMBRegHoldingCB()的地方主要是写单个保持寄存器(对应的功能码06)、写多个保持寄存器(对应的功能码16)、读保持寄存器(对应的功能码03)、读写多个保持寄存器(对应的功能码23),读写多个保持寄存器的地方调用了两次(读和写),在图4中只截取了一个的图片,因此,共有5处调用了eMBRegHoldingCB()。

图1

图2

图3

图4

这里随便说一句,FreeModbus协议栈是严格按照Modbus协议标准来做的,在Modbus协议规范中,对于保持寄存器的定义见图5,跟读、写寄存器相关的几个功能码,在FreeModbus协议栈里面都有定义,这也是使用标准协议栈的好处,相对于自己编写的协议栈,功能全面,不会缺少某些功能。

图5

第二个是回调函数定义的地方。从图6可以看出,eMBRegHoldingCB()函数是字啊mb.h中声明的。至于在何处定义(编写)这个函数?只要是在包含了mb.h的任何一个.c文件中都可以。

图6

2.回调函数编写方法

在孔丙火(微信公众号:孔丙火)的这个例子中,新建了一个modbus_app.c文件,eMBRegHoldingCB()的代码就编写在modbus_app.c中。如图7所示,是eMBRegHoldingCB()函数的总体结构,首先判断需要读或写的寄存器地址是否在定义的范围内,不在范围内的话,返回MB_ENOREG,这样协议栈就会回复相应的错误代码。

图7

如图8所示,在读或写的数据在范围内时,对数据进行操作。在程序内部,保持寄存器的数据时存储在数组usRegHoldingBuf[]中的,大小根据实际情况自行定义。

图8

图8所展示的是一个最基本的读写操作。在实际应用中,也许需要根据保持寄存器中的值做一些操作,后续的操作代码也可以写在这个函数中,这样可以保证第一时间执行。如图9所示,就是一个在收到相应的指令后,进入上电停止状态和修改通信参数的例子,后续会有专门一个章节,对此进行阐述。

图9

按照本文的思路,就可以编写自己的功能码回调函数了。

文章在公众号(孔丙火)同步推出,欢迎查看更多系列文章。

单片机、ARM、现场总线、PLC、嵌入式软硬件的设计经验分享,秉承“点点滴滴皆智慧”的理念,以实际项目为单元阐述知识点,一起分享,共同交流。

单片机程序中,Modbus功能码的回调函数如何编写--FreeModbus从站设计(10)

 

上一篇:嵌入式Linux开发中如何定位崩溃处?


下一篇:java 调用gdal读取gdb数据