我试图建立一个半双工RS-485通信使用libmodbus上的Raspberry Pi运行拉斯宾Buster,与FTDI USB到串行适配器。当我运行ls /dev/时,我的FTDI适配器显示为ttyUSB0。
我尝试了以下示例代码:
#include <modbus.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(void) {
modbus_t *ctx = modbus_new_rtu("/dev/ttyUSB0", 19200, 'N', 8, 1);
if (ctx == NULL) {
fprintf(stderr, "Unable to create the libmodbus context\n");
return 0;
}
if (modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485) == -1) {
fprintf(stderr, "Error setting the serial port as RS-485\n");
fprintf(stderr, "errno: %d\n (EBADF == 9)", errno);
modbus_free(ctx);
return 0;
}
}
用gcc test1.c -I/usr/include/modbus -lmodbus
编译。我得到了errno
作为9
,或者EBADF
,即使我用sudo
运行了这段代码。
发布于 2019-10-30 07:28:09
对于您的问题,有一个非常简单的解决方案:只是不要设置MODBUS_RTU_RS485
,很可能您不需要它。
这种模式实际上是对没有自动(硬件)方向控制的设备的解决方案。如您所知,Modbus RTU工作在半双工RS485链路上(只允许一个设备说话,而所有其他设备只能监听),因此需要一个额外的信号(到RX和TX)来控制设备在任何时候都写到总线上(方向控制)。
因此,您只需要设置MODBUS_RTU_RS485
,如果您的设备缺乏此功能,这是非常不可能的,或者如果您正在构建自己的收发器。特别是,大多数基于FTDI芯片的设备都应该具有此特性,因为该芯片本身具有TXDEN (传输启用)引脚。有关更多细节和向非默认引脚公开TXDEN信号的技巧,请参见这里。
当您没有这个特性(一种常见的场景是您想要在您的Rpi上使用嵌入式UART通过RS485为Modbus,实现您自己的收发器)时,您需要一个软件(或硬件)解决方案。这就是MODBUS_RTU_RS485
应该派上用场的地方,重新使用RTS流量控制信号。不幸的是,大多数串行驱动程序(包括您可能正在使用的ftdi_sio
)不支持这种模式(请再次参考上面的链接 )。
幸运的是,解决方法有一些解决办法:请参阅这里以获得完整的讨论。您还可以查看这个答案,其中我解释了如何使用Rpi上的GPIO引脚设置libmodbus,支持在总线上切换方向(也适用于大多数SBCs,例如,我在Pocket计算机上成功地使用了这种方法)。
https://stackoverflow.com/questions/58617314
复制相似问题