备注:经过评论区网友批评指正,协议栈没有Bug。这里只是一种临时解决问题的思路,可能带来其他问题,请各位朋友谨慎使用。
在STM32F401中移植了FreeModBus,移植教程参考了这里:http://www.openedv.com/thread-64794-1-1.html。采用03、04和06号功能码进行数据读写,发现数据能读出,但数值不对。单独调试串口证明串口正常。断点调试发现,每次读/写都是操作的本来想操作寄存器的下一个。于是,一步步查看协议栈各函数调用关系。终于发现,协议栈的小bug。
以03号功能码调用的函数eMBException eMBFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen )为例(在mbfuncinput.c中),有如下代码:
if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
{
usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
usRegAddress++;
usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8 );
usRegCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );
可以看到,在获取寄存器地址usRegAddress后,进行了++操作,把这句话屏蔽即可。同理,在其他几个函数eMBFunc…中,进行同样处理。这些Function分布在文件名为mbfunc**.c的文件中,搜索++字符,并确定是寄存器地址后,将该行屏蔽即可。