今天來說一道Facebook的面試題,曾經我的一個朋友夢想去美國矽谷工作,Facebook的工程師在面試時問了一道關於I2C的問題,比較簡單也比較直接,可惜我的那個兄弟由於太緊張,沒有答好,大家在看這篇文章時,不妨自測一下自己能不能準確答出來。
我們先來看一張圖,熟悉I2C的人一看,這不是I2C的level shifter電路嘛,在Philip的I2C標準裡面有,沒有啥複雜的。
我們先來解讀下這張圖,I2C的level shifter是通過NMOS管來實現的,有人可能會問,為什麼不用PMOS呢?一般情況下,只有在外部電源輸入端,我們設計INRUSH電流緩啟動或者防反插電路的時候才會用到PMOS。理由很簡單, PMOS是低電平打開,電源插入瞬間系統其實還沒有用於打開MOSFET的高電平,所以只能選擇PMOS, 而NMOS體積小,RDSON低,在系統內部會更多選擇NMOS。
言歸正傳,我們來繼續討論I2C問題。首先我們要牢牢記住,I2C是Open-drain,所以level shifter電路的兩邊都是上拉電阻Rp的,下面講下這個電路是怎麼工作的。
下圖是兩張I2C的基本操作時序圖,分別是Master對Slave所做的讀和寫:
我們可以看到, SDA一定是雙向的,既然是雙向的,那麼就有四種情況,我們來一一解釋level shifter是怎麼來cover它們的。(注意:這裡面會含有一個Facebook的問題,不要忘記自測哦。)
1) 左邊MasterSDA_1為輸出,驅H-3.3V,NMOS的VGS=0, 此時NMOS關閉;
2) 右邊的Slave的SDA_2是輸入,對外呈現高阻;
3) NMOS關斷和SLAVE為輸入,導致SDA_2懸空;
4) 最終SDA_2依靠RP2上拉到5V,完成3.3V到5V的轉換。
1) 左邊MasterSDA_1為輸出,驅Low=0,NMOS的VGS>0, 此時NMOS打開;
2) 右邊的Slave的SDA_2是輸入,對外呈現高阻;
3) NMOS打開和SLAVE為輸入,導致SDA_2=SDA_1=0;
4) 最終SDA_2被SDA_1拉到0,完成低電平的轉換。
1) 右邊Slave SDA_2為輸出,驅H-5V;
2) 左邊Master SDA_1為輸入,對外高阻, 被RP1上拉到3.3V;
3) NMOS 因為VGS=0一直關閉;
4) NMOS關閉,Master SDA_1維持3.3V高電平,完成電平轉換。
1) 右邊Slave SDA_2為輸出,驅LOW;
2) 左邊Master SDA_1為輸入,對外高阻, 被RP1上拉到3.3V;
3) NMOS 因為VGS=0一直關閉;
4) NMOS關閉,Master SDA_1為3.3V高電平。
問題來了,我們看到右邊的SDA_2位Low,但是左邊的是SDA_1位High,那不是失敗了嘛,不可能啊,這個電路是好的啊。
我們來看看下一步會發生什麼,其實這個問題沒有那麼難,仔細看看這張圖,還是比較容易發現線索的。
我們來揭曉答案:大家看看上圖的NMOS下面多了一個二極體,我們把這個二極體叫做Body Diode,它會在這個時候發揮作用。
5) 由於左邊SDA_1為高,右邊SDA_2為LOW, Body Diode導通;
6) SDA_1被拉低,導致NMOS VGS>0 後打開;
7) NOMO打開後,SDA_1和SDA_2相當於短在一起;
8) 最終左邊SDA_1被右邊的SDA_2拉低變為LOW。
我們看到由於體二極體的作用,打開NMOS管,使得右邊Slave輸出的L=0順利到達左邊的Master SDA_1輸入端。
當你看著這張圖,按圖索驥,也許不難發現答案,但是在面試的時候,一是緊張,二是沒有清晰的電路提示,有時候容易發揮不出來,你們覺得呢?
今天這個小坑就先講解到這裡,後面的第五宗罪——負載會更加精彩哦!