---
title: I2C 界面解密 — PART8 準位轉換
description: 作者：Bird 這是 I^2C（以下寫作 I2C）界面系列文章的最後一回，我們要…
url: "https://makerpro.cc/docs/i2c-interface-part8/"
updated: "2025-05-09"
category: I2C
---

# I2C 界面解密 — PART8 準位轉換

作者：Bird

這是 I^2C（以下寫作 I2C）界面系列文章的最後一回，我們要來聊一下 I2C bus 的準位轉換（level shifting），也就是如何連接不同邏輯準位的 I2C bus，讓它們可以一起工作。

### **準位轉換的難題**

典型的單向邏輯位準轉換電路長這樣：

 ![](https://makerpro.cc/wp-content/uploads/2020/08/1598099901645.jpg)

（圖片來源：Bird 提供）

這種電路利用兩個各自適合來源、目標邏輯準位電壓的 buffer，來連接兩側的電路；而另外一種雙向的邏輯準位轉換電路，則需要多一個方向的控制訊號，來告訴轉換器要往哪一個方向轉換：

 ![](https://makerpro.cc/wp-content/uploads/2020/08/1598099922243.jpg)

（圖片來源：Bird 提供）

上面兩顆 buffer 在 DIR 訊號爲 high 時會啓動，因此轉換的方向是由 A 到 B。下面兩顆 buffer 的 enable 訊號上有一顆小圓圈，代表它是負邏輯，也就是在 DIR 訊號爲 low 時才啓動，轉換方向 由 B 到 A，因此 DIR 可以用來控制這個電路的轉換與驅動方向。

但以上兩種位準轉換電路，都無法適用在 I2C bus 上。I2C bus 中並沒有一個訊號明確地指出 bus 的驅動方向，對每一個裝置來說，SCL 和 SDA 訊號隨時都有可能是輸入或輸出，瞬息萬變。

舉例來說，對 master 裝置來說，當它送完 START condition 以及接下來 8 個 bits 的 slave address 後，SDA 就會在第 9 個 SCL 週期變爲輸入，用來接收 slave 裝置傳來的 ACK bit；而 SCL 訊號雖然始終都是由 master 裝置送出，但事實上它在每一個 clock 送出後，都會持續監聽 SCL，看看有沒有 slave 裝置發出 clock stretching（忘了什麼是 clock stretching 的讀者，可以回頭翻一下[【Maker電子學】I2C 界面解密 — PART 5 時脈擴展](https://makerpro.cc/2020/07/i2c-interface-part5-clock-stretching/)）。

事實上 master 裝置就算在驅動 SDA，也會同時監聽 SDA 的狀態以辨別是否有 bus arbitration 的狀況發生（忘了什麼是 bus arbitration 的讀者，可以回頭翻一下[【Maker電子學】I2C 界面解密 — PART 6 仲裁協定](https://makerpro.cc/2020/07/i2c-interface-part6/)）。

由於 I2C bus 的 wired-AND 的特性，不管是 SCL 還是 SDA，它們都沒有明確的驅動方向；也可以說，對所有的裝置來講，SCL 和 SDA 在任何時候都同時是輸入和輸出。

我們強調過很多次，I2C bus 的輸出驅動方式是 open drain，裝置只能把 bus 訊號拉 low，或者不拉；當大家都不拉時，bus 的狀態才會靠拉起電阻的作用而變成 high。這樣的設計，讓 bus 上的邏輯 0 比邏輯 1 有更高的優先權，因爲只要有任何一個裝置發出 0，bus 就會是 0；只有當大家都發出 1 時，bus 才會是 1。

### **優雅的解決方法**

提出 I2C bus 標準的 NXP 半導體（前身爲飛利浦半導體 Philips Semiconductors）早在 I2C bus 問市之初，就已經爲大家設想好了邏輯位準轉換的做法。在一份編號爲 [AN10441](https://www.nxp.com/docs/en/application-note/AN10441.pdf) 的 application note 中，NXP 爲大家示範了只用兩顆 MOSFET 就達成 I2C bus 位準轉換的巧妙做法。

我們直接引用 AN10441 裡面的圖片來說明，這個電路長這樣：

 ![](https://makerpro.cc/wp-content/uploads/2020/08/1598099944876.jpg)

（圖片來源：Bird 提供）

第一眼看到這個電路，都會覺得它簡單得不可思議，光這兩顆電晶體就有辦法做到 I2C bus 的位準轉換嗎？我們來分析一下這個電路的運作就知道了。

電路的左側是電壓較低的 3.3 V 系統，右側是電壓較高的 5V 系統。電路中的四個 R~P電阻則是 I2C bus 的拉起電阻，各自講 3.3 V 和 5 V 的 bus 拉到對應的電源電壓。

這裡要特別注意的是，MOSFET 會有一個從 source 向 drain 導通的 body diode，在這個電路中，MOSFET 的 source 要接在電壓較低的一側，drain 要接在電壓較高的一側。這個電路有三種狀態：

1. 如果 5 V 側有裝置將 bus 拉到 low，5 V 側就會變成接近 0 V，本來逆偏壓而不導通的 MOSFET body diode 就會變成順偏壓，因而開始導通。導通之後，3.3 V 側的電壓就會開始下降，當 3.3 V 側的電壓低於某個程度時，由於 MOSFET 的 gate 是接在 3.3 V 電源上，導致 V~gs大於 MOSFET 的V~th，MOSFET 就會開始導通，更進一步地讓 5 V 側將 3.3 V 側的 bus 電壓拉低，直到兩邊電壓相等為止。這是由 5 V 側驅動 3.3 V 側的狀態。
2. 如果 3.3 V 側有裝置將 bus 拉到 low，由於 MOSFET 的 gate 接在 3.3 V 上，當 source 電壓降低到某個程度，一樣會導致 V~gs大於 MOSFET 的 V~th，MOSFET 就會開始導通，此時 3.3 V 側就會透過 MOSFET 將 5 V 側的 bus 拉低，直到兩邊電壓相等為止。這是由 3.3 V 側驅動 5 V 側的方法。
3. 如果兩邊都沒有裝置去拉 bus 的話，因為兩邊都有各自的拉起電阻，3.3 V 側的電壓就會是 3.3 V，5 V 側的電壓就會是 5 V，而圖中的 MOSFET，gate 和 source 的電壓都是 3.3 V，因此它的 V~gs等於 0，MOSFET 就不會導通；至於 MOSFET 的 body diode，因為是在逆偏壓的狀態下，因此也不會導通，這讓 bus 的兩邊都能被拉到各自的電源電壓，而不會有互相影響的問題。

講完了，是不是簡單得令人驚訝？有時候複雜的問題不一定要用複雜的解決方法，它可能有很精巧且優雅的簡單解法。我曾經看過設計 IC 的工程師爲了要解決 I2C bus 的位準轉換問題，用 Verilog 寫了一整個狀態機去追蹤 I2C bus 的所有狀態、判斷 bus 驅動的方向，再產生方向訊號去驅動邏輯位準轉換的 buffer。這樣的做法在某些 Fast+ 或更快的 I2C bus 設計上有其必要，但在 400 KHz 以下的 I2C bus 上就顯得太過複雜了，尤其原廠早在數十年前就提供了這樣簡單又優雅的解決方法。

### **小結**

這一系列關於各種常用通訊界面的文章，就結束在這一回了。回顧過去這半年多，我們花了四回的篇幅討論 UART、四回的篇幅討論 SPI，又花了八回的篇幅討論 I2C，希望這一系列的文章能對讀者有所幫助。

（責任編輯：賴佩萱）
