從零開始學USB(六 USB通訊的資料格式)

2021-10-03 23:38:18 字數 2317 閱讀 6199

前面章節已經學習過了usb的引腳定義了,但是對於其中的usb 2.0的兩根資料線d+和d-所對應的資料傳輸,卻沒有詳細介紹。此處就是介紹,在此序列資料線中,資料是如何被編碼和傳送的。

usb所傳輸的資料,用的資料編碼方式是nrzi(non-return-to-zero inverted),其具體的含**釋,看到有位網友已經非常清晰的分析過了,我就不重複造輪子了。

usb 的 nrzi 編碼

為了防止這位網友的伺服器出問題,下面我再複製乙份。

這兩天繼續看 usb 相關的內容,準備用純軟體實現一下 usb 裝置傳輸,為將來的專案打好基礎。

首先碰到的就是這個 nrzi 編碼的問題了,基礎太薄弱,看了一上午總算明白了大概。

首先,usb 的資料是序列傳送的,就像 uart、i2c、spi 等等,連續的01 訊號只通過一根資料線傳送給接受者。

但是因為傳送者和接收者執行的頻率不一樣,訊號的同步就是個問題,比如,接受者接收到了乙個持續一段時間的低電平,無法得知這究竟是代表了5個0 還是1000個0。

乙個解決辦法,就是在傳輸資料訊號的同時,附加乙個時鐘訊號,用來同步兩端的傳輸,接受者在時鐘訊號的輔助下對資料訊號取樣,就可以正確解析出發送的資料了,比如 i2c 就是這樣做的,sda 來傳輸資料,scl 來傳輸同步時鐘:

圖為i2c資料編碼格式

雖然這樣解決了問題,但是卻需要附加一根時鐘訊號線來傳輸時鐘。有沒有不需要附加的時鐘訊號,也能保持兩端的同步呢?

有的,這就是 rz 編碼(return-to-zero code),也叫做歸零編碼。

在 rz 編碼中,正電平代表邏輯 1,負電平代表邏輯 0,並且,每傳輸完一位資料,訊號返回到零電平,也就是說,訊號線上會出現 3 種電平:正電平、負電平、零電平:

圖為歸零編碼

從圖上就可以看出來,因為每位傳輸之後都要歸零,所以接收者只要在訊號歸零後取樣即可,這樣就不在需要單獨的時鐘訊號。實際上, rz 編碼就是相當於把時鐘訊號用歸零編碼在了資料之內。這樣的訊號也叫做自同步(self-clocking)訊號。

這樣雖然省了時鐘資料線,但是還是有缺點的,因為在 rz 編碼中,大部分的資料頻寬,都用來傳輸「歸零」而浪費掉了。

那麼,我們去掉這個歸零步驟,nrz 編碼(non-return-to-zero code)就出現了,和 rz 的區別就是 nrz 是不需要歸零的:

圖為非歸零編碼

這樣,浪費的頻寬又回來了,不過又喪失寶貴的自同步特性了,貌似我們又回到了原點,其實這個問題也是可以解決的,不過待會兒再講,先看看什麼是 nrzi:

nrzi 編碼(non-return-to-zero inverted code)和 nrz 的區別就是 nrzi 用訊號的翻轉代表乙個邏輯,訊號保持不變代表另外乙個邏輯。

usb 傳輸的編碼就是 nrzi 格式,在 usb 中,電平翻轉代表邏輯 0,電平不變代表邏輯1:

圖為nrz和nrzi

翻轉的訊號本身可以作為一種通知機制,而且可以看到,即使把 nrzi 的波形完全翻轉,所代表的資料序列還是一樣的,對於像 usb 這種通過差分線來傳輸的訊號尤其方便~

現在再回到那個同步問題:

的確,nrz 和 nrzi 都沒有自同步特性,但是可以用一些特殊的技巧解決。

比如,先傳送乙個同步頭,內容是 0101010 的方波,讓接受者通過這個同步頭計算出傳送者的頻率,然後再用這個頻率來取樣之後的資料訊號,就可以了。

在 usb 中,每個 usb 資料報,最開始都有個同步域(sync),這個域固定為 0000 0001,這個域通過 nrzi 編碼之後,就是一串方波(複習下前面:nrzi 遇 0 翻轉遇 1

此外,因為在 usb 的 nrzi 編碼下,邏輯 0 會造成電平翻轉,所以接收者在接收資料的同時,根據接收到的翻轉訊號不斷調整同步頻率,保證資料傳輸正確。

但是,這樣還是會有乙個問題,就是雖然接收者可以主動和傳送者的頻率匹配,但是兩者之間總會有誤差。

假如資料訊號是 1000個邏輯1,經過 usb 的 nrzi 編碼之後,就是很長一段沒有變化的電平,在這種情況下,即使接受者的頻率和傳送者相差千分之一,就會造成把資料取樣成 1001個或者 999個了。

usb對這個問題的解決辦法,就是強制插0,也就是傳說中的bit-stuffing,如果要傳輸的資料中有7個連續的1,傳送前就會在第6個1後面強制插入乙個0,讓傳送的訊號強制出現翻轉,從而強制接受者進行頻率調整。接受者只要刪除6個連續 1 之後的0,就可以恢復原始的資料了。

當然在協議中,這兩點說的也比較清晰,對著協議看一下就可以知道nrzi的編碼規則。

從零開始學USB(十四 USB資料傳輸的組織形式)

在前面的十一節中,學習了usb中傳輸中乙個包是由多個域組成。在前面的十二節中,學習了usb傳輸中學習了包的形式有哪些 令牌包 資料報 應答包等 以及各自的特點和功能。在前面的十三節中,學習了usb的乙個事務是由多個包組成的 in out setup事務等 以及四種傳輸型別,具體怎麼組織事務 乙個傳輸...

從零開始學USB(一 基礎知識1)

1.什麼是usb?usb是universal serial bus的縮寫,中文譯為通用序列匯流排。正如usb的第乙個單詞表述的那樣,為了通用。那麼我們看一下,還有哪些匯流排不是序列的,哪些是不通用的序列匯流排 下表來自 usb complete 裡面對一些常見匯流排所總結的一些區別 當然上表中關於s...

零開始學python 從零開始學Python

第1章 python入門 1 1 1 什麼是python 1 1 2 python語言有什麼特點 2 1 3 python可以幹什麼 4 練一練 5 第2章 準備開發環境 6 2 1 在windows上安裝python開發環境 6 2 2 選擇和安裝開發工具 11 練一練 17 第3章 基本概念 1...