USB的NRZI編碼
首先,USB 的數(shù)據(jù)是串行發(fā)送的,就像 UART、I2C、SPI 等等,連續(xù)的01 信號只通過一根數(shù)據(jù)線發(fā)給接受者。
但是因為發(fā)送者和接收者運行的頻率不一樣,信號的同步就是個問題,比如,接受者接收到了一個持續(xù)
一段時間的低電平,無法得知這究竟是代表了5個0 還是1000個0。
一個解決辦法,就是在傳輸數(shù)據(jù)信號的同時,附加一個時鐘信號,用來同步兩端的傳輸,接受者在時鐘
信號的輔助下對數(shù)據(jù)信號采樣,就可以正確解析出發(fā)送的數(shù)據(jù)了,比如 I2C 就是這樣做的,SDA 來傳
輸數(shù)據(jù),SCL 來傳輸同步時鐘:
雖然這樣解決了問題,但是卻需要附加一根時鐘信號線來傳輸時鐘。有沒有不需要附加的時鐘信號,也
能保持兩端的同步呢?
有的,這就是 RZ 編碼(Return-to-zero Code),也叫做歸零編碼。
在 RZ 編碼中,正電平代表邏輯 1,負電平代表邏輯 0,并且,每傳輸完一位數(shù)據(jù),信號返回到零電
平,也就是說,信號線上會出現(xiàn) 3 種電平:正電平、負電平、零電平:
從圖上就可以看出來,因為每位傳輸之后都要歸零,所以接收者只要在信號歸零后采樣即可,這樣就不
在需要單獨的時鐘信號。實際上, RZ 編碼就是相當(dāng)于把時鐘信號用歸零編碼在了數(shù)據(jù)之內(nèi)。這樣的信
號也叫做自同步(self-clocking)信號。
這樣雖然省了時鐘數(shù)據(jù)線,但是還是有缺點的,因為在 RZ 編碼中,大部分的數(shù)據(jù)帶寬,都用來傳
輸“歸零”而浪費掉了。
那么,我們?nèi)サ暨@個歸零步驟,NRZ 編碼(Non-return-to-zero Code)就出現(xiàn)了,和 RZ 的區(qū)別就是
NRZ 是不需要歸零的:
這樣,浪費的帶寬又回來了,不過又喪失寶貴的自同步特性了,貌似我們又回到了原點,其實這個問題
也是可以解決的,不過待會兒再講,先看看什么是 NRZI:
NRZI 編碼(Non-Return-to-Zero Inverted Code)和 NRZ 的區(qū)別就是 NRZI 用信號的翻轉(zhuǎn)代表一個
邏輯,信號保持不變代表另外一個邏輯。
USB 傳輸?shù)木幋a就是 NRZI 格式,在 USB 中,電平翻轉(zhuǎn)代表邏輯 0,電平不變代表邏輯1:
翻轉(zhuǎn)的信號本身可以作為一種通知機制,而且可以看到,即使把 NRZI 的波形完全翻轉(zhuǎn),所代表的數(shù)據(jù)
序列還是一樣的,對于像 USB 這種通過差分線來傳輸?shù)男盘栍绕浞奖銅
現(xiàn)在再回到那個同步問題:
的確,NRZ 和 NRZI 都沒有自同步特性,但是可以用一些特殊的技巧解決。
比如,先發(fā)送一個同步頭,內(nèi)容是 0101010 的方波,讓接受者通過這個同步頭計算出發(fā)送者的頻率,
然后再用這個頻率來采樣之后的數(shù)據(jù)信號,就可以了。
在 USB 中,每個 USB 數(shù)據(jù)包,最開始都有個同步域(SYNC),這個域固定為 0000 0001,這個域通
過 NRZI 編碼之后,就是一串方波(復(fù)習(xí)下前面:NRZI 遇 0 翻轉(zhuǎn)遇 1
此外,因為在 USB 的 NRZI 編碼下,邏輯 0 會造成電平翻轉(zhuǎn),所以接收者在接收數(shù)據(jù)的同時,根據(jù)接
收到的翻轉(zhuǎn)信號不斷調(diào)整同步頻率,保證數(shù)據(jù)傳輸正確。
但是,這樣還是會有一個問題,就是雖然接收者可以主動和發(fā)送者的頻率匹配,但是兩者之間總會有誤差。
假如數(shù)據(jù)信號是 1000個邏輯1,經(jīng)過 USB 的 NRZI 編碼之后,就是很長一段沒有變化的電平,在這種
情況下,即使接受者的頻率和發(fā)送者相差千分之一,就會造成把數(shù)據(jù)采樣成 1001個或者 999個了。
USB對這個問題的解決辦法,就是強制插0,也就是傳說中的bit-stuffing,如果要傳輸?shù)臄?shù)據(jù)中有7個
連續(xù)的1,發(fā)送前就會在第6個1后面強制插入一個0,讓發(fā)送的信號強制出現(xiàn)翻轉(zhuǎn),從而強制接受者進
行頻率調(diào)整。接受者只要刪除6個連續(xù) 1 之后的0,就可以恢復(fù)原始的數(shù)據(jù)了。
2,來至ST的另外一個解釋
評論