帶你認識物聯網基礎 Serial 通訊(二)-- UART 篇

更新於 發佈於 閱讀時間約 11 分鐘

Serial Communication

在上一篇文章帶你認識物聯網基礎 Serial 通訊(ㄧ)裡面,我們站在上層視角來看 Serial 通訊數據必須先在 UART 元件把 Parallel 轉成 Serial,EIA Driver 會把 Serial 轉成特定的 Serial 訊號。UART 數據轉換要考慮兩個關鍵點,如何讓資料從直行變橫列(躺平)的方法,還要考慮如何控制 Serial 訊號輸出。這次我們要深入看一下這兩部分的細節。不囉嗦,開始吧。

Buffer 區是資料躺平的關鍵

UART 的全名是 Universal Asynchronize Receiver/Transmitter 中文翻成「通用非同步收發傳輸器」,從名稱實在很難聯想到跟它就是 Serial 通訊運作核心。

高速公路與隧道

先稍微打住,關於Parallel 與 Serial 的概念在生活中我覺得有一個蠻不錯的例子可以類比,就是高速公路與隧道。

都會區的高速公路單向可達五線道以上,可以讓五個駕駛人同時在各自的車道上等速併排行駛,這就是 Parallel (並排)的概念;隧道設計跟高速公路不一樣車道數較少,想要穿過隧道的五台車子就必須在進隧道前「想辦法」變成一列才能安全通過。讓並行變成一前一後排列就是 Parallel 轉 Serial 的概念。

分段處理、先進先出(FIFO)

回到電腦這邊,電腦資料不具備駕駛人可以互相協調變成一列的能力,「想辦法」讓並排的資料變成一列就交給專門的 UART 來負責,實現的方式是分段處理、先進先出。它會把來源的 Parallel 資料蒐集到自己的暫存區內按照先進先出(FIFO,First In First Out)的原則進行管理,重複著每次從暫存區提取一筆 Parallel 資料進行 Serial 的訊號轉換的動作。

數據轉換流水線

假設來源來源的 Parallel 匯流排(data bus)上有 8 個數據通道好了,資料傳輸的時候每次都會有 8 個數據訊號會同時抵達 UART 這邊, 它會將數據安排到第一個暫存區 THR (Transmit Hold Register) 資料在這裡排隊等待,THR 大小多少不固定要看產品規格,以現在的例子至少要 1 byte。當 UART 發現 THR 有資料要處理,排在 THR 最前面(最早進來)的資料就會被提取出來到下一個暫存區 TSR (Transmit Shift Register) 進行轉換,在 TSR 完成轉換的 Serial 訊號就可以準備從 TX 出口離開了,一站接著一站就像流水線一般。資料發送的過程大概這樣:

Data Bus → Transmitter FIFO (THR) → Transmit Shift Register (TSR) → Serial
Parallel 2 Serial

Parallel 2 Serial

資料接收的過程就是把上面的箭頭全部反過來,Transmit 變成 Receive 就像這樣

Serial → Receive Shift Register (BSR) → Receiver FIFO (BHR) → Data Bus

Serial 2 Parallel

Serial 2 Parallel

單工、半雙工、全雙工

對 UART 來說通訊只要一組兩條線,要發送的資料走 TX,要接收的資料就走 RX。一組傳輸線按照傳輸的行為可以進一步區分單工(Simplex),半雙工(Half-Duplex) 。

一組傳輸線就像一條車道,單工像是我們的單行道,規定資料往一個方向移動,例如只送不收。如果允許把收跟送的時間分開互相等待,同一組線路 (RX/TX) 就能做到半雙工(half-duplex),就是單線道可以雙向通車,例如 RS232/RS485 基本都是半雙工。

有半雙工就有全雙工(Full-Duplex),只要再多提供一組訊號線就可以了,有兩組 RX TX 的 4 線 RS485 就是一個經典範例。

通訊參數 9600, N, 8, 1

通訊參數的一致性是發送與接收兩端能否成功通訊的關鍵。通訊參數代表成功通訊的前提條件跟我們說話類似,例如: 兩個人溝通需要用共通的語言、語法規則、聲量、語速等等都要考慮進來... 同樣的,電腦間通訊也是如此,要用多快的速度傳遞訊息,要如何打包訊息封包,都要通訊前先設定好通訊參數。

通訊速率 Baud Rate

通訊速率叫做 Baud (鮑) 也叫做 Baud Rate,定義是一秒鐘可以傳送或接收多少個符號,相當於我們說話的速度。二進位的電腦能用的符號只有兩個 0 (低電位) or 1 (高電位)

