Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
libmodbus
RT-Thread
RT-Thread 应用笔记 - libmodbus RTU RS485 从机
发布于 2020-12-06 23:13:45 浏览:4935
订阅该版
[tocm] [RT-Thread 入门学习笔记 - 目录](https://club.rt-thread.org/ask/article/3420.html) [RT-Thread 应用笔记 - 不正确使用LOG也会引发hard fault](https://club.rt-thread.org/ask/article/2329.html) [RT-Thread 应用笔记 - RTC Alarm 组件的使用](https://club.rt-thread.org/ask/article/2312.html) [RT-Thread 应用笔记 - freemodbus RTU RS485 从机](https://club.rt-thread.org/ask/article/2346.html) [RT-Thread 应用笔记 - freemodbus RTU RS485 主机](https://club.rt-thread.org/ask/article/2353.html) [RT-Thread 应用笔记 - libmodbus RTU RS485 从机](https://club.rt-thread.org/ask/article/2378.html) [RT-Thread 应用笔记 - libmodbus RTU RS485 主机](https://club.rt-thread.org/ask/article/2382.html) [RT-Thread 应用笔记 - STM32 CAN 通信双机](https://club.rt-thread.org/ask/article/2385.html) [RT-Thread USB学习实践系列](https://club.rt-thread.org/ask/article/2396.html) ## 背景 * modbus协议,简单,实用,一些小数据通信控制场合,用的比较多。 * 部分用户使用起来,并不是想象中那么的顺利。 * libmodbus,可用于modbus主从机的开发。 * libmodbus代码基于C库,有动态内存的使用,与freemodbus相比,在适配时稍有不同。 * 基于rt-thread,已经有libmodbus的软件包,默认是主机。 * 这里基于STM32F103 实现modbus RS485 RTU从机的功能。 * 部分使用libmodbus的用户,配置好libmodbus,发现无法通信,就开始【求助】,可能需要了解引脚配置! ## 前言 * 嵌入式软件工程师,需要了解原理图,了解引脚定义,如串口、RS485控制引脚等等。 * 我的板子,MCU 为STM32F103C8T6, Flash与SRAM都相对不大。 * UART1用于rt-thread MSH串口。 * UART3用于RS485,用于modbus rtu串口。 ## 移植 * 首先需要配置好rt-thread最小系统,在rt-thread源码工程里,找一个与使用MCU平台相似的BSP,修改使用。 * 下载配置libmodbus软件包,使用ENV menuconfig ![2020-12-02_221952.png](/uploads/20201206/ba9b41665a09da6371da706ed8e0af05.png) ![2020-12-02_222024.png](/uploads/20201206/5f478d61738fd9ebd7afaa687ef42560.png) * 配置完成后,需要ENV pkg --update,更新下载libmodbus。 * ENV scons --target=mdk5生成Keil MDK5的工程。 * 编译,STM32F103C8T6,发现Flash不够了,需要更改编译选项: -O2. ![2020-12-02_222742.png](/uploads/20201206/c7e5db7c62c51be9635673f7e0d3eb74.png) * 需要更改libmodbus的demo,默认为主机,这里,我简单修改了一下,实现从机功能 ```c #include
#include
#include "modbus.h" #define RS485_RE GET_PIN(A, 8) //RS485控制引脚 static void mb_slave_thread(void *param) { modbus_t *ctx = RT_NULL; int rc = 0; modbus_mapping_t *mb_mapping = NULL; /* 线圈与寄存器 */ uint8_t mb_reply[MODBUS_TCP_MAX_ADU_LENGTH]; ctx = modbus_new_rtu("/dev/uart3", 115200, 'N', 8, 1); /* uart3 */ modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485); modbus_rtu_set_rts(ctx, RS485_RE, MODBUS_RTU_RTS_UP); modbus_set_slave(ctx, 3); /* 设置从机地址 */ mb_mapping = modbus_mapping_new(16, 16, 10, 10); if (mb_mapping == RT_NULL) { rt_kprintf("modbus_mapping_new failed! \n"); modbus_free(ctx); return; } mb_mapping->tab_registers[0] = 'R'; mb_mapping->tab_registers[1] = 'T'; mb_mapping->tab_registers[2] = '-'; mb_mapping->tab_registers[3] = 'T'; mb_mapping->tab_registers[4] = 'h'; mb_mapping->tab_registers[5] = 'r'; mb_mapping->tab_registers[6] = 'e'; mb_mapping->tab_registers[7] = 'a'; mb_mapping->tab_registers[8] = 'd'; modbus_connect(ctx); while (1) { //modbus loop rc = modbus_receive(ctx, mb_reply); if (rc > 0) { modbus_reply(ctx, mb_reply, rc, mb_mapping); } else if (rc == -1) { /* Connection closed by the client or error */ break; } } modbus_close(ctx); modbus_free(ctx); } static int rtu_test_init(void) { rt_pin_mode(RS485_RE, PIN_MODE_OUTPUT); rt_thread_t tid; tid = rt_thread_create("mb_test", mb_slave_thread, RT_NULL, 2048, 12, 10); if (tid != RT_NULL) rt_thread_startup(tid); return RT_EOK; } INIT_APP_EXPORT(rtu_test_init); ``` * 注意RS485 引脚的配置:串口引脚,这里是uart3,RS485控制引脚,这里是PA8。 * uart3的串口引脚配置,rt-thread使用uart3设备,并没有UART3具体引脚的配置。需要手动更改xxx_msp.c文件! 这里修改:stm32f1xx_hal_msp.c ```c void HAL_UART_MspInit(UART_HandleTypeDef* huart) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(huart->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ } else if (huart->Instance==USART3) { __HAL_RCC_USART3_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /**USART3 GPIO Configuration PB10 ------> USART3_TX PB11 ------> USART3_RX */ GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } } ``` * 如果串口不通,首先确认下串口引脚配置,RS485的控制引脚 * libmodbus,默认打开了dfs,所以,ROM空间占用较大,使用动态内存,使用 stdlib string等C库。 * 可以打开Keil MDK的微库 Use microLib支持。 ![2020-12-02_234759.png](/uploads/20201206/6c6b852f8a85004b62029f9af2134048.png) ## 调试 * 因为配置的为从机,需要RS485主机进行调试 * 这里使用USB转RS485,接入电脑,打开modbus poll,开启主机功能。 * 从机配置的是保持寄存器的读取 ![2020-12-02_235843.png](/uploads/20201206/9084a13b5bc6f60260bfcdc3f54fac4a.png) * 通信成功的样子。 ## 总结 * 参考demo ```c https://gitee.com/zhangsz0516/rtt_stm32_libmodbus ``` * 如果调试不通,需要检查引脚配置、波特率设置、modbus主机设置,可以使用逻辑分析仪,查看串口的数据。 * libmodbus,主机功能挺全面,可以用于modbus 主从一体协议的实现, * libmodbus,好像没有从机地址的判断过滤接口,需要实现时,自己注意,否则,收到主机的命令,从机都会响应。 * 总线上有多个从机时,每个从机接收数据包后,判断是自己的从机地址,才能响应。
13
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
张世争
学以致用
文章
131
回答
813
被采纳
177
关注TA
发私信
相关文章
1
RT-THREAD在STM32H747平台上移植lwip
2
正点原子miniSTM32开发板读写sdcard
3
反馈rtt串口驱动对低功耗串口lpuart1不兼容的问题
4
Keil MDK 移植 RT-Thread Nano
5
RT1061/1052 带 RTT + LWIP和LPSPI,有什么坑要注意吗?
6
RT thread HID 如何收发数据
7
求一份基于RTT系统封装好的STM32F1系列的FLASH操作程序
8
RT-Thread修改项目名称之后不能下载
9
rt-studio编译c++
10
有木有移植rt-thread(nano)到riscv 32位MCU上
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
813
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部