漏極開路(OD)原理說解
漏極開路(OD),它與集電極開路(OC)是一致的,就是把下圖的三極管改成CMOS管就是了。
?
?
?
????集電極開路(OC)輸出的結(jié)構(gòu)如圖1所示,右邊的那個三極管集電極什么都不接,所以叫做集電極開路(左邊的三極管為反相之用,使輸入為“0”時,輸出也為“0”)。對于圖1,當(dāng)左端的輸入為“0”時,前面的三極管截止(即集電極C跟發(fā)射極E之間相當(dāng)于斷開),所以5V電源通過1K電阻加到右邊的三極管上,右邊的三極管導(dǎo)通(即相當(dāng)于一個開關(guān)閉合);當(dāng)左端的輸入為“1”時,前面的三極管導(dǎo)通,而后面的三極管截止(相當(dāng)于開關(guān)斷開)。
?? 為了方便理解,我們把上面的圖1改寫成圖2的樣子。
?????????????????????????
圖2中的開關(guān)受軟件控制,“1”時斷開,“0”時閉合。很明顯可以看出,當(dāng)開關(guān)閉合時,輸出直接接地,所以輸出電平為0。而當(dāng)開關(guān)斷開時,則輸出端懸空了,即高阻態(tài)。這時電平狀態(tài)未知,如果后面一個電阻負(fù)載(即使很輕的負(fù)載)到地,那么輸出端的電平就被這個負(fù)載拉到低電平了,所以這個電路是不能輸出高電平的。也就是說這個輸出端的電平是受負(fù)載的影響的。這樣是很不穩(wěn)定的,要避免這種情況。最多的就是使用上拉電阻。
????????????????????????
?
??
??? 再看圖三。圖三中那個1K的電阻即是上拉電阻。如果開關(guān)閉合,則有電流從1K電阻及開關(guān)上流過,但由于開關(guān)閉和時電阻為0(方便我們的討論,實際情況中開關(guān)電阻不為0,另外對于三極管還存在飽和壓降),所以在開關(guān)上的電壓為0,即輸出電平為0。如果開關(guān)斷開,則由于開關(guān)電阻為無窮大(同上,不考慮實際中的漏電流),所以流過的電流為0,因此在1K電阻上的壓降也為0,所以輸出端的電壓就是5V了,這樣就能輸出高電平了。但是這個輸出的內(nèi)阻是比較大的(即1KΩ),如果接一個電阻為R的負(fù)載,通過分壓計算,就可以算得最后的輸出電壓為5*R/(R+1000)伏,即5/(1+1000/R)伏。所以,如果要達(dá)到一定的電壓的話,R就不能太小。如果R真的太小,而導(dǎo)致輸出電壓不夠的話,那我們只有通過減小那個1K的上拉電阻來增加驅(qū)動能力(所謂的驅(qū)動力,往往與電流有關(guān)的)。但是,上拉電阻又不能取得太小,因為當(dāng)開關(guān)閉合時,將產(chǎn)生電流,由于開關(guān)能流過的電流是有限的,因此限制了上拉電阻的取值,另外還需要考慮到,當(dāng)輸出低電平時,負(fù)載可能還會給提供一部分電流從開關(guān)流過,因此要綜合這些電流考慮來選擇合適的上拉電阻。
P.S:說到OC門的話,大家都能想到三態(tài)門,那么就不得不提起它的“線與”功能了,這個功能是很方便的。操作上面也很簡單。如下附圖:
????????????????
?? 另一種輸出結(jié)構(gòu)是推挽輸出。推挽輸出的結(jié)構(gòu)就是把上面的上拉電阻也換成一個開關(guān),當(dāng)要輸出高電平時,上面的開關(guān)通,下面的開關(guān)斷;而要輸出低電平時,則剛好相反。比起OC或者OD來說,這樣的推挽結(jié)構(gòu)高、低電平驅(qū)動能力都很強(qiáng)。如果兩個輸出不同電平的輸出口接在一起的話,就會產(chǎn)生很大的電流,有可能將輸出口燒壞。而上面說的OC或OD輸出則不會有這樣的情況,因為上拉電阻提供的電流比較小。如果是推挽輸出的要設(shè)置為高阻態(tài)時,則兩個開關(guān)必須同時斷開(或者在輸出口上使用一個傳輸門),這樣可作為輸入狀態(tài),有些單片機(jī)的一些IO口就是這種結(jié)構(gòu)。
?總結(jié):從上面也可以知道了,I/0輸出有兩種方式。那么現(xiàn)在的難點就是如何讓I/0口輸入數(shù)據(jù)。其實上面已經(jīng)講過了,就是只需要把輸出設(shè)置為高阻狀態(tài)就可以了。那么有些新人就會問了,都設(shè)成高阻狀態(tài)了,數(shù)據(jù)還怎么輸入???這其實是一個誤區(qū),其根本是沒有理解I/O口的結(jié)構(gòu)。
?? 如果我們將一個讀數(shù)據(jù)用的輸入端接在輸出端(這就是上面疑惑的答案了),這樣就是一個IO口了(51的IO口就是這樣的結(jié)構(gòu),其中P0口內(nèi)部不帶上拉,而其它三個口帶內(nèi)部上拉),如圖4所示。當(dāng)我們要使用輸入功能時,只要將輸出口設(shè)置為1即可,也就是要把下面的z=1,這樣就相當(dāng)于那個開關(guān)斷開,而對于P0口來說,就是高阻態(tài)了。
?
???? 到現(xiàn)在為止,已經(jīng)把輸入輸出端口原理已經(jīng)講明了了。如果理解了上面所講的,那么寫程序也就是的把對應(yīng)的端口進(jìn)行設(shè)置就OK了,比較簡單的。如果不明白,可以問我,QQ或者郵件都可以,最后我會留下聯(lián)系方式的。
???? 那么下面我們開始講解一下相應(yīng)的程序語言吧。我用的單片機(jī)芯片是加強(qiáng)型的51單片機(jī)C8051F020,它都外擴(kuò)了一些功能,如AD、DA、溫度傳感器,但是核心還是沒有改變的。要與FPGA進(jìn)行通信,我用Quartus II的VHDL語言進(jìn)行編程。也就是說,單片機(jī)與FPGA都要進(jìn)行相應(yīng)的端口設(shè)置。
???? 先講解一下FPGA方面的編程,如圖5,這是在Quartus II界面里的圖形
??????????????????????
其中端口含義如下:in_num[15..0]——代表要從FPGA向單片機(jī)傳輸?shù)臄?shù)據(jù)總線
????????????????? out_num[15..0]——代表要從單片機(jī)傳送給FPGA的數(shù)據(jù)總線,它與in_num[15..0]在直
????????????????????????????????????接與其它的端口(軟件界面里面)直接與其它端口連接
????????????????? Mcu[15..0]——代表硬件上要與單片機(jī)連接的端口。
??????????????????clk---則是時鐘信號,
????????????????? en--使能信號,當(dāng)它為高的時候,則單片機(jī)向FPGA傳輸數(shù)據(jù),否則傳輸方向相反。
?? 對應(yīng)的VHDL放言如下:
library ieee;
use ieee.std_logic_1164.all;
entity interface2 is
?port(Mcu:inout std_logic_vector(15 downto 0);??????????????????
????? in_num:in std_logic_vector(15 downto 0);???????????????
????? out_Num:out std_logic_vector(15 downto 0);???????????????????
????? clk:in std_logic;
????? en:in std_logic);
end interface2;
architecture rtl of interface2 is
??? signal a,b:std_logic_vector(15 downto 0);
begin
?? common: process(clk)
?? begin
???? if(clk'event and clk='1')then
??????? a<=in_num;
??????? out_num<=b;
????? end if;
???? end process;
?? Wri_Read:process(en,Mcu)
??? begin
????? if(en='1')then??????????????????????????????????
?????????? Mcu<=(others=>'Z');????????????????????????? --
????????? b<=Mcu;?????????????????????????????????
?????? else
????????? Mcu<=a;??????????????????????????????????? --當(dāng)en='0'的時候,就作為輸出端口
?????? end if;
?? end process;
? end rtl;
?
這里有幾個注意點:一、首先最好只用一個雙向口,也就是我這里的Mcu[15..0],另外一個“雙向口”則等效成一個輸入口與一個輸出口,也就是這里in_num[15..0]與out_num[15..0].否則會有麻煩的。因為如果不這么做,那么在Quartus里面與這個雙向口相連的端口必須都要設(shè)成雙向口,這樣的話,嘿嘿...???????
二、與那個Mcu[15..0]相聯(lián)系的端口必須是雙向口的,具體圖解如下。
?
?
?? 最后,進(jìn)行單片機(jī)方面的設(shè)置了,其中最重要的就是端口初始化了。如下:
//這個是FPGA要求的,當(dāng)從FPGA里讀取數(shù)據(jù)時所要滿足的條件
//眾所周知,在雙向口的設(shè)置中,對于端口的輸入與輸出的設(shè)置是最重要的
//輸入時一定要記得把雙向口的輸出設(shè)置為高阻狀態(tài),在單片機(jī)中要記得設(shè)置為漏極開路
//當(dāng)輸出要記得把單片機(jī)設(shè)置為推挽輸出,否則設(shè)置為漏極開路的話是達(dá)不到效果 的
void? ReadData(void)
{
???? en=0;?????????????????????? //這部分要與fpga聯(lián)合起來設(shè)置???? P1MDOUT=0x00;?????????????? //此時單片機(jī)設(shè)置為漏極開路,在對端口寫1時才能呈現(xiàn)高阻狀態(tài)
? P74OUT=0x00;??????????????? //這里我用的單片機(jī)是用P1口與P4口用來傳輸數(shù)據(jù)的
? P1=0xff;??????????????????? //對應(yīng)端口寫1,設(shè)置成高阻狀態(tài)
? P4=0xff;??????????????????? //對應(yīng)端口寫1,設(shè)置成高阻狀態(tài)
}
//這個也是FPGA要求的,當(dāng)往FPGA里寫入數(shù)據(jù)時所要滿足的條件
void? WriteData(void)
{
???? en=1;?????????????????????? //當(dāng)en=1時,我要向fpga里面寫數(shù)據(jù)了,
???? P1MDOUT=0xff;?????????????? //寫數(shù)據(jù)的時候,別忘記把對應(yīng)的端口改成用推挽方式
? P74OUT=0x03;??????????????? //不用的引腳設(shè)成漏極開路的狀態(tài).當(dāng)輸出的方式時才把它設(shè)為推挽輸出
}
?
?