飞凌嵌入式
直播中

jf_01801880

2年用户 91经验值
擅长:嵌入式技术
私信 关注
[技术]

【飞凌i.MX9352开发板试用】 + libmodbus移植 测试 485接口

Modbus是一种通信协议,通常用于工业自动化系统中的设备之间进行通信。它可以在不同的物理介质上运行,包括RS485接口。RS485是一种串行通信标准,常用于工业自动化系统中。它允许多个设备通过单个通信线路进行通信,并且可以实现远距离通信。因此,Modbus协议经常在RS485接口上实现,以便在工业自动化系统中进行设备之间的通信。

libmodbus是一个用于实现Modbus协议的开源C语言库,它提供了一组API,用于在不同的平台上进行Modbus通信。libmodbus库支持Modbus RTU、Modbus ASCII和Modbus TCP协议,并且可以在Linux、Unix、Windows等操作系统上使用。它可以用于编写Modbus主机和从机应用程序,并支持多个从机设备的读写操作。libmodbus库还提供了一些方便的工具,如modbus命令行工具和modbus服务器,用于测试和调试Modbus通信。由于其开源性质和跨平台支持,libmodbus成为了工业自动化领域中广泛使用的Modbus库之一。

i.MX9352开发板上已经设计了两个RS485接口且电磁兼容电路设计得很到位,还用了金升阳的芯片专门进行了隔离,很赞,我们这里通过移植libmodbus库到板子上,硬件上把两个485接口连起来,一主一从进行模拟实际工业上两个设备通过RS485走Modbus RTU协议进行通讯。

先从官网拉源码进行编译,这里我选择直接在板子编译,连接好网线后在板子上进行。

git clone https://github.com/stephane/libmodbus.git 
cd libmodbus
./autogen.sh
./configure 
make -j
sudo make install

这样我们libmodbus的环境就配好了,开始写代码测试板子的485接口,一个做主,一个做从。

host 主机

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "modbus/modbus.h"

#define SLAVE_NAME "/dev/ttyUSB3"

unsigned short dest[256] = {0x01, 0x02};
uint8_t m_bits = 0, m_input_bits = 0;

int main()
{
	modbus_t *ctx = modbus_new_rtu(SLAVE_NAME, 9600, 'N', 8, 1);	
	if (ctx == NULL)
	{
		fprintf(stderr, "%s", SLAVE_NAME);
		return -1;
	}
	modbus_set_debug(ctx, 1);
	modbus_set_response_timeout(ctx, 0, 1000000);
	modbus_set_slave(ctx, 1);

	if (modbus_connect(ctx) == 1)
	{
		fprintf(stderr, "connection failed!\n");
	}

	modbus_mapping_t *map = modbus_mapping_new_start_address(0, 1, 0, 1, 0, 0x10, 0, 0); //
  if (map == NULL)
    {
        fprintf(stderr, "Failed to allocate the mapping\n");
        return -1;
    }

    map->tab_registers = dest;
    map->tab_bits = &m_bits;
    map->tab_input_bits = &m_input_bits;

	while(1)
	{
		uint8_t query[256];

        int rc = modbus_receive(ctx, query);
        int header_length = modbus_get_header_length(ctx);
        query[0] = modbus_get_slave(ctx);
        if (rc > 0)
        {
            
                modbus_reply(ctx, query, rc, map);
        }
        else
        {
            modbus_flush(ctx);
            fprintf(stderr, "ctx_host:Failed to modbus_receive\n");
        }

        usleep(50000);
	}

	return 0;
}

slave从机读取

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "modbus/modbus.h"

#define SLAVE_NAME "/dev/ttyUSB0"

unsigned short dest[256] = {0};

int main()
{
	modbus_t *ctx = modbus_new_rtu(SLAVE_NAME, 9600, 'N', 8, 1);	
	if (ctx == NULL)
	{
		fprintf(stderr, "%s", SLAVE_NAME);
		return -1;
	}
	modbus_set_debug(ctx, 1);
	modbus_set_response_timeout(ctx, 0, 1000000);
	modbus_set_slave(ctx, 1);

	if (modbus_connect(ctx) == 1)
	{
		fprintf(stderr, "connection failed!\n");
	}

	while(1)
	{
		if (modbus_read_registers(ctx, 0x0001, 1, dest) == -1)
		{
			fprintf(stderr, "read error!\n");
		}
		else
		{
			modbus_flush(ctx);
		}
		
		usleep(300000);
	}

	return 0;
}

简单的Makefile

all:
	gcc src/slave.c -o slave  -lmodbus
	gcc src/host.c -o host  -lmodbus

编译后执行的效果
image.png

如果执行的时候提示没有找到库但已经安装好了,可以ldd查看一下执行程序缺少了哪个,似乎是因为板子没有配置LD_LIBRARY_PATH的原因,可以参考一下这个进行配置

这个错误消息表明您的程序无法找到libmodbus.so.5共享库文件。这可能是由于该库未安装或未正确配置导致的。

要解决这个问题,您可以尝试以下步骤:

  1. 检查libmodbus.so.5是否已安装。您可以使用以下命令来搜索该库:
sudo find / -name libmodbus.so.5

如果该库已安装,则命令将返回库文件的路径。如果该库未安装,则您需要安装它。

  1. 如果该库已安装,但程序仍然无法找到它,请确保库文件的路径已添加到LD_LIBRARY_PATH环境变量中。您可以使用以下命令来设置环境变量:
export LD_LIBRARY_PATH=/path/to/lib:$LD_LIBRARY_PATH

请将"/path/to/lib"替换为libmodbus.so.5所在的目录。

  1. 如果您已经尝试了上述步骤但问题仍然存在,请确保程序正在使用正确的库文件。您可以使用以下命令来检查程序正在使用哪个库文件:
ldd /path/to/your/program

请将"/path/to/your/program"替换为您的程序的路径。

如果您还有其他问题,请提供更多详细信息,以便我能够更好地帮助您解决问题。

上一下硬件连接图,直接A1连A2,B1连B2即可。

IMG_20230628_123140.jpg

好了,这篇就到这里了。

更多回帖

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