简介 FreeModbus 是一款开源的 Modbus 协议栈,但是只有从机开源,主机源码是需要收费的。同时网上也没有比较好的开源的 Modbus 主机协议栈,在这样的背景下,armink 大神开发了这款支持主机模式的 FreeModbus 协议栈。 本文的分为2篇推送,分别介绍如何在潘多拉开发板上运行 Modbus 主机与从机。首先介绍串口方式通信的 Modbus 主机和从机。然后介绍如何使用网络进行 Modbus 通信。 准备工作1、首先演示使用串口作为 Modbus 通信通道的方式,将潘多拉开发板的 uart2 通过 usb 转串口线连接到电脑上 2、使用 usb 线连接开发板的 st-link 接口到电脑上,打开电源开发,开发板上电。 3、查看设备管理器,可以看到两个串口设备,一个用来 shell 通信,一个用来 Modbus 通信。 5 C5 H/ r4 d P" v/ h t" s9 l* j3 i
运行 Modbus 主机配置工程在 RT-Thread 源码目录下找到潘多拉的bsp rt-thread\bsp\stm32\stm32l475-atk-pandora ,在此目录下打开 ENV 工具。 配置 FreeModbus 软件包1、输入 menuconfig 命令打开配置工具 2.按照下面的路径进入 FreeModbus 软件包的配置菜单,并开启主机模式 - RT-Thread online packages --->2 ]2 q' S9 o# W
- IoT - internet of things --->
+ C/ y5 m% \- _/ O* v1 J - [*] FreeModbus: Modbus master and slave stack --->$ l) @ p) X8 K' G$ z2 }# m: J
- [*] Master mode --->
k* T, m3 y( j2 A' U5 c, J7 x - [ ] Slave mode ----) B, b! B/ q" g" R( W, i
- Version (latest) --->
复制代码3.配置主机模式选项 进入 Mastar mode 配置菜单,然后开启主机示例程序,如下图所示: advanced configuration:高级配置选项 Enable RTU master mode:开启 RTU 模式支持(主机暂只支持 RTU 模式) Enable master sample:开启主机示例程序 Test slave device address:测试用的从机设备地址 uart number used by master sample, e.g. 2 means uart2:表示使用串口几进行通信,默认使用 uart2 uart baudrate used by master sample:通信用的波特率 " W; u4 p8 R7 J
; O8 b$ l* _0 V8 I1 m7 [7 F4 h6 k8 q n# w% s+ P0 |6 L5 r$ H3 O
配置硬件 uart2
( z& f3 ]; b" E然后返回到主菜单,进入硬件配置的菜单里开启 uart2 。 - Hardware Drivers Config --->! \' |8 Y" G6 j8 n! A" ?' x( m
- On-chip Peripheral Drivers --->
9 k9 j: |7 o1 ^) b2 r - -*- Enable UART --->, v2 a% W) k, U+ T6 ]& E U
- [*] Enable UART2
复制代码 ( a- \6 y: |5 ], H) Q/ M% r3 [0 f
退出 menuconfig 配置工具并保存。然后 pkgs --update 下载软件包,然后 scons --target=mdk5 生成工程。
" @3 Q) r5 ~6 B: R3 B7 B. \- ^) @3 u% V) ^) S. L
, F2 b. f3 W& q( g( |7 V$ b% ?
运行示例程序打开工程,在 FreeModbus 分组里可以看到主机的示例代码 sample_mb_master.c 关键代码如下所示:
0 e% Q/ v/ q1 D& i# F# ^. [8 l- #define MB_POLL_CYCLE_MS 5004 B" E$ S9 ?- q0 G+ E) l: N
- 8 @, p2 o B( p) \+ N9 ? u
- static void send_thread_entry(void *parameter)
0 Y6 y$ ?1 e1 N# g) H - {; J5 I8 H" w6 M& f7 y4 P9 x
- eMBMasterReqErrCode error_code = MB_MRE_NO_ERR;
7 k" o' u) Q! R0 L5 ?+ \ - rt_uint16_t error_count = 0;& p: W y8 a- S! G4 T# V/ ^, S
- USHORT data[2] = {0};
2 H$ r* B$ y; ^) P# Z$ F - 0 \% A" R! M$ u1 J# h2 ~: }* h X
- while (1)7 `! x0 ~- ?2 u5 y
- {
8 ~ L7 [* `9 I# S - /* 准备要写入的数据 */
6 m- {5 ?1 e3 ?) L( P3 X - data[0] = (USHORT)(rt_tick_get() / 10);; c9 ?: y, x: S
- data[1] = (USHORT)(rt_tick_get() % 10);
1 D* B- j5 G3 F) o* o - /* 向从机写多个保持寄存器 */
p( f6 L& ~8 E: S+ g2 W - error_code = eMBMasterReqWriteMultipleHoldingRegister(SLAVE_ADDR, /* salve address */
z8 D$ A8 s) e7 b - MB_SEND_REG_START, /* register start address */" Y" Q# w% M: T" D' D9 D
- MB_SEND_REG_NUM, /* register total number */
4 x- V/ G0 f& o( S; x8 o - data, /* data to be written */
- L5 U# [& C& {# }+ N - RT_WAITING_FOREVER); /* timeout */$ D6 K( h7 Y, c) X& R4 S W4 c
8 {# {2 E, M; \% w0 ], Q7 Y- /* Record the number of errors */: h0 z( f }( k+ s0 l
- if (error_code != MB_MRE_NO_ERR)
3 x& `! n8 o2 c1 a3 Z5 g - {' e' l4 c/ K# U8 Z+ R
- error_count++;
3 C3 H7 y* J5 y - }
: k5 N( Q7 M' T+ F& k+ |$ f1 u - }
: E+ ]1 _! c/ ` - }
% W" z0 _# @" m2 q' g - ! e9 H: ]* e0 R! m5 o I2 e$ V+ U4 s
- static void mb_master_poll(void *parameter)
! J. L! p) Q: T# P" C! r3 x - {
5 Z- ]. ^- \6 Q8 F% ^5 _# w7 O8 x - /* Modbus 主机协议栈初始化,初始化为 RTU 模式 */) S. {. |# z, w( n5 ~
- eMBMasterInit(MB_RTU, PORT_NUM, PORT_BAUDRATE, PORT_PARITY);
1 \6 g3 B2 q& ]( i) }0 ^* B0 h - eMBMasterEnable();
. U' [" w0 }1 s+ f5 d# n
: v+ P) y7 a4 h$ G% Z) _- while (1)
5 ~; U: Y. \' X0 C. J - {
- A( D0 y9 _/ Y' o8 O - /* 定时轮询 */- M; s, p$ P8 a8 c) I
- eMBMasterPoll();
2 S$ f, [" v4 ]6 f7 Z. H - rt_thread_mdelay(MB_POLL_CYCLE_MS);' s t( o ?( E' X" S7 T5 N. Z+ f
- }
" M- N9 P# S% ~% T ]) _! M - }
复制代码 编译下载,程序开始运行。
输入 mb_master_samlpe 运行主机示例程序。
# W4 s5 p! j* _0 K# j" Q5 ?% |% N0 Q2 q: I8 Q8 e4 Y P$ s7 K
|