接下來幾篇文章,我們會來談談在數位系統設計上常用到的一些界面,如 UART、I2C、SPI 等。這些常見的界面用起來雖然不難,但背後其實有很多有趣的原理和機制可以細細研究。
就讓我們從串列界面的老祖宗:UART 開始聊起吧。
串列通訊的始祖
「把一整排的資料按照順序排列,逐一送到遠方,接收方再用同樣的順序將資料排回去」,這就是串列通訊的原始精神。
那爲什麼要這麼麻煩呢?爲了節省線路。
假設我有一個 byte,也就是 8 個 bit 的資料要送到遠方,如果想要一次就把 8 個 bit 都送過去,就需要 8 根電路連線,但如果用上面說的方法,利用邏輯電路上的移位暫存器來排列資料,就只要... 一根線?不,至少要兩根線。
(圖片來源:Bird 提供)
移位暫存器需要一個 clock 訊號才能工作:它在每個 clock 的上升緣(或下降緣—如果是比較搞怪的設計)將資料移入或移出,因此除了 data 訊號外,至少還需要一根 clock 訊號才能運作,而如果移位暫存器的工作夠可靠,兩邊的初始狀態都一樣且傳輸的過程中保證沒有出錯,那麼 reset 訊號並不是必需的。
Clock 訊號是用來確保傳送和接收方能同步的一種方法,所謂同步就是兩者在一個說好的時間收送資料。比方說移位暫存器,接收方會在 clock 的上升緣取樣資料,傳送方就會確保在 clock 的上升緣時資料是穩定且有效的。
以上這種傳送方法其實就是 UART 的哥哥,叫做 USRT:Universal Synchronous Receiver/Transceiver。
再省一根線
有沒有辦法再省掉一根線,不要用 clock 也能把串列資料傳送到遠方呢?如果沒有 clock,接收方要如何知道要用什麼速度來接收資料呢?
兩邊先講好,用一樣的速度來傳送、接收資料就好了!
於是在 UART 上就出現了 baud rate 這個概念。Baud 這個字指的是串列傳送時的基本符號,其實就是 bit,傳送方和接收方必需要設定一樣的 baud rate(傳送速度),比方說我們很常用的 115200 bps ,就代表每秒鐘傳送十一萬五千兩百個 bit(聽起來很厲害!),每一個 bit 的時間就是 1/115200 = 8.68 us,也就是說,接收方每隔 8.68us 就讀一個 bit。
只需不到短短一分鐘...
輸入您的信箱與ID註冊即可享有一切福利!
會員福利
免費電子報
會員搶先看
主題訂閱
好文收藏
2023/03/13
受益良多
感謝無私分享
2022/09/26
您好,閱讀了您寫的UART、I2C、SPI的介紹後,有了一個疑問
請問UART跟SPI需要pull-up電阻嗎?
2022/07/09
這篇通訊基礎知識文章對小弟很受用,謝謝!
2022/05/21
0xC5 換成二進位就是 11000101 的傳送
好像一般是從低位元(LSB)先傳最後才是高位元(MSB)
也就是 10100011
2020/09/01
感覺有點怪。照道理講,如果baud rate 有問題的話 那他們估計”start結束的位置”本身就會不一致。而這樣的不一致將會導致第一個data_bit兩者估計位置是不相同的。但看你的圖是一樣的。
以你給的資料為例 115200bps and 126720bps
從看到高準位降至低準位 同為 start的開始,所以直到第一個data_bit的取樣位置(取樣位置依樣取中間)
1 . (115200bps) 8.68+4.34=13.02
2 . (126720bps) 7.89+3.945 = 11.835
最後的一個bit取樣位置如下
1 . (115200bps) 13.02+78.68 = 73.78
2 . (126720bps) 11.835+77.89 = 67.065
而73.78前面只能容許4.34的誤差範圍 所以明顯的不行
2020/09/01
嗯,如果從 start bit 開始計算 timing 的話,由於多了一個 bit,UART 僅能容許 11% 的 baud rate 誤差,但實務上由於 start bit 固定為 0,它不需要被 sample,因此大部分的 UART 硬體實作時會在 start bit 的結束,也就是上升緣時,才開始 baud rate counter 的計數,因此可容許的誤差才會是 100% / 8 = 12.5%, 而不是 100% / 9 = 11.1%
2020/09/02
不好意思 想問一下如果第一筆也是0怎麼辦,他一樣是在低電位,這樣你一樣要先從start開始算起才知道哪一個是first_data
2020/09/02
如果第一個 bit 是 0,receiver 確實就沒有 retiming 的機會,它就只能用 start bit 的下降緣當參考。事實上現在 UART 的 receiver 設計非常多樣化,有些接收電路會在每一個 transition edge 做 retiming,重設 baud rate counter,因此可以容忍更大的 baud rate 誤差,但如果要以最傳統的 UART 來看,您是正確的,worst case 是 11.1% 的誤差容許
2020/09/02
感謝你了 文章寫得輕鬆易懂,有其他推薦的UART文章嗎 講UART_IRQ類型的
2020/06/09
文章寫到UART 的邏輯準位和直覺是相反的。
UART 上的 1 是 logic low,也就是低電位, 0 是 logic high
但是在8051上面的TX, RX 也是UART的通訊協定但是正邏輯 ,
就是 1 是logic high , 0 是logic low
, 所以你要講的是不是要講
UART 通訊協定下 ,如果是用RS232做介面傳輸 , 1 是 logic low, 0 是 logic high
UART 通訊協定下 ,如果是用TTL ,RS422 ,RS485 做介面傳輸 , 1 是 logic high, 0 是 logic low
2020/06/13
是的,您是正確的。文章中稍有語意不清之處,我會再修改以避免溷肴。
2020/02/11
:也就是說,接收方每隔 115200 bps 就讀一個 bit。
是不是要改成 每隔8.68 us,就讀一個bit?
2020/06/13
謝謝指正,您是正確的。
2020/01/09
“由於 UART 在沒有傳送資料時,邏輯位準是維持 high 的,因此當 stop bit 一來時,UART 的電壓就會變低,變成 logic low 的位準。”
請問stop bit 是不是寫錯了,應該是 start bit ?
2020/01/09
Hi Kevin, 作者確認你是對的(有讀者這麼認真看文章,他很感動喔!)
謝謝喔!
2019/12/26
Thanks a lot