免费国外b站刺激战场直播app,柴火垛里的疯狂55集,百万日元的女人们,洞房初夜

關(guān)于RS485自動收發(fā)那些天坑

對于 RS485 ,大家應(yīng)該都很熟悉了,在 modbus 協(xié)議中最常用。

但最近魚鷹在調(diào)試 RS485 時遇到了不少問題。

首先,我們知道 RS485 屬于半雙工,同一時刻,只能收或者發(fā)。

像這種情況,我們需要一種機制控制它的收發(fā),既可以是軟件,也可以是硬件。

硬件

一般RS485芯片,都會提供一個控制引腳完成收發(fā)工作。

這個引腳可能由用戶控制,也可能由芯片自動控制(一般比較貴),還有第三種可能是,設(shè)計一種自動收發(fā)的電路(應(yīng)該沒有超脫三界之外的吧)。

自動收發(fā)電路很多,有用三極管控制的,也有用緩沖器的(好像是吧),電路大致如下:

圖來源于網(wǎng)絡(luò)

因為 UART_TX 空閑電平為高,因此三極管導(dǎo)通,RE 接地,默認(rèn)為發(fā)。

但是我還看過一種用 S8550 實現(xiàn)的電路,基極接地,三極管默認(rèn)(空閑)不導(dǎo)通。

我不是電子工程師,無法判斷兩者電路的好壞,但我感覺默認(rèn)不導(dǎo)通更好,功耗更低,另外即使引腳未配置(剛上電,肯定沒那么快配置),那么也不會影響到總線上的其它節(jié)點通信,這個涉及到各個 485 節(jié)點上電時序問題。

這種電路好像因為三極管開關(guān)頻率限制,無法做到很高頻率(一般115200,市面上購買的模塊基本都是類似這種電路)。

總之一句話,電路需要默認(rèn)處于接收狀態(tài),保證不會干擾總線通信,否則只要其中一個節(jié)點默認(rèn)狀態(tài)不是接收,那么無法通信(因此,如果無法通信,不如查一查是否有節(jié)點狀態(tài)不對,而不是首先懷疑芯片燒掉了)。

另外其中一個節(jié)點發(fā)送,其它節(jié)點必須保持接收,不要發(fā)送數(shù)據(jù),否則數(shù)據(jù)肯定不是你想要的。

這種有頻率限制,那是否有那種頻率沒限制,同時不需要買貴的 RS485 自動收發(fā)芯片的方案呢?

還真有,這要看你的 MCU 芯片本身是否支持了。

比如 IMX93,就可以實現(xiàn)(參考 IMX93RM.pdf,62.3.4)。

官網(wǎng)論壇也有對此實現(xiàn)方法:

https://community.nxp.com/t5/i-MX-Processors/RS485-iMX93/m-p/1896764#M225674

特別注意這里使用 RTS 引腳,而不是 CTS(其它芯片可能是用RTS)

設(shè)備樹配置如下(一般在arch/arm64/boot/dts/freescale/xxx 下,引腳描述文件

pinctrl_uart7: uart7grp {fsl,pins =
 ;};&lpuart7 { uart-has-rtscts; rts-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>; linux,rs485-enabled-at-boot-time; 
// rs485 abilitata fin da subito al boot rs485-rts-active-high; rs485-rts-delay = <1 1>;};

最終的效果是:

來源官網(wǎng)論壇

當(dāng)你發(fā)送數(shù)據(jù)時,DE 引腳會被芯片自動控制電平狀態(tài)(默認(rèn)為低電平),從而實現(xiàn)不需要由用戶控制的自動收發(fā)功能,并且沒有頻率限制(但受串口自身頻率限制)。

 軟件

說完硬件,再說軟件。

其實很多軟件或驅(qū)動是會帶上 DE 引腳的控制(硬件挖坑,軟件負(fù)責(zé)填坑),比如如果你的開發(fā)板不支持上面的功能,那大概率這顆芯片的Linux串口驅(qū)動會帶上該功能。

還有開源軟件 libmodbus 也考慮了這個引腳的控制。只是從效率和省心的角度,當(dāng)然是自動收發(fā)爽了。

為了使用 485 的功能,不管 MCU 是否支持,都需要使能 485 模式,只是可能參數(shù)上需要進(jìn)行調(diào)整。下面是硬件支持的配置:

#include #include #include #include #include  int fd = open("/dev/ttyLP7", O_RDWR);    if (fd < 0) { } struct serial_rs485 rs485conf = {0}; /* enable RS485 mode: */ rs485conf.flags |= SER_RS485_ENABLED; /* set logical level for RTS pin equal to 1 when sending: */ rs485conf.flags |= SER_RS485_RTS_ON_SEND; /* set logical level for RTS pin equal to 0 after sending: */ rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND); /* Set delays for RTS if needed */ rs485conf.delay_rts_before_send = 0; rs485conf.delay_rts_after_send = 0; /* Enable full-duplex mode if supported */ // rs485conf.flags |= SER_RS485_RX_DURING_TX; if (ioctl(fd, TIOCSRS485, &rs485conf) < 0) {        /* Error handling */ }

Python代碼          

port = serial.Serial(port="/dev/ttyLP6", baudrate=115200, timeout=2, write_timeout=2)port.rs485_mode = serial.rs485.RS485Settings()

shell 腳本,注意關(guān)閉回顯

stty -F /dev/ttyLP6 115200 cs8 -cstopb -parenb -echoecho "dddd" > /dev/ttyLP6

系統(tǒng)

從系統(tǒng)角度,我們也要知道一些基礎(chǔ)知識。

比如,串口設(shè)備名稱一般是 /dev/tty*。

通過命令 udevadm info 可以反查看該設(shè)備的硬件(設(shè)備樹)信息:

udevadm info /dev/tty* |grep DEVPATH=/devices/platform

輸出:

DEVPATH=/devices/platform/soc/107d001000.serial/tty/ttyAMA10

這樣我們可以知道,ttyAMA10 設(shè)備是芯片上的 107d001000 串口。

另外,我們可以通過系統(tǒng)啟動信息查看掛載的串口:

dmesg | grep -i fsl-lpuart

剛插入的設(shè)備不知道掛載在哪個/dev/tty* 目錄下,同樣可以通過上面的類似命令找到:

dmesg | grep -i tty

設(shè)備樹節(jié)點查看路徑:

/sys/firmware/devicetree/base/soc@xx/bus@xxx/serial@xxxx

腳本直接控制 IO:

gpioset gpiochip0 14=1 gpioset gpiochip0 14=0

這里面的 gpiochip0 和 14 也不是隨便選的,并且 chip 的選擇和我們常規(guī)的想法不同,具體可看  SDK 文檔說明。

設(shè)備樹編譯:

dtc -I dts -O dtb -o /path/to/your-device-tree.dtbo /path/to/your-device-tree.dts

總之,要在 Linux 環(huán)境中調(diào)試好串口驅(qū)動,遠(yuǎn)比 MCU 環(huán)境更復(fù)雜,需要掌握知識也更多。

聲明:本內(nèi)容為作者獨立觀點,不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 1
收藏 4
關(guān)注 160
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