常見的編碼方式有以下幾種,
1、NRZ(Not Return to Zero)不歸零編碼, 這是一種比較簡單的編碼方式,二進制數據“0”和“1”分別用高電平和低電平來表示,當1位數據傳輸完以后,信號電平
不返回零所以稱為不歸零編碼。
2、BiPhase編碼, 相比NRZ編碼方式,這種編碼稍微復雜了一點,他是這樣規定,在每一位數據傳輸時,電平都會跳變(高電平變低電平,或者低電平變高電平),
同時當數據為“1”時(按照規定也可以是“0”),在數據位中間也會跳變。
3、曼徹斯特編碼方式, 這種編碼方式利用信號的邊沿來表示二進制數據“0”和“1”,比如信號的上身沿表示“1”,下降沿表示“0”,而這種跳變一般發生在位幀的中間。
以上3中編碼方式的波形如下圖所示,

圖1 常見編碼方式波形圖
曼徹斯特編碼
假設信號的上升沿表示“0”, 下降沿表示“1”,同時假設數據的波特率為f, 那么一個位的時長為1/f,那么位幀的中間時長為1/2f,我們用T來表示這個半個位幀的時長。
有了以上的假設條件,那么曼徹斯特的編碼流程如下,
1. 首先I/O口輸出高電平。
2. 檢查數據是否發送完成,如果是,跳到步驟7。
3. 檢查下一個數據位的值。
4. 如果是“1”,調用發送1的函數ManchesterOne(T)。
5. 如果是"0",調用發送0的函數ManchesterZero(T)。
6. 返回到步驟2。
7. I/O輸出為高電平並返回。
ManchesterOne(T)的執行過程
1. I/O 輸出低電平。
2. 等待半位幀時間T。
3. I/O輸出高電平。
4. 等待半位幀時間T。
5. 返回。
ManchesterZero(T)的執行過程
1. I/O 輸出高電平。
2. 等待半位幀時間T。
3. I/O輸出低電平。
4. 等待半位幀時間T。
5. 返回。
曼徹斯特解碼
曼徹斯特解碼過程要比編碼復雜,一般的,解碼過程有以下步驟:
1. 獲取數據流的波特率(或者已知數據流的波特率)。
2. 同步數據流的時鍾信號(實質是區分位幀邊沿和半位幀邊沿)。
3. 根據上面兩步對數據流進行解碼。
假設的條件和編碼時一樣,具體的實現步驟如下,
1. 將定時器的捕獲中斷設置為所有邊沿(對於沒有上升沿和下降沿同時捕獲的MCU,需要在中斷處理函數里改變捕獲沿)。
2. 中斷函數里處理捕獲標志位和捕獲值。
3. 開啟定時器,捕獲第一個邊沿並丟棄。
4. 捕獲下一個邊沿,檢查捕獲值是否等於2T(T = 1/2f,其中f為數據流的波特率。
5. 重復步驟4,直到捕獲值等於2T(此時就和數據流的時鍾同步了)。
6. 讀取當前I/O信號的電平值,並保存為當前位的值(0或者1)。
7. 捕獲下一個邊沿
a. 捕獲值和T比較
b. 如果捕獲值等於T
i. 捕獲下一個邊沿同時確定該捕獲值也等於T(如果不等說明編碼錯誤)
ii. 下一位的值和當前值相同
iii. 返回該值
c. 如果捕獲值等於2T
i. 下一位的值和當前值相反
ii. 返回該值
d. 否則返回錯誤
8. 保存下一位的值到緩存
9. 如果接收到的數據位達到要求,返回對數據做進一步處理
10. 否則更新當前值(設置為下一位的值),重復步驟7
下圖展示的是這種解碼方式的一個示意圖,
圖2 曼徹斯特解碼示意圖
總結
總的來說,編碼和解碼還是比較簡單的,曼徹斯特的典型應用是在RFID領域里標簽讀取。另外,上面假設上升沿表示“1”,下降沿表示“0”,對於相反的情況(即上升
沿表示“0”,下降沿表示“1”),解碼過程處理不同的地方在步驟6,假如同步到數據流的時鍾,對於上升沿表示“1”,下降沿表示“0”的情況,當前位的值和讀取到的I/O
的值相同;對於上升沿表示“0”,下降沿表示“1”的情況,當前位的值和讀取到的I/O的值相反。
