首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Beaglebone通过半双工RS-485突破板实现自动RTS的PySerial

用Beaglebone通过半双工RS-485突破板实现自动RTS的PySerial
EN

Stack Overflow用户
提问于 2014-01-15 21:32:11
回答 3查看 11.2K关注 0票数 6

我正在尝试使用Beaglebone运行Angstrom (3.8内核),在9600-N8-1的半双工RS-485网络上与设备通信。

我正在尝试使用一个RS-485突破板类似于这个:https://www.sparkfun.com/products/10124,除了芯片是一个MAX3485 http://www.maximintegrated.com/datasheet/index.mvp/id/1079。我用别针和终端条买了预装的板。我的一位朋友用示波器对它进行了测试,并宣布RS-485板工作正常。董事会有五个引脚连接到BBB。3-5V (电源)、RX、TX、RTS和GND.

我已经禁用了对血脑屏障的HDMI支持,以便UART4_RTSnUART4_CTSn引脚可用。

代码语言:javascript
复制
    mkdir /mnt/boot
    mount /dev/mmcblk0p1 /mnt/boot
    nano /mnt/boot/uEnv.txt
    #change contents of uEnv.txt to the following:
    optargs=quiet capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN 

然后,我找到了一个覆盖来启用带有RTS/CTS控件的UART-4:

代码语言:javascript
复制
            /*
     * Modified version of /lib/firmware/BB-UART4-00A0.dtbo to add RTS so we can reset Arduinos
     */
    /dts-v1/;
    /plugin/;

    / {
      compatible = "ti,beaglebone", "ti,beaglebone-black";
      part-number = "BB-UART4-RTS";
      version = "00A0";
      exclusive-use = "P9.13", "P9.11", "P9.15", "P8.33", "P8.35", "uart4";

      fragment@0 {
        target = <0xdeadbeef>;

        __overlay__ {


          pinmux_bb_uart4_pins {
            pinctrl-single,pins = <
              0x070 0x26   /* P9_11 = UART4_RXD = GPIO0_30,    MODE6 */
              0x074 0x06   /* P9_13 = UART4_TXD = GPIO0_31,    MODE6 */
              /* need to enable both RTS and CTS, if we only turn on RTS then driver gets confused */
              0x0D0 0x26   /* P8_35 = UART4_CTSN = lcd_data12, MODE6 */
              0x0D4 0x06   /* P8_33 = UART4_RTSN = lcd_data13, MODE6 */
              /* 0x040 0x0F   /* P9_15 = GPIO1_16 = GPIO48,       MODE7  failed attempt to put DTR on gpio */
            >;
            linux,phandle = <0x1>;
            phandle = <0x1>;
          };
        };
      };

      fragment@1 {
        target = <0xdeadbeef>;

        __overlay__ {
          status = "okay";
          pinctrl-names = "default";
          pinctrl-0 = <0x1>;
        };
      };

      __symbols__ {
        bb_uart4_pins = "/fragment@0/__overlay__/pinmux_bb_uart4_pins";
      };

      __fixups__ {
        am33xx_pinmux = "/fragment@0:target:0";
        uart5 = "/fragment@1:target:0"; /* Not a mistake: UART4 is named uart5 */
      };

      __local_fixups__ {
        fixup = "/fragment@1/__overlay__:pinctrl-0:0";
      };
    };

编译并启用了覆盖:

代码语言:javascript
复制
    cd /lib/firmware
    dtc -O dtb -o BB-UART4-RTS-00A0.dtbo -b 0 -@ BB-UART4-RTS-00A0.dts 
    echo BB-UART4-RTS:00A0  > /sys/devices/bone_capemgr.*/slots

像这样把485板连接到BB上

代码语言:javascript
复制
    3-5V to P9_05 (VDD_5V)
    RX-I to P9_13 (UART4_TXD) 
    TX-O to P9_11 (UART4_RXD)
    RTS  to P8_33 (UART4_RTSn)
    GND  to P9_01 (DGND)

在python中,我试图像这样使用串行端口:

代码语言:javascript
复制
    import serial
    ser = serial.Serial('/dev/ttyO4', baudrate=9600, rtscts=True)
    ser.write(list_of_byte_dat)

我知道这个程序可以工作,因为当我在/dev/ttyUSB0上使用USB到RS-485转换器并设置rtscts=False时,通信在两个方向上都工作得很好。但是我无法用RS-485板使通讯正常工作。