Baud Rate 9600 就是每秒可以傳送或接收 9600 個 0 or 1

可以計算出來傳送或接收 1 bit 的資料所需的時間是 1/9600 = 0.10417ms。

目前 Baud Rate 的設定從 50 到 921600 都有,理論上 Baud Rate 數值越高,傳輸資料時間越短(難度越高),能傳輸的資料數量也更多(相當於頻寬增加了)。實際應用要設定多少 Baud Rate 還是要看於設備的規格,我以前比較常碰到的 Baud Rate 大概就是 9600, 19200, 38400 跟 115200 這幾種。

試想一下,如果兩邊 Baud Rate 設定不一樣會發生甚麼情形? 假設傳送端的 Baud Rate 設定是 19200 ,接收端設定是 9600 ,每隔 0.05208ms 就有一個 bit 資料傳過來,接收端每隔 0.10417ms 才會讀取一次,讀取速度比傳送速度慢了一倍,結果是接收端只會收到奇數 bit 或偶數 bit,組合起來就會變成沒有意義的亂碼。

資料封包 Frame

決定好通訊速率還要決定資料封包 Frame。資料封包有四個要素,按照順序分別起始位元 (Start bit) 、資料位元個數(Data bits)、校驗位元(Parity bit) 以及停止位元(Stop bit)。

Serial Frame

Serial Frame

起始位元 Start bit

起始位元固定是 1 個 bit,排在資料封包的最前面。UART 的通訊設計是高電位 1 低電位 0,平常待機都是維持在高電位的狀態,看起來就是 1111111111….,用示波器來看就是沒有變化的一直線。

起始位元的目的是用一個 bit 的時間要告訴接收端”後面有資料來了”,具體做法是它會拉低 1 bit (低電位) 的時間,當接收端偵測到就知道要開始收資料了。

資料位元 Data bits

接下來是資料位元個數也要預先設定在通訊參數裡面,要傳送的資料放在這邊。以現在例子就是 8。接收端確認到起始位元後,就開始連續讀取 8 個的資料位元。資料位元數可以設定的數值包含 5, 6, 7, 8,不同的數值會影響封包大小跟傳輸時間。

校驗位元 Parity bit

再來是校驗位元是用來檢查資料內容的正確性的,原理是看資料位元裡面總共有多少個 1,可以設定為 Odd (奇同位) 或是 Even (偶同位)或是 None (不需要)。比如上面的 110010100,資料位元裡面有 4 個 1,如果此時我們的通訊參數是 Even,那麼傳送端就會把這校驗位元設為 0 (資料位元加上校驗位元合計已經有偶數個 1 了)。

如果同樣資料通訊參數現在設成 Odd,傳送端必須把校驗位元設定為 1,這樣就有 5 個 1 可以滿足奇數個 1 的要求。校驗位元只要資料位元有超過 1 個 bit 的數值異常就檢測不出來了實用性不高。實務上都設定 None。設定 None 還有個好處,可以讓資料位元長度增加到 9 bits。

結束位元 Stop bit

封包的最後是 Stop bit,有點像無線電對談的時候結束要說 Over 一樣,告訴接收端封包已經送完了,可以設定 1, 1.5, 2 bits 的時間長度。那麼傳送一個 byte 需要多少時間呢? 按照 9600, N, 8, 1 的設定,答案是 1.0417ms,因為 9600 的每個 bit 需要 0.10417ms,一個封包總共有 10 bit (= 1 Start bit + 8 Data bits + 1 Stop bit) 。

Timeout

說到傳輸時間了,不妨也注意一下 timeout 或者叫做延遲時間 Latency,它是用來判斷通訊是否中斷停止的依據,預設長度是 4 bytes,要用 Frame 大小計算大約就是 4ms,只要通訊中發生中斷超過 4ms 就會被認為超時 timeout,就可以決定要停止傳送或重送,寫 code 的時候就可以有明確的 delay 時間。

流量控制 RTS/CTS

通常我們要傳遞的資料不會只有一個封包這麼小,而是會切成很多個封包不斷往通訊線裡面送,如此就產生了資料流,忙碌的時候就是整條馬路都是車的感覺。

CPU 很忙

每個封包之間的時間差不同,CPU 也會有來不及處理資料封包的時候,此時資料就會先放在暫存區裡面,如果資料又一直進來,CPU 還是沒空處理,那麼暫存區就會有擠爆的錯誤(overrun) 發生。所以除了傳送資料的 RX/TX ,還會多加兩條 RTS/CTS 來做流量控制。

