瑞芯微RV1126B开发板(EASY-EAI-PI2) modbus
1. MODBUS简介MODBUS是一项应用层报文传输协议用于在通过不同类型的总线或网络连接的设备之间的客户机/服务器通信。Modbus比其他通信协议使用的更广泛的主要原因是因为它公开发表并且无版权要求而且易于部署和维护对供应商来说修改移动本地的比特或字节没有很多限制。1.1 协议版本与内容Modbus协议目前存在用于串口、以太网以及其他支持互联网协议的网络的版本。大多数Modbus设备通信通过串口EIA-485物理层进行。对于串行连接存在两个变种它们在数值数据表示不同和协议细节上略有不同。MODBUS模式分为三类一种模式是RTU远程终端设备)另一种模式是ASCII美国信息交换码第三种模式为TCP(运行在以太网上的协议)。【Modbus RTU】是一种紧凑的采用二进制表示数据的方式(Modbus协议上规定且默认模式必须是RTUASCII作为选项)【Modbus ASCII】是一种人类可读的冗长的表示方式。这两个变种都使用串行通信serial communication方式。对于通过TCP/IP例如以太网的连接存在多个【Modbus/TCP】变种这种方式不需要校验和计算。对于所有的这三种通信协议在数据模型和功能调用上都是相同的只有封装方式是不同的。1.2 通信和设备Modbus协议是一个master/slave架构的协议。有一个节点是master节点其他使用Modbus协议参与通信的节点是slave节点。每一个slave设备都有一个唯一的地址。在串行和MB网络中只有被指定为主节点的节点可以启动一个命令在以太网上任何一个设备都能发送一个Modbus命令但是通常也只有一个主节点设备启动指令。一个ModBus命令包含了打算执行的设备的Modbus地址。所有设备都会收到命令但只有指定位置的设备会执行及回应指令地址0例外指定地址0的指令是广播指令所有收到指令的设备都会运行不过不回应指令。所有的Modbus命令包含了检查码以确定到达的命令没有被破坏。基本的ModBus命令能指令一个RTU改变它的寄存器的某个值控制或者读取一个I/O端口以及指挥设备回送一个或者多个其寄存器中的数据。1.3 MODBUS使用要点通过以上叙述可知使用Modubs需要时刻围绕以下几点l Modbus是主从方式通信,不能同步进行通信l 主机不发送总线上就没有数据通信l 设备必须要有RTU协议,这是Modbus协议上规定的l 基本流程如下发送从机的地址功能码寄存器的地址寄存器地址的个数校验码回复从机的地址功能码要发送给主机数据的字节数数据校验码我司的easyeai-api软件开源库将复杂的报文格式、收发操作做了统一的封装为客户提供简单便捷的调用方式实现Modubs通讯功能。2. 快速上手2.1 开发环境准备如果您初次阅读此文档请阅读《入门指南/开发环境准备/Easy-Eai编译环境准备与更新》并按照其相关的操作进行编译环境的部署。在PC端Ubuntu系统中执行run脚本进入EASY-EAI编译环境具体如下所示。cd ~/develop_environment ./run.sh 22042.2 源码下载以及例程编译在EASY-EAI编译环境下创建存放源码仓库的管理目录cd /opt mkdir EASY-EAI-Toolkit cd EASY-EAI-Toolkit通过git工具在管理目录内克隆远程仓库git clone https://github.com/EASY-EAI/EASY-EAI-Toolkit-1126B.git注* 此处可能会因网络原因造成卡顿请耐心等待。* 如果实在要在gitHub网页上下载也要把整个仓库下载下来不能单独下载本实例对应的目录。进入到对应的例程目录执行编译操作具体命令如下所示cd EASY-EAI-Toolkit-1126B/Demos/netProtocol-modbus/ ./build.sh注* 由于依赖库部署在板卡上因此交叉编译过程中必须保持/mnt挂载。2.3 例程运行通过串口调试或ssh调试进入板卡后台定位到例程部署的位置如下所示cd /userdata/Demo/netProtocol-modbus运行例程命令如下所示./test-modbus_tcp_master ./test-modbus_tcp_slave2.4 运行效果TCP模式执行效果如下所示如果需要更换RTU模式可自行修改代码代码路径EASY-EAI-Toolkit-1126B/Demos/netProtocol-modbus/test-modbus_tcp_slave.cAPI的详细说明以及API的调用本例程源码详细信息见下方说明。3. MODBUS库函数说明本章节介绍EASY EAI的MODBUS库函数的使用方法。3.1 引用方式EASY EAI api库位于本仓库的easyeai-api目录中。为方便客户在本地工程中直接调用我们的EASY EAI api库此处列出工程中需要链接的库以及头文件等方便用户直接添加。API源代码路径为EASY-EAI-Toolkit-1126B/easyeai-api/netProtocol/modbus/。用户可通过源代码了解接口实现甚至可对源码进行修改。3.2 创建实例以TCP方式创建Modbus实例并初始化modbus_t* modbus_new_tcp(const char *ip, int port);复制具体介绍如下所示。3.3 设置从机ID设置从机ID的函数原型为void modbus_set_slave(modbus_t *ctx, int slave);具体介绍如下所示。3.4 和从机进行连接和从机建立连接的函数原型为void modbus_connect(modbus_t *ctx);具体介绍如下所示。3.5 寄存器进行操作功能码对应函数3.5.1 读取线圈状态可读取多个连续线圈的状态对应功能码为0x01int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);具体介绍如下所示。3.5.2 读取输入状态可读取多个连续输入的状态对应功能码为0x02int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);具体介绍如下所示。3.5.3 读取保持寄存器的值可读取多个连续保持寄存器的值对应功能码为0x03int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);具体介绍如下所示。3.5.4 读输入寄存器的值可读取多个连续输入寄存器的值对应功能码为0x04int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);具体介绍如下所示。3.5.5 写入单个线圈的状态对应功能码为0x05int modbus_write_bit(modbus_t *ctx, int addr, int status);具体介绍如下所示。3.5.6 写入多个连续线圈的状态对应功能码为15int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);具体介绍如下所示。3.5.7 写入单个寄存器对应功能码为0x06int modbus_write_register(modbus_t *ctx, int addr, int value);具体介绍如下所示。3.5.8 写入多个连续寄存器对应功能码为16int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src);具体介绍如下所示。3.6 关闭套接字关闭套接字函数原型为void modbus_close(modbus_t *ctx);具体介绍如下所示。3.7 释放实例和从机建立连接的函数原型为void modbus_free(modbus_t *ctx);具体介绍如下所示。4. 使用实例示例主机代码路径EASY-EAI-Toolkit-1126B/Demos/netProtocol-modbus/test-modbus_tcp_master.c。示例从机代码路径EASY-EAI-Toolkit-1126B/Demos/netProtocol-modbus/test-modbus_tcp_slave.c。