我的RS-485板有两个问题,都是处理RTS的.

  1. 板上的RTS按我所期望的方式向后工作。当我在rs485板的RTS引脚上施加电压时,板上的RTS引线就会关闭,板也不会传输。当我从RTS引脚上移除电压时,RTS引线打开,板就会传输。如何逆转血脑屏障上UART_RTSn引脚的极性?Temporary solution: I've made a small bone script program that uses UART4_RTSn pin as input. It turns on a different GPIO when the UART4_RTSn pin is off and turns off that same GPIO pin when the UART4_RTSn pin is on. Then hooked up the RTS pin on the rs485 board to the GPIO pin instead of the UART4_RTSn pin. 这似乎是一个糟糕的解决方案,但它确实使RS485板上的RTS在正确的时间启动,当响应命令line.How时,line.How是否可以通过调整硬件配置或以pyserial方式更改配置来改变UART4_RTSn引脚的极性? 这就引出了第二个问题。
  2. 正如我在问题1中指出的,在将值回显到tty端口时,UART4_RTSn引脚将自动工作(但向后),如下所示: echo -en‘\X02\xFD\xCD. /dev/ttyO4 4 这将使UART4_RTSn在传输数据时闪烁。如果我有它的设置,没有上面提到的文字记录,那么它将是正常的,并在传输时眨眼。如果我使用我的骨记录黑客,那么它将正常关闭,并在传输时眨眼(这就是我想要的)。但是,这只在使用命令行的echo时才有效。当我使用python并设置串口时,UART4_RTSn引脚就不活动了。它在传输时不会眨眼。一旦我在python中做了这个声明: ser =serial.Serial(‘/dev/ttyO4 4’,baudrate=9600,rtscts=True) UART4_RTSn销关闭并保持关闭。使用ser.write(stuff)发送信息时,它不会闪烁。因此,rs485板无法传输。如何使UART4_RTSn引脚在pyserial中自动工作?我尝试过设置rtscts=False,但它没有起作用,我能够使用ser.setRTS(True)ser.setRTS(False)手动切换引脚值,所以我知道我使用的是正确的引脚,并且它正在被识别。但我不想直接切换UART4_RTSn引脚。我希望它在串行端口传输数据时自动工作,在使用echo时自动工作,但在Python中则不这样做。

任何帮助都将不胜感激。

EN

回答 3

Stack Overflow用户

发布于 2014-01-17 02:42:11

RTS通常是一个活动的低信号,我怀疑使用echo传输数据的原因是它不使用RTS/CTS (保持高),所以只能传输数据。

根据http://www.raspberrypi.org/phpBB3/viewtopic.php?f=26&t=29408上的一篇文章

如果启用硬件流控制(在"man“中启用crtscts,或启用"stty /dev/ttyAMA0”或pySerial rtscts=True),则只有在断言CTS时才会进行发送。除非内核输入缓冲区已满,否则RTS将被断言。内核输入缓冲区大约是1页或4KB,所以在RTS实际更改之前,应用程序必须在读取方面落后很多。

因此,检查CTS是被断言(拉到地面)在你的董事会之外。然而,我不认为这将给你正确的控制RTS,你需要。

因此,对于您的应用程序,您应该禁用硬件流控制(rtscts=False),并在写之前用setRTS(1)手动控制RTS,然后再用setRTS(0)控制RTS。

如果您仍然没有看到数据通过设备,尝试交换A&B线- A/B标签是(令人沮丧的)不一致的RS485设备。如果可能的话,最好在你自己的应用中使用D+/D标签。

票数 1
EN

Stack Overflow用户

发布于 2014-07-29 08:50:42

使用ioctl改变逻辑级别..。

代码语言:javascript
复制
98         struct serial_rs485 rs485conf;
 99 
100         /* Enable RS485 mode: */
101         rs485conf.flags |= SER_RS485_ENABLED;
102 
103         /* Set logical level for RTS pin equal to 1 when sending: */
104         rs485conf.flags |= SER_RS485_RTS_ON_SEND;
105         /* or, set logical level for RTS pin equal to 0 when sending: */
106         rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);
107 
108         /* Set logical level for RTS pin equal to 1 after sending: */
109         rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
110         /* or, set logical level for RTS pin equal to 0 after sending: */
111         rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
112 
113         /* Set rts delay before send, if needed: */
114         rs485conf.delay_rts_before_send = ...;
票数 1
EN

Stack Overflow用户

发布于 2014-01-16 22:42:21

  1. 您可以使用pnp晶体管/p沟道mosfet/逻辑门极非逆变器(如7404 )。
  2. 也许您必须在写操作ser.write(.)之后刷新写缓冲区ser.flush()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21148655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档