本文测试主机为 arm-linux,可以使用 libmodbus 静态库实现modbus通信,为追求可移植性,本文主要使用 freemodbus 来实现。
1、下载
移植到arm的需下载源码进行交叉编译 http://libmodbus.org/releases/libmodbus-3.1.4.tar.gz
2、解压安装
tar -xzvf libmodbus-3.1.4.tar.gz
cd libmodbus-3.1.4
# 新建安装文件夹
mkdir -p install
chmod 777 install
./configure --prefix=$(pwd)/install --host=arm-linux --enable-static ac_cv_func_malloc_0_nonnull=yes CC=arm-fsl-linux-gnueabi-gcc
make
make install
3、编译完成
编译完成将获得如下文件
4、测试
我的工程总体结构如下所示
在 mys_src 里面添加 modbus 主机测试程序 modbus_test.c
makefile编写如下所示:
#编译配置,使能为1
CONFIG_MODBUS_BUILD = 1
#当前路径
CUR_DIR := $(shell pwd)
#libmodbus目录
LIBMODBUS_DIR := $(CUR_DIR)/../libmodbus
# 头文件路径
INCLUDE :=
INCLUDE += -I$(CUR_DIR)/../include/
ifeq ($(CONFIG_MODBUS_BUILD), 1)
INCLUDE += -I$(LIBMODBUS_DIR)/include/modbus/
endif
#C编译器的选项
CFLAGS :=
CFLAGS += -g -Wall
CFLAGS += -std=gnu99
CFLAGS += $(INCLUDE)
#库文件参数
LDFLAGS :=
#libmodbus共享库链接
#LDFLAGS += -L$(LIBMODBUS_DIR)/lib
#libmodbus静态库链接
ifeq ($(CONFIG_MODBUS_BUILD), 1)
LDFLAGS += $(LIBMODBUS_DIR)/lib/libmodbus.a
endif
SRCS += modbus_test.c
OBJS += modbus_test.o
BINS += modbus_test
all:$(OBJS) $(BINS)
$(OBJS):%.o:%.c
$(CC) -c $(CFLAGS) $^ -o $(OBJ_DIR)/$@
$(BINS):$(OBJS)
$(CC) -o $(BIN_DIR)/$@ $(OBJ_DIR)/$^ $(LDFLAGS)
modbus_test.c
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <modbus.h>
#define MODBUS_DEV_NAME "/dev/ttymxc3" ///< 串口设备
int main(void)
{
modbus_t *ctx =NULL;
// 以串口的方式创建libmobus实例,并设置参数
ctx = modbus_new_rtu(MODBUS_DEV_NAME, 115200, 'N', 8, 1);
if (ctx == NULL) //使用UART4,对应的设备描述符为ttymxc3
{
fprintf(stderr, "Unable to allocate libmodbus contex\n");
return -1;
}
// 使用RS485时需考虑设置串口模式、RTS引脚等
// modbus_rtu_set_serial_mode(MODBUS_RTU_RS485); //设置串口模式
modbus_set_debug(ctx, 1); //设置1可看到调试信息
modbus_set_slave(ctx, 1); //设置slave ID
if (modbus_connect(ctx) == -1) //等待连接设备
{
fprintf(stderr, "Connection failed:%s\n", modbus_strerror(errno));
return -1;
}
int i,rc;
uint16_t tab_reg[64] = {0}; //定义存放数据的数组
while (1)
{
printf("\n----------------\n");
//读取保持寄存器的值,可读取多个连续输入保持寄存器
rc = modbus_read_registers(ctx, 0, 10, tab_reg);
if (rc == -1)
{
fprintf(stderr,"%s\n", modbus_strerror(errno));
return -1;
}
for (i=0; i<10; i++)
{
printf("reg[%d] = %d(0x%x)\n", i, tab_reg[i], tab_reg[i]);
}
usleep(5000000);
}
modbus_close(ctx); //关闭modbus连接
modbus_free(ctx); //释放modbus资源,使用完libmodbus需要释放掉
return 0;
}
5、测试
modbus从机模拟
Modbus slave测试工具可以用来做modbus从机设备,从而实现arm控制板通过串口与PC端模拟的modbus从机进行通信测试。
Modbus slave下载地址:https://www.modbustools.com/download/ModbusSlaveSetup64Bit.exe
然后设置 setup->slave definition 从机ID、设置为保存寄存器,10条
同时我们也给寄存器设置一些值
开发板运行测试程序后,成功读取modbus从机寄存器值