单片机/MCU论坛
直播中

xiaopeng

11年用户 224经验值
擅长:嵌入式技术,处理器/DSP
私信 关注
[文章]

【HD-G2UL-EVM开发板体验】实现Modbus通讯

说明

Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。
Modbus协议目前存在用于串口、以太网以及其他支持互联网协议的网络的版本。

既然Modbus是一种软件协议,所以完全可以自己用代码来实现该协议,其实也不复杂。另外,还有一些开源的Modbus库可以进行移植和使用。我所了解的比较常用的Modbus开源库有FreeModbus和libmodbus,前者更适合在单片机上使用,后者适合在Linux/windows的系统上使用。

因为HD-G2UL-EVM开发板跑的是Linux系统,所以本次使用libmodbus来实现modbus通讯,避免重复造轮子。

源码获取

libmodbus的源代码可以从github上免费获取:
https://github.com/stephane/libmodbus

如果是在linux系统使用该库,建议直接在linux下clone该源代码,如果现在windows下clone源代码再拷贝到linux系统下可能会遇到一些问题(猜测是windows和Linux的编码格式不一样)。

图片.png

图片.png

创建安装目录

可以再任意目录下创建一个目录,后续步骤将把libmodbus库安装在该文件夹中。
(建议将该文件夹创建在普通用户目录下,不要创建在系统目录下,否则涉及到权限问题,后面会比较难解决)

我这里在/home/xinmeng/work目录下创建了一个install文件夹:

图片.png

配置编译选项

1、进入到源码目录,执行sh脚本,生成configure文件:
./autogen.sh

2、执行./configure命令设置编译条件和安装路径:

./configure --host=aarch64-poky-linux --enable-static --prefix=/home/xinmeng/work/install

其中,aarch64-poky-linux为交叉编译的前缀,/home/xinmeng/work/install 为安装路径

执行后结果如下:

图片.png

编译

使用make命令进行编译:
图片.png

安装

使用make install命令进行安装:
图片.png

将生成的.so库文件复制到开发板的/usr/lib目录下:

图片.png

编写测试程序

使用/dev/ttyS1串口进行测试,

编写好的Modbus 主机测试程序如下:

modbus_master_test.c:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "modbus.h" //modbus动态库文件

int main(int argc, char *argv[])
{
	uint16_t tab_reg[64] = {0};
	modbus_t *ctx = NULL;
	
	int rc;
	int i;
	
	//以串口方式创建libmodbus实例,并设置参数
	ctx = modbus_new_rtu("/dev/ttyS1", 9600, 'N', 8, 1);
	if(ctx == NULL)
	{
		fprintf(stderr, "Unable to allocate libmodbus contex\n");
		return -1;
	}
	
	modbus_set_debug(ctx, 1);//设置1可以看到调试信息
	modbus_set_slave(ctx, 1);//设置从机id
	
	if(modbus_connect(ctx) == -1)//等待设备连接
	{
		fprintf(stderr, "Connection failed:%s\n", modbus_strerror(errno));
		return -1;		
	}
	
	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(3000000);
	}
	
	modbus_close(ctx);
	modbus_free(ctx);
	return 0;
}

将install/include/modbus/中的头文件复制到与modbus_master_test.c文件一个目录中:

图片.png

编写makefile文件并编译

makefile文件:

modbus_master_test:modbus_master_test.c 
	$(CC) -Iinclude -o modbus_master_test modbus_master_test.c -L /usr/lib/ -lmodbus

clean:
	rm *.o modbus_master_test

编译生成可执行文件:

图片.png

图片.png

将可执行文件复制到开发板中并运行:

1、没接Modbus从机运行结果:
图片.png

2、使用Modbus slave模拟从机,运行结果:

图片.png

读到的数据完全正确。

结论

根据测试结果来看,Modbus主机的功能实现了,说明libmodbus库的移植成功了。

回帖(1)

infortrans

2023-1-10 11:34:09
学习一下,感谢分享。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分