看訊號辦事

RTS 全名叫做 Request To Send,CTS 是 Clear to send 都是接收端跟發送端用來控制資料流量的 flag。接收端為了避免暫存區爆掉會在暫存區水位設定一個閥值,比如說 80%。只要資料水位在 80% 以下,就讓傳送端持續把資料送過來,一但發現資料水位超過 80%,就必須通知傳送端先暫停傳輸。

具體的用法是,把接收端跟傳送端的 RTS/CTS 對接。傳送端有資料要送的時候,會先把自己的 RTS 拉起來通知接收端,等接收端回應自己收到 CTS (接收端的 RTS 也打開了)就可以開始把資料傳出去。接收端會持續收資料並監看自己的暫存區資料水位,一旦超過閥值就觸發保護機制,接收端會把自己的 RTS 關掉,發送端看到自己的 CTS 關掉,就知道該停下來了。

RTS to CTS

RTS to CTS

小結論

以上就是這次要跟大家分享的 Serial 通訊 - UART 的部分。我們只要記得 UART 元件的職責就是負責 Parallel 轉成 Serial 的資料就好,畢竟轉換電路都已經被廠商封裝到 chip 裡面了,看不到也摸不著。但是通訊參數設定跟流量控制的概念對於系統整合應用的人來就很重要,設定錯誤的通訊參數會讓你的通訊失敗,不了解也會讓你寫的 code 效率折扣或者很不穩定。

接下來,我們就要準備進入 Serial 通訊的最後一趴,聊聊 EIA Driver,看看 TTL 是怎麼轉成 RS232/RS485 這些實體介面,以及他們是怎麼運作的。敬請期待。

