最近在调试armink大佬的FreeModbus时遇到些问题,在论坛中发帖求助,得到armink大佬的支持,并建议写篇文章分析,于是就有了这篇文章。
1. console与modbus的冲突问题
我使用的板子仅有一个串口,平时是用来做rt_kprintf输出的,但ModbusRTU模式也会用到串口,同时配置使用会导致冲突的问题,于是这里需要先屏蔽console(使用的RTT版本为3.0.3)。
首先在bsp/drivers/board.h中进行屏蔽。代码如下:
```//
// Default: 1
void rt_hw_board_init(void);
将STM32_CONSOLE_USART配置为0,可以屏蔽console,但需要注意的是,这样屏蔽并不完全,还需要在rtconfig.h中进行屏蔽。代码如下:
```#define RT_USING_DEVICE
/ RT_USING_INTERRUPT_INFO is not set /
这里的RT_CONSOLE_DEVICE_NAME需要与board.h中 配置一致,如”no/uart1/uart2”等。很多时候我们会配置其中一个地方而忘记另一个地方,导致配置失效,看后续能否把这两处配置移到同一个文件中进行,这样就不会出问题了。
2. 使能modbus对应的串口
这里我们使用的是uart1,需要在rtconfig.h中进行配置以保证系统启动后能初始化串口。代码如下:#define RT_USING_UART1
这能保证系统启动后能调用ld文件中的初始化函数列表中的stm32_hw_usart_init来对我们要使用的串口进行初始化。
3. modbus从机示例代码
自己写了一个简单的从机示例代码,如下:
```#include
static rt_uint8_t thread_ModbusSlavePoll_stack[512];
struct rt_thread thread_ModbusSlavePoll;
/**
void test_modbus (void)
{
rt_thread_init(&thread_ModbusSlavePoll, “MBSlavePoll”,
thread_entry_ModbusSlavePoll, RT_NULL, thread_ModbusSlavePoll_stack,
sizeof(thread_ModbusSlavePoll_stack), thread_ModbusSlavePoll_Prio,
5);
rt_thread_startup(&thread_ModbusSlavePoll);
}```
使用eMBInit来完成初始化配置,协议采用ModbusRTU;0x01表示从机子地址;1表示端口1,即uart1;115200表示从机波特率;MB_PAR_EVEN表示采用偶校验。只需要在主程序中调用test_modbus即可开始从机测试。
4. 采用 modbus poll 软件来测试从机
使用串口连接板子和PC,打开modbus_poll软件配置端口,如图所示:
点击菜单栏Connection,选择好协议、端口、波特率等参数,点击OK开始连接。
连接成功后点击寄存器地址来修稿保持寄存器的值,需要配置从机ID,寄存器地址等参数。
配置完成后能看到对应寄存器值同步更新。
5. 修改modbus从机寄存器值
编写从机的初衷是希望主机能及时查询到从机值的变化,我们可以使用eMBRegHoldingCB接口来改写保持寄存器的值,接口原型如下:eMBErrorCode eMBRegHoldingCB(UCHAR * pucRegBuffer, USHORT usAddress,
USHORT usNRegs, eMBRegisterMode eMode)
需要配置的参数是待写入的数据缓冲区指针、寄存器首地址、写入的寄存器个数以及操作模式(读或写)。
6. 关于modbus的寄存器浮点数问题
单精度浮点数占4个字节32bits,modbus单个寄存器空间为2个字节16bits,可以在连续的两个寄存器中存放单精度浮点数的高段和低段来存储一个单精度浮点数。需要注意的是存储方式需要根据主机对浮点数的读取方式来做应对,如区分是低字优先还是高字优先、先高后低还是先低后高。
这里也给一种浮点数转成字或字节的解决方案,如下:
装载浮点数后可以分解成字节的形式,在根据主机的读取方式来倒装,最后写入寄存器。
that’s all, thank you!
在MODBUS里,方向控制脚怎么设置呢?
我使用的是无流控的,流控脚配置成了一个未使用的脚。
需要在board.h中宏定义好流控脚,如下:
如果你硬件上使用了流控,把流控脚宏定义成你使用的引脚,并在初始化modbus前先初始化对应的GPIO口即可。
slave模式波特率设为9600压根通信不上?
115200 也会隔一会出现一个超时错误。。。
咋回事,你们遇见了么? …
9600可以通讯,大约隔10个包会有一次超时,最近在干其他事,还没研究这个问题。
我用freemodbus的时候提示字节丢失错误
但是我看通讯数据的时候觉得数据没有问题啊!
那个大神能给我指点一 …
回复帧是不是少了两个字节?
之前有网友告诉我把系统时钟由10ms调成1ms会好一点,你可以试试看.