我正在尝试使用运行Angstrom(3.8内核)的Beaglebone Black与9600-N-8-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-I,TX-O,RTS和GND.
我已禁用BBB上的HDMI支持,以便UART4_RTSn和UART4_CTSn引脚可用.
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:
/*
* 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";
};
};
编译并启用叠加层:
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
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我试图使用这样的串口:
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.
>电路板上的RTS从我期望的方式向后工作.当我在rs485板的RTS引脚上施加电压时,电路板上的RTS指示灯熄灭,电路板不会发送.当我从RTS引脚移除电压时,RTS LED导通,电路板将发送.如何反转BBB上UART_RTSn引脚的极性?
临时解决方案:我已经制作了一个使用UART4_RTSn引脚作为输入的小骨脚本程序.当UART4_RTSn引脚关闭时,它会打开另一个GPIO,当UART4_RTSn引脚打开时,它会关闭同一个GPIO引脚.然后将rs485板上的RTS引脚连接到GPIO引脚而不是UART4_RTSn引脚.
这似乎是一个糟糕的解决方案,但它确实使RS485板上的RTS在从命令行回显到/ dev / ttyO4的正确时间出现.
如何通过调整硬件配置或更改pyserial中的配置来更改UART4_RTSn引脚的极性?
这让我想到了第二个问题
>正如我在问题1中所述,UART4_RTSn引脚在向tty端口回显值时会自动(但向后)工作,如下所示:
echo -en '\x02\xFD\xCD......' > /dev/ttyO4
这将使UART4_RTSn LED在数据传输过程中闪烁.如果我没有上面提到的bonescript进行设置,那么它将正常启动并在传输时闪烁.如果我使用我的bonescript hack那么它会正常关闭并在传输时闪烁(这就是我想要的).但是,这仅在从命令行使用echo时才有效.当我使用python并设置串口时,UART4_RTSn引脚变为无效.传输时不会闪烁.一旦我在python中发表声明:
ser = serial.Serial('/dev/ttyO4', 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中则不行.
任何帮助将不胜感激.
最佳答案 RTS通常是一个低电平有效信号,我怀疑你看到数据与回声一起传输的原因是它没有使用RTS / CTS(保持高电平),因此只能传输数据.
根据http://www.raspberrypi.org/phpBB3/viewtopic.php?f=26&t=29408的帖子
If you enable hardware flow control (CRTSCTS in “man termios”, or
“stty crtscts -F /dev/ttyAMA0”, or pySerial rtscts=True), then sending
will take place only when CTS is asserted. RTS will be asserted except
when the kernel input buffer is full. The kernel input buffer is about
one page or 4KB, so your application has to get well behind with its
reads before RTS actually changes.
因此,检查CTS是否在电路板外部断言(拉到地).但是我不认为这会让你对你需要的RTS有正确的控制权.
因此,对于您的应用程序,您应该禁用硬件流控制(rtscts = False)并在写入之前使用setRTS(1)手动控制RTS,然后再使用setRTS(0).
如果您仍然没有看到数据通过设备,请尝试交换A& B线 – 在RS485设备上(令人沮丧地)A / B标签不一致.如果可能,最好在您自己的应用程序中使用D / D标签.