USB的編碼方式——NRZI編碼

NRZI編碼:
    像 UART、I2C、SPI 、USB 這樣的串行總線,通信時連續的0、1 信號只通過一根數據線發送給接收者。但是因爲發送者和接收者運行的頻率不一樣,信號的同步就是個問題,比如,接受者接收到了一個持續一段時間的低電平,無法得知這究竟是代表了 5 個 0 還是 1000 個 0 。一個解決辦法,就是在傳輸數據信號的同時,附加一個時鐘信號線,用來同步兩端的傳輸,接受者在時鐘信號的輔助下對數據信號採樣,就可以正確解析出發送的數據了,比如 I2C 就是這樣做的,SDA 來傳輸數據,SCL 來傳輸同步時鐘。雖然這樣解決了問題,但是卻需要附加一根時鐘信號線來傳輸時鐘。有沒有不需要附加的時鐘信號,也能保持兩端的同步呢? 
      有,那就是我們的URZI編碼(No Return Zero-Inverse),如圖1和圖2所示,(圖1的序號1是普通信號格式,序號2是NRZI編碼格式) USB 傳輸的編碼就是 NRZI 格式,在 USB 中,電平翻轉代表邏輯 0,電平不變代表邏輯1。翻轉的信號本身可以作爲一種通知機制,而且可以看到,即使把 NRZI 的波形完全翻轉,所代表的數據序列還是一樣的,對於像 USB 這種通過差分線來傳輸的信號尤其方便~
圖1  NRZI編碼圖解


圖2  NRZI編碼圖解

       現在再回到那個同步問題: 的確 這樣的NRZI 仍然沒有自同步特性,但是可以用一些特殊的技巧解決。比如,先發送一個同步頭,內容是 0101010 的方波,讓接受者通過這個同步頭計算出發送者的頻率,然後再用這個頻率來採樣之後的數據信號,就可以了。 
       在 USB 中,每個 USB 數據包,最開始都有個同步域(SYNC),這個域固定爲 0000 0001,這個域通過 NRZI 編碼之後,就是一串方波(複習下前面:NRZI 遇 0 翻轉遇 1 不變),接受者可以用這個 SYNC 域來同步之後的數據信號。 
       此外,因爲在 USB 的 NRZI 編碼下,邏輯 0 會造成電平翻轉,所以接受者在接受數據的同時,根據接收到的翻轉信號不斷調整同步頻率,保證數據傳輸正確。 
       但是,這樣還是會有一個問題,就是雖然接受者可以主動和發送者的頻率匹配,但是兩者之間總會有誤差。假如數據信號是 1000 個邏輯 1,經過 USB 的 NRZI 編碼之後,就是很長一段沒有變化的電平,在這種情況下,即使接受者的頻率和發送者相差千分之一,就會造成把數據採樣成 1001 個或者 999 個 1了。 
       USB 對這個問題的解決辦法,就是強制插 0,也就是傳說中的 bit-stuffing,如果要傳輸的數據中有 7 個連續的 1,發送前就會在第 6 個 1 後面強制插入一個 0,讓發送的信號強制出現翻轉,從而強制接受者進行頻率調整。接受者只要刪除 6 個連續 1 之後的 0,就可以恢復原始的數據了。 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章