# 通訊傳輸協定 ## 概述 ### 1. 串列與並列通訊 並列通訊指的是匯流排有多根數據線,訊號可以一次性的透過匯流排上的多根數據線傳遞。串列通訊中匯流排只有一根數據線,每次只能通過這跟數據線傳送一個電位訊號。  並列通訊的速度通常比較快(一次傳送較多內容)但同時在佈線方面會比較困難,且每個數據線之間可能會有訊號干擾。嵌入式系統中比較常用串列通訊。 ### 2. 單工與雙工 依照數據傳送的方向可以分為 * 單工(simplex) * 雙工(duplex) 單工通訊只能有發送方(transmiter)傳送給接收方(receiver),每個硬體零件只能擔任一種角色。 <img src="https://hackmd.io/_uploads/BkLxILi-eg.png" width=400> 雙工通訊中每個設備可以同時作為發送方與接收方,可以從設備 A 傳送訊息至設備 B,也可反過來從設備 B 傳送訊息給設備 A。 雙工通訊又分為半雙工(half-duplex)與全雙工(full-duplex)。半雙工中,發送與接收訊息無法同時進行,每次只能進行一種模式。全雙工中發送與接收可以同時進行。  ### 3. 傳輸率 資料傳輸中有兩種常用的單位 * 位元率(bit rate) * 鮑率(baud rate) 位元率指的是每秒傳輸多少個位元。以 1000 bps 的傳輸速率來說,每秒傳送 1000 個 bit。 鮑率則是定義每秒傳輸的符號(symbol)數量,符號指的是不同電壓或訊號的相位變化。根據調變技術的不同,每個符號可以攜帶一位或多位資訊。以常見的電壓訊號來說,每個符號會攜帶一位元的資訊。 <img src="https://hackmd.io/_uploads/rJuaqLobel.png" width=300> 因此,以 baud rate = 1000 的傳輸速率為例,表示每秒可以傳輸 1000 個符號。 一般來說 bit rate $\ge$ baud rate。兩者的轉換關係式如下 : bit rate = baud rate $\times$ 每個符號攜帶的位元數資訊 > [!Note] > 電位傳輸中,每個符號攜帶一個位元資訊(1/0),因此 bit rate = baud rate。 ## UART ### 1. UART 簡介 通用非同步收發器(**U**niversal **A**synchronous **R**eceiver **T**ransmitter),簡稱 UART,是一種用於不同計算機之間通訊的協定 > [!Important] > UART 是一種通用的串列,非同步通訊匯流排,該匯流排總共有兩條數據線,可以實現全雙工的發送和接收訊息。通常用於主機與周邊裝置之間的通訊。一般如果沒有特別說明的串列通訊埠(serial port)指的都是 UART。 ### 3. UART 通訊協定 > [!Note] > UART 在傳送資料時是最低位元(bit-0)先傳送,所以從示意圖或示波器上看的時候需要反過來解讀(左側是最低位元) UART 通訊的過程有以下幾個重點 * 起始位元(start bit) * 資料內容(data frame) * 校正位元(check bit): 可有可無 * 停止位元(stop bit)  **(1) 閒置狀態與起始位元** UART 通訊協定規定在沒有傳送資料時的閒置(idle)狀態下,輸出高電位訊號。開始傳送資料前會先有一個低電位訊號的起始位元 **(2) 資料內容** UART 通訊協定在資料傳輸過程中從最低位元(LSB)開始依序傳輸到最高位元(MSB),且每個 data frame 可以選擇傳出 5 到 8 個 bits。(但習慣上是以 8 bits 為單位) **(3) 校正位元** 校正位元的用意是檢查數據傳輸的正確性,常見的校正方式有兩種 * 檢查和(check sum): 把傳輸資料相加後檢查總和 * 同位位元(parity bit): 又稱奇偶校正,檢查資料中 1 個個數是奇數個還是偶數個 * 如果同位位元 = 1,表示資料中的高電位訊號有奇數個 * 如果同位位元 = 0,表示資料中的高電位訊號有偶數個 校正位元不一定要使用,不使用的話傳輸速度為比較快。 **(4) 停止位元** 用來表示這筆 data frame 傳輸完成,是一個 1 到 2 個 bits 的高電位訊號。  以一個 0x5D 的資料傳輸,舉例如下  但如果有多個連續的相同訊號傳輸,區分這些相同連續訊號的方式是設定傳輸的 baud rate。因為 baud rate = 每秒傳送的符號數量,因此 baud rate 的倒數就是傳送每個符號的所需要的時間(又稱信號時間)。 所以在使用 UART 通訊傳輸時,發送方與接收方必須要設置相同的資料傳輸速率。 > [!Note] > UART 中的非同步傳輸,指的是不會共用一個時脈(clock)訊號,而是設定相同的資料傳輸速率,並依靠 start bit 來取樣對時,確保 data frame 在誤差範圍內正確取樣。 ### 4. UART 硬體接線 UART 屬於全雙工模式,兩個設備的發送端(Tx)與接收斷(Rx)要交叉連接,且兩邊需要共地。 <img src="https://hackmd.io/_uploads/SJqfx_jZgg.png" width=400> ## 電氣位準: TTL/RS232/RS485 ### 1. TTL 電晶體 - 電晶體邏輯(**T**ransistor **T**ransistor **L**ogic, TTL)是一種電路類型,早期電路設計多使用這種,現今與之相對的 CMOS 電路。TTL 的電壓標準定義 2V - 5V 為高電位(邏輯1),0V ~ 0.8V 為低電位(邏輯0)。現今的 IC 設計幾乎沒有使用 TTL 設計,都是採用 C-MOS 或 N-MOS 設計。只是因為歷史因素與習慣使然,所以現今的 MCU/SoC 還是會稱 5V/0V 這種電位標準為 TTL。 > [!Note] > TTL 現今有兩種意義 > 1. 一種早期的電路類型 > 2. 電位標準 像 UART 這種通訊協定,只是規定傳輸/接收的資料要如何去做解讀,並沒有規定要怎麼去做傳輸,所以可以使用不同的電位標準標準(TTL/RS232/RS485)進行資料傳輸。 ##### 參考 * [TTL介绍](#https://blog.csdn.net/guoqx/article/details/137612843) * [UART、TTL和RS232的区别](#https://blog.csdn.net/muxi_huang/article/details/106746825) * [電晶體-電晶體邏輯](#https://zh.wikipedia.org/zh-tw/%E9%9B%BB%E6%99%B6%E9%AB%94-%E9%9B%BB%E6%99%B6%E9%AB%94%E9%82%8F%E8%BC%AF) ### 2. RS232 協議 RS232 協議直接規定了標準的連接器,且規定了連接器上每個腳針的用途,不過一般只會使用 RX、TX 與 GND 這三條線。  (圖片來源: [TTL、RS232、485传输距离到底有多远?](https://www.eet-china.com/mp/a148560.html)) RS232 協議除了接線與接口外,也對訊號的傳輸型式做了規定 * 以 -5V ~ -15V 作為高電位(邏輯1) * 以 +5V ~ +15V 作為低電位(邏輯0) 這種設計可以增加傳輸過程的抗干擾能力,且傳輸距離也比較長(約 15 公尺左右) > [!Note] > UART 一般是採用 TTL 電位標準進行傳輸,使用 TTL 標準會有以下幾個問題 > > * 抗干擾能力插,傳輸過程易出錯 > * 通訊距離短,一般在 1 公尺以內 因為 UART 常用傳輸規定是 TTL 標準,如果要採用 RS232 協議的標準進行傳輸,則必須在傳輸後/接收前加上一個轉換裝置(通常是一個 IC 裝置),Ex. MAX232 EPE <img src="https://hackmd.io/_uploads/BklDAXiKGgx.png" width=500> 但 RS232 也有一些問題 : * 接後的電位訊號比較高,容易損壞電路晶片 * 與 TTL 電位不兼容,需要依靠轉換器 * 通訊速度低共模干擾 * 傳輸距離不夠長 > [!Note] > RS232 只是在傳輸訊號上做了增強,與軟體(程式碼)上的實作無關 ### 3. RS485 協議 與 RS2323 協議類似,特點是 RS485 協議可以允許連接多個收發器(Ex. 一個伺服器主機與多個客戶端主機),反之 TTL/RS232 都是點對點的通訊,而 RS485 可以形成一個網路。 訊號方面,RS485 採用的是差分訊號進行資料傳輸,使用兩根電線來表示一個位元,假設一根電線 H 另一根電線是 L,則兩根電線之間的電位差為 d = H - L * 若電位差 d 的範圍介在 +2V ~ +6V 則表示高電位(邏輯1) * 若電位差 d 的範圍介在 -2V ~ -6V 則表示低電位(邏輯0)  此外兩個電線是纏繞在一起的雙絞線設計,這種設計搭配差分訊號可以抵抗干擾,因為在受到干擾時,兩根電線的電壓會同時上升或下降,電線之間的電位差值不會受到影響 因為 RS485 是使用兩根電線表示一個位元的兩線設計,所以這兩根電線不能同時進行傳送與發送,也就是說 RS485 是半雙工的設計。在軟體方面程式碼要注意的是接收資料的時候不能傳輸資料,反之亦然。 UART 要使用 RS485 進行資料傳輸勢必也需要使用一個轉換器(Ex. MAX485) RS485 優點 * 接口的電位訊號較低,不容易損壞晶片 * 通訊速度快 * 抗干擾能力強 * 傳輸距離遠(約 1500 公尺) * 可實現多節點的網路系統  ##### 參考 * [串口(UART/COM/TTL/RS232/RS485)](https://blog.csdn.net/ARM_qiao/article/details/125103127) * [SPI、UART、RS232、RS485、IIC 5种嵌入式经典通信总线协议精讲](https://www.bilibili.com/video/BV1SK4y1X7jp?spm_id_from=333.788.videopod.episodes&vd_source=013aadbea8bdf3cae80ef10a80420d71&p=6) ## I2C/IIC I2C(Inter-Integrated Circuit)通訊是 Philips 在 80 年代推出的一種串列、半雙工的通訊協議,主要用於近距離且低速的晶片之間的通訊。 I2C 總共有兩根雙向的訊號線,一根是數據線(serial data, SDA),用於傳輸/接收資料,另一根是時脈線(serial clock, SCL),用於通訊雙方時脈的同步。 I2C 是一種多主機的設計,連接在 I2C 匯流排上的裝置可分為主機(master)與從機(slave),主機可以開啟和結束通訊,但從機只能被主機呼叫。此外,因為 I2C 協議允許多個裝置,因此連接在匯流排上的裝置都會有一個唯一的地址(7-bit),也因為 I2C 的匯流排上會有多個主機,所以 I2C 協定會有衝突檢測,防止當多個主機同時使用匯流排。  ### 1. 通訊過程 I2C 的大略通訊過程如下 : 1. 主機發送起始訊號並啟用匯流排(透過 SDA 線) * 此時匯流排上的所有裝置都能收到此訊號,並知道有某個主機準備開始發送訊息 * 因此其他的主機不能發送訊號,因為匯流排被佔據了 2. 主機發送一個 byte 的數據指出欲通訊的從機的位址(7 bit)與後續資料的傳輸方向(1 bit)(見下圖) * bit 1 到 bit 7 決定從機位址 * bit 0 表示傳輸方向 * 0 : 寫入資料,方向為主機到從機 * 1 : 讀取資料,方向為從機到主機 * 匯流排上的所有從機都會收到訊號,並透過 bit 1 到 bit 7 判斷自己是不是被呼叫裝置 3. 被呼叫的從機接收到訊號後,回傳一個回應訊號(ACK)給主機 4. 發送器發送一個 byte 的資料給接收器 * 這邊沒有規定發送/接收的是主機還是從機 * 因為不論是主機或從機都有可能擔任發送方或接收方 * 依據前面所說 bit 0 的資料傳輸方向決定誰是接收/發送 5. 接收器回應一個訊號(A)給發送器 * 這邊沒有規定發送/接收的是主機還是從機 * 因為不論是主機或從機都有可能擔任發送方或接收方 * 依據前面所說 bit 0 的資料傳輸方向決定誰是接收/發送 重複循環 4. 與 5. 步驟,直到主機發送停止訊號。  (圖片來源: [2C Primer: What is I2C? (Part 1)](https://www.google.com/search?sxsrf=AE3TifNct9rd7A95l4EL9KAzsRa-Khjp8A:1748786826823&q=i2c&udm=2#vhid=gmX2OP1MDCSENM&vssid=mosaic)) ### 2. I2C 傳輸協定 #### 2.1 起始訊號與停止訊號 I2C 的 SDA 與 SCL 兩根電線在閒置狀態下都是保持高電位 * 當 SCL 為高電位,且 SDA 由高轉低表示起始訊號(S) * 當 SCL 為高電位,且 SDA 由低轉高表示停止訊號\(P) > [!Note] > 不論是起始訊號或結束訊號都是由主機發出,起始訊號發出後代表總線處於忙碌狀態度,無法讓其他主機發送訊號。  (圖片來源: [2C Primer: What is I2C? (Part 1)](https://www.google.com/search?sxsrf=AE3TifNct9rd7A95l4EL9KAzsRa-Khjp8A:1748786826823&q=i2c&udm=2#vhid=gmX2OP1MDCSENM&vssid=mosaic)) #### 2.2 資料傳輸與回應 I2C 資料傳輸時每次傳輸一個 byte,過程中會先傳送最高位,再傳送最低位。發送器每傳送完一個 byte 的資料後接收器必須發送 1-bit 的回應訊息,且回應訊息是低電位,兩者結合在一起就是 9-bit 的資料。 直到所有資料傳輸完畢後再由主機發送一個結束訊號。 > [!Note] > 回顧 UART 的傳輸過程,每次傳輸的資料不一定是 8-bit 的長度。 #### 2.3 同步訊號 在訊號傳輸的過程,接收方會面臨到 2 個問題 : * 何時知道發送器開始傳送訊息 ? * 如何判斷一個位元的長度(Ex. 分辨 10 訊號與 1100 訊號) > [!Note] > 以 UART 來說,第一個問題是透過發送一個起始訊號解決,第二個問題透過傳輸率(baud rate)解決 對於 I2C 來說,第一個問題一樣可以透過起始訊號解決。第二個問題是透過連接兩個裝置的時脈線(SCL)解決。SCL 可以保證接收方與發送方兩者間的時脈訊號一致。在 I2C 協議透過 SDA 線進行通訊時 : * SCL 在低電位期間,發送器向 SDA 發送 1-bit 的資料 * 在此期間允許 SDA 線上的訊號發生改變 * SCL 在高電位期間,接收器從 SDA 讀取 1-bit 的資料 * 在此期間不允許 SDA 線上的訊號發生改變,必須保持穩定 因為有 SCK 保持兩者傳輸與接收訊息的時間基準,所以 I2C 可以不受限的傳輸任意長度(以 byte 為單位)的資料,不像 UART 只能傳送固定長度的資料,避免資料傳輸造成的時間誤差。 > [!Note] > I2C 與 UART 傳輸資料時其實都是以 byte 為單位,差別在於 UART 傳輸一個 byte 的資料後必須跟著一個結束訊號,但 I2C 可以連續不間斷的傳輸,直到資料傳輸完畢才發送結束訊號,因此才會說 I2C 的資料長度不受限制。  #### 2.4 傳輸實例 I2C 的傳輸過程可以分為三種 * 主機向從機連續寫入數據 * 從機向主機連續讀取數據 * 主機向從機寫入,從機再向主機讀取 以第 3 種來說,因為 I2C 在傳輸過程必須保持資料傳輸方向的一致性,因此當主機向從機寫完數據且下一次從機開始讀取資料前,主機必須再次發送一個起始訊號,才能變更資料傳輸的方向,保持 I2C 的訊號一致。 但特別的是,在轉換資料的過程中,主機其實不需要發送結束訊號\(P),可以直接開始起始訊號(S)並接著發出從機位址與讀寫訊號(AD+R)。因為一旦在中間發送了結束訊號,代表這次的通訊結束,那麼匯流排可能就會被其他的主機與從機佔據。  ## SPI ### 1. SPI 概述 串列週邊介面(**S**erial **P**eripheral **I**nterface, SPI)是一種: (1)高速(相較 UART 與 I2C 而言) (2) 全雙工 (3) 同步的串列通訊傳輸方式。SPI 與 I2C 類似,都是採用主從(master-slave)機制,通常會有一個主機與多個從機。  SPI 通訊時至少需要 4 根線(從機越多線越多): * SCLK : 用於提供主從雙方統一時脈 * MOSI: 主機輸出從機輸入(Master Output Slave Input) * MISO: 主機輸入從機輸出(Master Input Slave Output) * CS/SS: 用於定址(chep select) 因為 SPI 可以有一台主機對應多個從機,因此它的最後一根引線(SS/CS)用作定址,用來選擇主機現在要跟哪一個從機開始做通訊。 在 SPI 開始傳輸前,主機會透過 CS/SS 線發送一個訊號用來選擇現在要使用哪一個從機進行傳輸。這個訊號有可能是高電位或低電位,具體要根據從機而定,有些從機使用高電位認定,有些則使用低電位。如果是 $\text{SS}$ 則表示從機使用高電位定址,如果是 $\overline{\text{SS}}$ 則表示該從機使用低電位定址。 <img src="https://hackmd.io/_uploads/HJEhvbpmxg.png" width=350> ### 2. 通訊過程 SPI 傳送資料時會先傳送最高有效位元(MSB)再傳送最低有效位元(LSB),這點與 I2C 相同但與 UART 不同。 與 I2C 不同的是 : * SPI 沒有起始訊號與結束訊號 * SPI 每傳送完一個 byte 的資料後,不用等待對方的回覆訊息(ACK)就可以直接傳送下一個 byte 的資料 SPI 採用同步方式進行傳輸,需要有一個時脈協調主從雙方的傳送與接收。 * 每一個時脈的正緣/負緣,發送方(transmitter)向數據線發送數據 * 同時脈後面的負緣/正緣,接收方(receiver)從數據線讀取數據 簡單來說,在每一個時脈的第一個邊緣會進行發送/讀取,下一個邊緣會進行讀取/發送,因此一個 byte 的資料只要 8 個時脈就可以傳輸完成。 ### 3. 相位與極性 SPI 協定總共有 4 種工作模式(mode 0/1/2/3),取決於它的急極性(CPOL)與相位(CPHL)。 * 極性表示閒置期間的時脈狀態 * CPOL = 0 表示閒置期間 SCLK 為低電位 * CPOL = 1 表示閒置期間 SCLK 為高電位 * 相位表示採樣數據的時間點 * CPHA = 0 表示每個週期的第 1 個邊緣採樣(第 2 個邊緣傳輸) * CPHA = 1 表示每個週期的第 2 個邊緣採樣(第 1 個邊緣傳輸) 對 SPI 來說極性跟相位是可以改變的,但 I2C 的極性跟相位是固定的。但一般在進行 SPI 傳輸時工作模式並不是任意選擇,而是要根據從機的設計選擇對應的模式,從機要使用哪一種模式可以查閱它的 data sheet 或 user manual,主機可以透過設定暫存器來選擇要使用對應從機的模式。 > [!Note] > * 採樣(sample)指的是從數據線上讀取位元資料 > * 傳輸(shift)指的是把資料從暫存器送到數據線上 #### 3.1 SPI 模式對照表(SPI Mode Table) | SPI 模式 | CPOL | CPHA | 閒置狀態下的時鐘極性 | 用來取樣與/或傳輸資料的時鐘相位 | |:-:|:-:|:-:|:-:|:-:| | 0 | 0 | 0 | 低電位(Logic low) | 上升緣取樣、下降緣傳輸 | | 1 | 0 | 1 | 低電位(Logic low) | 下降緣取樣、上升緣傳輸 | | 2 | 1 | 0 | 高電位(Logic high) | 下降緣取樣、上升緣傳輸 | | 3 | 1 | 1 | 高電位(Logic high) | 上升緣取樣、下降緣傳輸 | #### 3.2 SPI 傳輸模式(圖示)     (圖片來源: [Introduction to SPI Interface](https://www.analog.com/en/resources/analog-dialogue/articles/introduction-to-spi-interface.html)) > [!Warning] > Q: 在 mdoe 0 與 mode 2 有個會讓人疑惑的點。在 mode 0 與 mode 2 的時候都會在第 1 個邊緣就採樣,但理論上在這之前並沒有資料傳輸,那又要如何採樣(讀取)資料 ? > > A: 實際上在這兩種模式下,在時脈第一次開始震動之前資料就會被傳輸到數據線之上,一旦開始震度產生第 1 個邊緣,對方就會開始採樣。 #### 4. 與 I2C 比較 * 相同點 * 都是串列與同步傳輸 * 都採用 TTL 電位標準,傳輸距離和場景類似 * 都採用主從模式 * 相異點 * I2C 為半雙工,SPI 為全雙工 * I2C 有回應機制,SPI 沒有 * I2C 需要先通過匯流排向從機發送位址(所以時間較慢但佈線簡單),SPI 直接使用 C/S 線決定從機(所以速度較快但佈線複雜) * I2C 的相位和極性固定,SPI 可以選擇
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up