avatar-img
16會員
61內容數
WarrenLo's 軟體設計武功祕笈
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Warren Lo的沙龍 的其他內容
聊到 Serial 通訊就一定會提到 COM Port,它是微軟定義的一個經典 Serial 通訊實作。COM Port 在筆電還不普及的年代可以很輕鬆在 PC(桌機)的主機板上找到有標示 COM1 或者 COM2 的通訊接口,這些就是最常見的 COM Port 通常搭載的都是 R232 的通訊規格
問題來了,如果在一組 Master-Slave 在通訊過程中出現其他的裝置「插嘴」的狀況會怎麼樣?因為迴路只有一條,所以只要在同一個通訊迴路上同時有兩台裝置發出訊號,結果就是兩個資料封包互相對撞雙雙損毀…
物聯網裝置跟電腦一樣處理資料過程仰賴記憶體,不同類型的資料必須放在不同的記憶體空間。RD 會按照功能需求去規劃這些數據儲存空間,就像設計師規劃客廳、廚房、衛浴與臥室等居住空間一樣。各個空間的規劃原則上不會允許重疊,如此才能確保不同資料間不會發生互相覆蓋導致記憶體錯誤發生。
Modbus 是比 Ethernet 更簡單的通訊架構,走的是 Master-Slave 模式。協議規定 Slave 裝置們都不可以主動回應,所以 Slave 們在通訊過程中遇到看不懂的、壞掉的資料封包,能做的處理方式就是直接丟掉,從外面看 Slave 裝置的行為就跟「已讀不回」一樣毫無反應
當 Modbus 通訊模式可以選 RTU 或 ASCII 這兩種傳輸模式,不過因為兩者的運作機制不一樣,所以通訊時只能選擇其中一種來使用且傳輸端與接收端都必須使用相同的傳輸模式,才不會發生數據解讀錯誤變成一堆亂碼、兩邊雞同鴨講的狀況。關於這兩種傳輸模式的差異之處,主要有三點
我們在上一篇文章聊到了測試左移所需的 8 大能力中的前面 4 個,包含學習研究、反應回饋、作戰計畫、追溯管理的能力,這四個能力也是我們平常工作與生活上遇到困難時的解決問題的核心能力,建議還沒看過第一篇的朋友,可以先回第一篇了解一下。那麼接下來我們要就繼續聊聊測試左移的另外四個能力。
聊到 Serial 通訊就一定會提到 COM Port,它是微軟定義的一個經典 Serial 通訊實作。COM Port 在筆電還不普及的年代可以很輕鬆在 PC(桌機)的主機板上找到有標示 COM1 或者 COM2 的通訊接口,這些就是最常見的 COM Port 通常搭載的都是 R232 的通訊規格
問題來了,如果在一組 Master-Slave 在通訊過程中出現其他的裝置「插嘴」的狀況會怎麼樣?因為迴路只有一條,所以只要在同一個通訊迴路上同時有兩台裝置發出訊號,結果就是兩個資料封包互相對撞雙雙損毀…
物聯網裝置跟電腦一樣處理資料過程仰賴記憶體,不同類型的資料必須放在不同的記憶體空間。RD 會按照功能需求去規劃這些數據儲存空間,就像設計師規劃客廳、廚房、衛浴與臥室等居住空間一樣。各個空間的規劃原則上不會允許重疊,如此才能確保不同資料間不會發生互相覆蓋導致記憶體錯誤發生。
Modbus 是比 Ethernet 更簡單的通訊架構,走的是 Master-Slave 模式。協議規定 Slave 裝置們都不可以主動回應,所以 Slave 們在通訊過程中遇到看不懂的、壞掉的資料封包,能做的處理方式就是直接丟掉,從外面看 Slave 裝置的行為就跟「已讀不回」一樣毫無反應
當 Modbus 通訊模式可以選 RTU 或 ASCII 這兩種傳輸模式,不過因為兩者的運作機制不一樣,所以通訊時只能選擇其中一種來使用且傳輸端與接收端都必須使用相同的傳輸模式,才不會發生數據解讀錯誤變成一堆亂碼、兩邊雞同鴨講的狀況。關於這兩種傳輸模式的差異之處,主要有三點
我們在上一篇文章聊到了測試左移所需的 8 大能力中的前面 4 個,包含學習研究、反應回饋、作戰計畫、追溯管理的能力,這四個能力也是我們平常工作與生活上遇到困難時的解決問題的核心能力,建議還沒看過第一篇的朋友,可以先回第一篇了解一下。那麼接下來我們要就繼續聊聊測試左移的另外四個能力。
你可能也想看
Google News 追蹤
Thumbnail
大家好,我是woody,是一名料理創作者,非常努力地在嘗試將複雜的料理簡單化,讓大家也可以體驗到料理的樂趣而我也非常享受料理的過程,今天想跟大家聊聊,除了料理本身,料理創作背後的成本。
Thumbnail
哈囉~很久沒跟各位自我介紹一下了~ 大家好~我是爺恩 我是一名圖文插畫家,有追蹤我一段時間的應該有發現爺恩這個品牌經營了好像.....快五年了(汗)時間過得真快!隨著時間過去,創作這件事好像變得更忙碌了,也很開心跟很多厲害的創作者以及廠商互相合作幫忙,還有最重要的是大家的支持與陪伴🥹。  
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
題目敘述: 給定一個二維陣列的高與寬,並且給定起點位置座標。 請從起點位置開始順時針拜訪陣列元素,並且把沿路走過的座標記錄下來。 以陣列的形式返回答案。
Thumbnail
※ 什麼是路由? 當我們說「路由」時,可能是在談論路由器(實體設備),也可能是在談論路由(選擇路徑的過程),或者是在談論路徑(資料封包的傳輸路徑)。 路由器 (Router):這是一種實體設備,負責將資料封包 (Packet) 從一個網路傳送到另一個網路。它的工作方式類似於交通指揮,確保資料封包
Thumbnail
這篇文章介紹了路由器 (Router) 在網絡硬體中的功能與運作概念,包括路由器的工作原理、運作流程和與其他硬體設備的區別。文章也提及了路由器運作的基本概念,例如路由表的建立方式和路由協定的基礎知識。
Thumbnail
<iostream> ​在之前的文章有提到過,<iostream> 是專門處理程式的輸入 (input) 以及輸出 (output) 的函式庫。輸入輸出的對象是以電腦作為主角: 輸入指的是「把資料給電腦」,輸出指的是「從電腦那邊取得資料」。 在這個系列的文章中,程式輸入指的都是從鍵盤輸入資料給電
Thumbnail
這篇文章,會帶著大家複習以前學過的 區間DP框架, 並且以回文子字串、回文子序列的應用題與概念為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個演算法框架。 回文字串的基本定義 s = s[::-1] 也就是說字串s的正序 和 逆序完全相同。 回文字串的基本結構 空字串"
Thumbnail
這篇文章,會帶著大家複習以前學過的遞回框架, 並且鏈結串列的概念與應用為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個演算法框架。 遞回框架 尋找共通模式(common pattern),對應到演算法的General case 確立初始條件(initial conditio
Thumbnail
在Python中,queue是一個非常有用的模块。 它提供了多種佇列(queue)實現,用於在多線程環境中安全地交換信息或者數據。 佇列(queue)是一種先進先出(FIFO)的數據結構,允許在佇列的一端插入元素,另一端取出元素。(FIFO 是First In, First Out 的縮寫)
Thumbnail
** 3C機構設計爸版權所有 ** USB 是我們每天生活上所使用的device中最常有的I/O port,舉凡TV、cash machine、PC、Server、phone、……等等,數不完的device都有USB 接口,當然也存在著不同種類的USB接口,在下次的分享中,3C機構設計爸會做一個U
Thumbnail
本文介紹了抽水馬達和繼電器的工作原理,以及如何與Arduino搭配使用。繼電器的定義、結構、和工作原理,以及抽水馬達的定義、結構、和工作原理都有詳細說明。此外,還介紹了串聯和並聯的關係,並提供了抽水馬達模組的程式碼。
Thumbnail
大家好,我是woody,是一名料理創作者,非常努力地在嘗試將複雜的料理簡單化,讓大家也可以體驗到料理的樂趣而我也非常享受料理的過程,今天想跟大家聊聊,除了料理本身,料理創作背後的成本。
Thumbnail
哈囉~很久沒跟各位自我介紹一下了~ 大家好~我是爺恩 我是一名圖文插畫家,有追蹤我一段時間的應該有發現爺恩這個品牌經營了好像.....快五年了(汗)時間過得真快!隨著時間過去,創作這件事好像變得更忙碌了,也很開心跟很多厲害的創作者以及廠商互相合作幫忙,還有最重要的是大家的支持與陪伴🥹。  
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
題目敘述: 給定一個二維陣列的高與寬,並且給定起點位置座標。 請從起點位置開始順時針拜訪陣列元素,並且把沿路走過的座標記錄下來。 以陣列的形式返回答案。
Thumbnail
※ 什麼是路由? 當我們說「路由」時,可能是在談論路由器(實體設備),也可能是在談論路由(選擇路徑的過程),或者是在談論路徑(資料封包的傳輸路徑)。 路由器 (Router):這是一種實體設備,負責將資料封包 (Packet) 從一個網路傳送到另一個網路。它的工作方式類似於交通指揮,確保資料封包
Thumbnail
這篇文章介紹了路由器 (Router) 在網絡硬體中的功能與運作概念,包括路由器的工作原理、運作流程和與其他硬體設備的區別。文章也提及了路由器運作的基本概念,例如路由表的建立方式和路由協定的基礎知識。
Thumbnail
<iostream> ​在之前的文章有提到過,<iostream> 是專門處理程式的輸入 (input) 以及輸出 (output) 的函式庫。輸入輸出的對象是以電腦作為主角: 輸入指的是「把資料給電腦」,輸出指的是「從電腦那邊取得資料」。 在這個系列的文章中,程式輸入指的都是從鍵盤輸入資料給電
Thumbnail
這篇文章,會帶著大家複習以前學過的 區間DP框架, 並且以回文子字串、回文子序列的應用題與概念為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個演算法框架。 回文字串的基本定義 s = s[::-1] 也就是說字串s的正序 和 逆序完全相同。 回文字串的基本結構 空字串"
Thumbnail
這篇文章,會帶著大家複習以前學過的遞回框架, 並且鏈結串列的概念與應用為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個演算法框架。 遞回框架 尋找共通模式(common pattern),對應到演算法的General case 確立初始條件(initial conditio
Thumbnail
在Python中,queue是一個非常有用的模块。 它提供了多種佇列(queue)實現,用於在多線程環境中安全地交換信息或者數據。 佇列(queue)是一種先進先出(FIFO)的數據結構,允許在佇列的一端插入元素,另一端取出元素。(FIFO 是First In, First Out 的縮寫)
Thumbnail
** 3C機構設計爸版權所有 ** USB 是我們每天生活上所使用的device中最常有的I/O port,舉凡TV、cash machine、PC、Server、phone、……等等,數不完的device都有USB 接口,當然也存在著不同種類的USB接口,在下次的分享中,3C機構設計爸會做一個U
Thumbnail
本文介紹了抽水馬達和繼電器的工作原理,以及如何與Arduino搭配使用。繼電器的定義、結構、和工作原理,以及抽水馬達的定義、結構、和工作原理都有詳細說明。此外,還介紹了串聯和並聯的關係,並提供了抽水馬達模組的程式碼。