modbus是一项工业上经常用到的通讯协议,而freemodbus是一款开源的从机协议栈。关于它的移植网上已经有了很多的文章,但是大多都只是针对其中部分问题的表述。本文将会把自己在移植freemodbus过程中遇到的问题以及freemodbus的源码分析尽量表述清楚。
(由于源码分析部分在工作用的电脑上,这部分后续补上)
关于移植:
本次移植使用的片子是stm32f103的片子,编译环境喂keil5.23
freemodbus源码GitHub链接:
cwalter-at/freemodbusgithub.com首先移植需要有大致两方面工作:1、相关硬件功能的编写;2、freemodbus底层操作寄存器(线圈)的函数。
关于硬件功能主要包括usart的初始化,发送/接收状态设置,串口中断函数等;timer定时器的初始化,使能,失能以及定时器中断等。其中需注意的是在串口中断及定时器中断中加入对应的处理函数,通知状态机进行相应处理。
定时器方面基本没有什么问题,确定还要使用的定时器以及编写好对应的函数没什么问题可以正常使用。但是在串口移植的时候需要注意,自己使用的串口发送中断是txe还是tc。使用txe中断需要预先发送一个字节触发串口发送中断,而是用tc中断需要在中断中添加延时否则会导致最后一个字节发送不出去的问题。关于这两个问题的分析及解决方法:
txe中断(本人测试过可以解决,八度大神还是屌啊):
FreeModbus在STM32上移植-OpenEdv-开源电子网www.openedv.comtc中断(该方法本人并没有测试过是否可以解决问题):
STM32F407移植FreeModbus中遇到接收最后一个字节是0xff或0xfe的解决方法_刘恩明的博客-CSDN博客_485通信输出0xff 0xfeblog.csdn.net硬件方面的问题大体如上
关于软件部分:
1、状态机在调用对应功能 的函数时,会在其中寄存器地址的处理后加入一句语句:usAddress++,不知道原作者加这一句是干嘛的。注释掉即可,或者在底层的寄存器处理函数中加入一句对应的usAddress--;所谓负负得正嘛
2、在寄存器操作的部分中,有一个bug位于mbfuncholding.c文件eMBFuncReadHoldingRegister函数中文件第185行的位置,源代码如下:
usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8 ); usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );
应修正为:
usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8 ); usRegCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );
3、关于需要实现的四个底层操作寄存器、线圈的函数需根据需求自行设计。后续在本人完成gd32f330的fremodbus移植后会贴出自己搞的移植后的freemodbus源码。
附录移植完毕的demo(基于GD32F330C8T6)
https://github.com/SlatedFish-QAQ/GD32_FreeModbus