高阻態這是一個數字電路里常見的術語,指的是電路的一種輸出狀態,既不是高電平也不是低電平,如果高阻態再輸入下一級電路的話,對下級電路無任何影響,和沒接一樣。
高阻態的意義:當門電路的輸出上拉管導通而下拉管截止時,輸出為高電平;反之就是低電平;如上拉管和下拉管都截止時,輸出端就相當於浮空(沒有電流流動),其電平隨外部電平高低而定,即該門電路放棄對輸出端電路的控制 。
典型應用:
在總線連接的結構上。總線上掛有多個設備,設備於總線以高阻的形式連接。這樣在設備不占用總線時自動釋放總線,以方便其他設備獲得總線的使用權。如果你的設備端口要掛在一個總線上,必須通過三態緩沖器。因為在一個總線上同時只能有一個端口作輸出,這時其他端口必須在高阻態,同時可以輸入這個輸出端口的數據。所以你還需要有總線控制管理, 訪問到哪個端口,那個端口的三態緩沖器才可以轉入輸出狀態,這是典型的三態門應用。
assign SDA = (sda_en)? sda_out:1'bz;
當sda_en為高時SDA作為輸出口,輸出sda_out的數據,當sda_en為低時三態門是處於高阻態,這時三態門是作為輸入口使用,其電平隨外部電平高低而定,即該門電路放棄對輸出端電路的控制 ,這時輸入的數據為SDA的數據(即外部器件的數據)。
提問:為什么iic中SDA線要用到三態開漏模式去控制?
答:因為SDA數據傳輸線是一個發送和接收數據共用的信號線。(即FPGA的一個IO口既需要輸出數據,又需要接收數據inout類型),那么則需要三態開漏模式去控制實現什么時候作為輸出,什么時候作為輸入;而且輸出的時候不受輸入的影響,輸入的時候不受輸出影響
假設第一秒,IIC_SDA_OUT_DATA輸出數據到SDA信號線上,此時SDA外部器件也要讀取IIC_SDA_OUT_DATA輸出的數據;那么則需要IIC_SDA_OE接通(即IIC_SDA_OE = 1'b1),同時還要避免外部器件通過SDA數據線讀取到IIC_SDA_IN_DATA的電平 狀態(即萬一IIC_SDA_OUT_DATA輸出數據位1時,而恰巧IIC_SDA_IN_DATA的電平狀態為0,則SDA信號線的電平就會置一,產生錯誤信號)。
假設第二秒,IIC_SDA_IN_DATA從SDA數據線讀取數,此時只需要將IIC_SDA_OE斷開即可避免 IIC_SDA_OUT_DATA 對讀取數據的影響。
避免的方法:將SDA數據線接上一個上拉電阻,然后利用下面的代碼實現
//在IIC_SDA_OUT_DATA輸出數據到SDA數據線上時,又需要避免IIC_SDA_IN_DATA電平對數據產生影響的解決方案 assign SDA = IIC_SDA_OE ? IIC_SDA_OUT_DATA : 1'bZ ; //寫過程這種寫法欠佳 assign SDA = IIC_SDA_OE ? (IIC_SDA_OUT_DATA ? 1'bZ : 1'b0) : 1'bz;//寫過程這種更好
由上面第二行代碼可知,當FPGA向SDA數據線上寫數據時,IIC_SDA_OE = 1'b1 ; 則 SDA = IIC_SDA_OUT_DATA ? 1'bz : 1'b0 ;
當FPGA向SDA數據線上寫數據1時,SDA = 1'bz(SDA的IO口為高阻態,從而避免IIC_SDA_IN_DATA的影響),又因為外接上拉電阻,所以外部器件得到的信號還是為1;
當FPGA向SDA數據線上寫數據0時,SDA = 1'b0(SDA的IO口為低電平),同時也會將外接上拉電阻電平拉低,所以外部器件得到的信號還是為0.
當FPGA不向SDA數據線上寫數據時,即IIC_SDA_OE = 1'b0;則 SDA = 1'bz ,此時三態門作為輸入使用,IIC_SDA_IN_DATA的數據受SDA上的數據影響,即等於外部器件所輸出的數據。