RS485 序列通訊

1. 簡介

EIA-485,也稱為 TIA/EIA-485 或 RS-485,是一種標準,定義了用於平衡數字多點系統中驅動器和接收器的電氣特性。 該標準廣泛用於工業自動化中的通訊,因為它可以在長距離和電氣噪聲環境中有效使用。

3. 核心中已有的資料結構

Linux 核心提供了 struct serial_rs485 來處理 RS485 通訊。 此資料結構用於設定和配置平臺數據和 ioctl 中的 RS485 引數。

裝置樹還可以提供 RS485 啟動時間引數 [1]。 當驅動程式呼叫 uart_get_rs485_mode() 時,序列核心會從裝置樹提供的值填充 struct serial_rs485

任何能夠同時作為 RS232 和 RS485 工作的裝置的驅動程式都應實現 rs485_config 回撥並在 struct uart_port 中提供 rs485_supported。 序列核心呼叫 rs485_config 來執行裝置特定部分,以響應 TIOCSRS485 ioctl(見下文)。 rs485_config 回撥接收指向已清除的 struct serial_rs485 的指標。 在使用 rs485_supported 呼叫 rs485_config 之前,會清除使用者空間提供的 struct serial_rs485rs485_supported 指示驅動程式對 struct uart_port 支援哪些 RS485 功能。 TIOCGRS485 ioctl 可用於讀取與當前配置匹配的 struct serial_rs485

struct serial_rs485

用於控制 RS485 設定的序列介面。

定義:

struct serial_rs485 {
    __u32 flags;
#define SER_RS485_ENABLED               _BITUL(0);
#define SER_RS485_RTS_ON_SEND           _BITUL(1);
#define SER_RS485_RTS_AFTER_SEND        _BITUL(2);
#define SER_RS485_RX_DURING_TX          _BITUL(4);
#define SER_RS485_TERMINATE_BUS         _BITUL(5);
#define SER_RS485_ADDRB                 _BITUL(6);
#define SER_RS485_ADDR_RECV             _BITUL(7);
#define SER_RS485_ADDR_DEST             _BITUL(8);
#define SER_RS485_MODE_RS422            _BITUL(9);
    __u32 delay_rts_before_send;
    __u32 delay_rts_after_send;
    union {
        __u32 padding[5];
        struct {
            __u8 addr_recv;
            __u8 addr_dest;
            __u8 padding0[2];
            __u32 padding1[4];
        };
    };
};

成員

flags

RS485 功能標誌。

delay_rts_before_send

傳送前延遲(毫秒)。

delay_rts_after_send

傳送後延遲(毫秒)。

{unnamed_union}

anonymous

padding

已棄用,請改用 padding0padding1。 請勿與 addr_recvaddr_dest 一起使用(由於重疊)。

{unnamed_struct}

anonymous

addr_recv

RS485 定址模式的接收過濾器(僅當設定了 SER_RS485_ADDR_RECV 時使用)。

addr_dest

RS485 定址模式的目標地址(僅當設定了 SER_RS485_ADDR_DEST 時使用)。

padding0

填充(設定為零)。

padding1

填充(設定為零)。

描述

用於控制具有合適支援的晶片上的 RS485 設定的序列介面。 如果您的平臺支援,請使用 TIOCSRS485 進行設定,並使用 TIOCGRS485 進行獲取。 設定函式返回新狀態,所有不支援的位都會適當恢復。

標誌位是

  • SER_RS485_ENABLED - 啟用 RS485。

  • SER_RS485_RTS_ON_SEND - 傳送時 RTS 引腳的邏輯電平。

  • SER_RS485_RTS_AFTER_SEND - 傳送後 RTS 引腳的邏輯電平。

  • SER_RS485_RX_DURING_TX - 全雙工 RS485 線路。

  • SER_RS485_TERMINATE_BUS - 啟用匯流排端接(如果支援)。

  • SER_RS485_ADDRB - 啟用 RS485 定址模式。

  • SER_RS485_ADDR_RECV - 啟用接收地址過濾器(啟用 addr_recv)。 需要 SER_RS485_ADDRB

  • SER_RS485_ADDR_DEST - 目標地址(啟用 addr_dest)。 需要 SER_RS485_ADDRB

  • SER_RS485_MODE_RS422 - 啟用 RS422。 需要 SER_RS485_ENABLED

4. 從使用者級別使用

從使用者級別,可以使用之前的 ioctl 獲取/設定 RS485 配置。 例如,要設定 RS485,您可以使用以下程式碼

#include <linux/serial.h>

/* Include definition for RS485 ioctls: TIOCGRS485 and TIOCSRS485 */
#include <sys/ioctl.h>

/* Open your specific device (e.g., /dev/mydevice): */
int fd = open ("/dev/mydevice", O_RDWR);
if (fd < 0) {
        /* Error handling. See errno. */
}

struct serial_rs485 rs485conf;

/* 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;
/* or, set logical level for RTS pin equal to 0 when sending: */
rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);

/* Set logical level for RTS pin equal to 1 after sending: */
rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
/* or, set logical level for RTS pin equal to 0 after sending: */
rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);

/* Set rts delay before send, if needed: */
rs485conf.delay_rts_before_send = ...;

/* Set rts delay after send, if needed: */
rs485conf.delay_rts_after_send = ...;

/* Set this flag if you want to receive data even while sending data */
rs485conf.flags |= SER_RS485_RX_DURING_TX;

if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
        /* Error handling. See errno. */
}

/* Use read() and write() syscalls here... */

/* Close the device when finished: */
if (close (fd) < 0) {
        /* Error handling. See errno. */
}

5. 多點定址

Linux 核心為多點 RS-485 序列通訊線路提供定址模式。 定址模式透過 struct serial_rs485 中的 SER_RS485_ADDRB 標誌啟用。 struct serial_rs485 具有兩個額外的標誌和欄位,用於啟用接收和目標地址。

地址模式標誌
  • SER_RS485_ADDRB: 啟用定址模式(也在 termios 中設定 ADDRB)。

  • SER_RS485_ADDR_RECV: 啟用接收(過濾)地址。

  • SER_RS485_ADDR_DEST: 設定目標地址。

地址欄位(使用相應的 SER_RS485_ADDR_* 標誌啟用)
  • addr_recv: 接收地址。

  • addr_dest: 目標地址。

設定接收地址後,通訊只能與特定裝置進行,並且其他對等方將被過濾掉。 過濾由接收方強制執行。 如果未設定 SER_RS485_ADDR_RECV,則將清除接收地址。

注意:並非所有支援 RS485 的裝置都支援多點定址。

6. 參考