简介 FreeModbus 是一款开源的 Modbus 协议栈,但是只有从机开源,主机源码是需要收费的。同时网上也没有比较好的开源的 Modbus 主机协议栈,在这样的背景下,armink 大神开发了这款支持主机模式的 FreeModbus 协议栈。 本文的分为2篇推送,分别介绍如何在潘多拉开发板上运行 Modbus 主机与从机。首先介绍串口方式通信的 Modbus 主机和从机。然后介绍如何使用网络进行 Modbus 通信。 准备工作1、首先演示使用串口作为 Modbus 通信通道的方式,将潘多拉开发板的 uart2 通过 usb 转串口线连接到电脑上 2、使用 usb 线连接开发板的 st-link 接口到电脑上,打开电源开发,开发板上电。 3、查看设备管理器,可以看到两个串口设备,一个用来 shell 通信,一个用来 Modbus 通信。 8 H: q' I: l9 v4 C: N4 Y
运行 Modbus 主机配置工程在 RT-Thread 源码目录下找到潘多拉的bsp rt-thread\bsp\stm32\stm32l475-atk-pandora ,在此目录下打开 ENV 工具。 配置 FreeModbus 软件包1、输入 menuconfig 命令打开配置工具 2.按照下面的路径进入 FreeModbus 软件包的配置菜单,并开启主机模式 - RT-Thread online packages --->
& g. G2 } H7 W! b( ^' R$ L4 b8 P# g - IoT - internet of things --->" t ^/ B5 o- U9 r) N+ M( A
- [*] FreeModbus: Modbus master and slave stack --->
$ S+ V" O0 K. m+ K$ C+ E% x* j - [*] Master mode --->
$ V) l7 Q+ [& x) ? - [ ] Slave mode ----
& h0 E; R) L9 D& b0 [8 _ - 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:通信用的波特率 & C/ w9 b( l6 E5 E4 x* i, o
/ w# X$ g! C, u
% C1 d2 [0 G% z* u5 p
配置硬件 uart2# f8 }9 q9 X# i% \+ q! X9 c# k
然后返回到主菜单,进入硬件配置的菜单里开启 uart2 。 - Hardware Drivers Config --->
/ e$ g5 ^ |2 p! o0 m8 i - On-chip Peripheral Drivers --->8 M$ J# K& y# r9 q+ f# g8 e
- -*- Enable UART --->" N7 y2 k e4 {; c
- [*] Enable UART2
复制代码
! F/ c& ~5 N' c8 Z0 Q- b退出 menuconfig 配置工具并保存。然后 pkgs --update 下载软件包,然后 scons --target=mdk5 生成工程。 : t3 z5 g/ a" U8 Z8 v3 [
$ T! I! J9 _# K P! u1 d: c
7 f4 {3 A- i2 c( [3 o6 Y7 t运行示例程序打开工程,在 FreeModbus 分组里可以看到主机的示例代码 sample_mb_master.c 关键代码如下所示:
% ?8 Y5 a; @* z1 u- #define MB_POLL_CYCLE_MS 500* |# W% L9 \8 C( t! Z
* A7 C7 _" Y2 G1 t B. T- static void send_thread_entry(void *parameter): @/ v. \; \; L4 K2 S1 ^
- {
. {" I* B7 F# ?* z - eMBMasterReqErrCode error_code = MB_MRE_NO_ERR;$ \: n( B) J+ I7 }( S4 P- r
- rt_uint16_t error_count = 0;
% b& f9 z9 o+ z1 N( P% @) I4 g - USHORT data[2] = {0};, o1 e1 U8 t( m7 a
- w1 E6 @. [4 K- while (1)- e3 e: T; z5 |/ ^0 U
- {
O) t$ ]6 e8 W - /* 准备要写入的数据 *// }& n8 B+ m1 q2 u& o! W2 s
- data[0] = (USHORT)(rt_tick_get() / 10);
' Z$ j6 g; y" r @+ @& r: ? - data[1] = (USHORT)(rt_tick_get() % 10);+ _: s) c5 X. [
- /* 向从机写多个保持寄存器 */! @% E& O2 m8 h' z. j# L& z
- error_code = eMBMasterReqWriteMultipleHoldingRegister(SLAVE_ADDR, /* salve address */8 |% p! \9 ~% E! y) g8 T
- MB_SEND_REG_START, /* register start address */2 s# r0 S! |+ h$ i3 B. `" E
- MB_SEND_REG_NUM, /* register total number */- I0 Y) H7 t) d3 ^
- data, /* data to be written */- A( z7 z z! g2 Z, V# s1 F- v
- RT_WAITING_FOREVER); /* timeout */
2 X7 }: P5 |1 p% }. F5 _
. n7 _* B+ I! i; O' Y" ^" |- /* Record the number of errors */2 t8 l$ h. w0 {& w/ b
- if (error_code != MB_MRE_NO_ERR)
' u: z0 _3 c, p0 M7 x* l% V; s - { o, D, a" D" K3 B
- error_count++;
+ B8 s4 X* v/ N+ j, n - }
3 z, c! ]. j% n - }$ X5 ~. f! X# |- x
- }+ d2 y; t; B( S% m7 `6 @
- . f/ G, N9 J$ x) N* `$ t5 t
- static void mb_master_poll(void *parameter)9 C. c( p/ [/ O1 K
- {* S( I/ [$ C2 ^. T( J+ T$ x# L) s7 O
- /* Modbus 主机协议栈初始化,初始化为 RTU 模式 *// l. t8 N( S4 |" f1 Z
- eMBMasterInit(MB_RTU, PORT_NUM, PORT_BAUDRATE, PORT_PARITY);! l5 k, h* b0 c/ S3 S1 h
- eMBMasterEnable();( i- L7 u# n/ o$ @* r
; R5 B% [. K6 _1 i- while (1)
6 D. F, U4 ^* m( x7 O; u - {, S4 F5 H7 g; k E& X Y& k$ S
- /* 定时轮询 */
- c' ]8 i! l+ m3 q k, ` - eMBMasterPoll();
+ S5 E# k$ z) k1 e# h2 H: S - rt_thread_mdelay(MB_POLL_CYCLE_MS);
5 E' y+ Z( U% X4 [5 |0 ?1 ` - }
3 |' M! Q4 Z7 b h( m - }
复制代码 编译下载,程序开始运行。
输入 mb_master_samlpe 运行主机示例程序。
; j6 D0 x ]0 q$ M* t/ `
" T' U5 `1 a7 K# J; K1 ^ |