現(xiàn)在一般流行的做法都是用串行通信的,那樣能夠節(jié)省I/O口的。但是有的時(shí)候在端口不緊缺的時(shí)候可以考慮用并行的方法來(lái)進(jìn)行設(shè)置。這個(gè)暑假我在進(jìn)行電子競(jìng)賽的培訓(xùn),對(duì)于這個(gè)問(wèn)題找到了一些相關(guān)的資料,可以提供一些幫助。
本文引用地址:http://www.biyoush.com/article/201611/321958.htm如果是這方面的高手的話,其實(shí)會(huì)發(fā)現(xiàn)這個(gè)原理很簡(jiǎn)單,只要理解一些I/O口的設(shè)置就能完成了。但是如果對(duì)于單片機(jī)或者FPGA的I/O口的電路不理解的話可能就會(huì)走許多的歪路了。
閑話少說(shuō),進(jìn)入正題。
首先,還是要理解所謂的推挽輸出與漏極輸出兩者的區(qū)別。先說(shuō)說(shuō)漏極開(kāi)路(OD),它與集電極開(kāi)路(OC)是一致的,就是把下圖的三極管改成CMOS管就是了。
集電極開(kāi)路(OC)輸出的結(jié)構(gòu)如圖1所示,右邊的那個(gè)三極管集電極什么都不接,所以叫做集電極開(kāi)路(左邊的三極管為反相之用,使輸入為“0”時(shí),輸出也為“0”)。對(duì)于圖1,當(dāng)左端的輸入為“0”時(shí),前面的三極管截止(即集電極C跟發(fā)射極E之間相當(dāng)于斷開(kāi)),所以5V電源通過(guò)1K電阻加到右邊的三極管上,右邊的三極管導(dǎo)通(即相當(dāng)于一個(gè)開(kāi)關(guān)閉合);當(dāng)左端的輸入為“1”時(shí),前面的三極管導(dǎo)通,而后面的三極管截止(相當(dāng)于開(kāi)關(guān)斷開(kāi))。
為了方便理解,我們把上面的圖1改寫成圖2的樣子。
圖2中的開(kāi)關(guān)受軟件控制,“1”時(shí)斷開(kāi),“0”時(shí)閉合。很明顯可以看出,當(dāng)開(kāi)關(guān)閉合時(shí),輸出直接接地,所以輸出電平為0。而當(dāng)開(kāi)關(guān)斷開(kāi)時(shí),則輸出端懸空了,即高阻態(tài)。這時(shí)電平狀態(tài)未知,如果后面一個(gè)電阻負(fù)載(即使很輕的負(fù)載)到地,那么輸出端的電平就被這個(gè)負(fù)載拉到低電平了,所以這個(gè)電路是不能輸出高電平的。也就是說(shuō)這個(gè)輸出端的電平是受負(fù)載的影響的。這樣是很不穩(wěn)定的,要避免這種情況。最多的就是使用上拉電阻。
再看圖三。圖三中那個(gè)1K的電阻即是上拉電阻。如果開(kāi)關(guān)閉合,則有電流從1K電阻及開(kāi)關(guān)上流過(guò),但由于開(kāi)關(guān)閉和時(shí)電阻為0(方便我們的討論,實(shí)際情況中開(kāi)關(guān)電阻不為0,另外對(duì)于三極管還存在飽和壓降),所以在開(kāi)關(guān)上的電壓為0,即輸出電平為0。如果開(kāi)關(guān)斷開(kāi),則由于開(kāi)關(guān)電阻為無(wú)窮大(同上,不考慮實(shí)際中的漏電流),所以流過(guò)的電流為0,因此在1K電阻上的壓降也為0,所以輸出端的電壓就是5V了,這樣就能輸出高電平了。但是這個(gè)輸出的內(nèi)阻是比較大的(即1KΩ),如果接一個(gè)電阻為R的負(fù)載,通過(guò)分壓計(jì)算,就可以算得最后的輸出電壓為5*R/(R+1000)伏,即5/(1+1000/R)伏。所以,如果要達(dá)到一定的電壓的話,R就不能太小。如果R真的太小,而導(dǎo)致輸出電壓不夠的話,那我們只有通過(guò)減小那個(gè)1K的上拉電阻來(lái)增加驅(qū)動(dòng)能力(所謂的驅(qū)動(dòng)力,往往與電流有關(guān)的)。但是,上拉電阻又不能取得太小,因?yàn)楫?dāng)開(kāi)關(guān)閉合時(shí),將產(chǎn)生電流,由于開(kāi)關(guān)能流過(guò)的電流是有限的,因此限制了上拉電阻的取值,另外還需要考慮到,當(dāng)輸出低電平時(shí),負(fù)載可能還會(huì)給提供一部分電流從開(kāi)關(guān)流過(guò),因此要綜合這些電流考慮來(lái)選擇合適的上拉電阻。
P.S:說(shuō)到OC門的話,大家都能想到三態(tài)門,那么就不得不提起它的“線與”功能了,這個(gè)功能是很方便的。操作上面也很簡(jiǎn)單。如下附圖:
另一種輸出結(jié)構(gòu)是推挽輸出。推挽輸出的結(jié)構(gòu)就是把上面的上拉電阻也換成一個(gè)開(kāi)關(guān),當(dāng)要輸出高電平時(shí),上面的開(kāi)關(guān)通,下面的開(kāi)關(guān)斷;而要輸出低電平時(shí),則剛好相反。比起OC或者OD來(lái)說(shuō),這樣的推挽結(jié)構(gòu)高、低電平驅(qū)動(dòng)能力都很強(qiáng)。如果兩個(gè)輸出不同電平的輸出口接在一起的話,就會(huì)產(chǎn)生很大的電流,有可能將輸出口燒壞。而上面說(shuō)的OC或OD輸出則不會(huì)有這樣的情況,因?yàn)樯侠娮杼峁┑碾娏鞅容^小。如果是推挽輸出的要設(shè)置為高阻態(tài)時(shí),則兩個(gè)開(kāi)關(guān)必須同時(shí)斷開(kāi)(或者在輸出口上使用一個(gè)傳輸門),這樣可作為輸入狀態(tài),有些單片機(jī)的一些IO口就是這種結(jié)構(gòu)。
總結(jié):從上面也可以知道了,I/0輸出有兩種方式。那么現(xiàn)在的難點(diǎn)就是如何讓I/0口輸入數(shù)據(jù)。其實(shí)上面已經(jīng)講過(guò)了,就是只需要把輸出設(shè)置為高阻狀態(tài)就可以了。那么有些新人就會(huì)問(wèn)了,都設(shè)成高阻狀態(tài)了,數(shù)據(jù)還怎么輸入???這其實(shí)是一個(gè)誤區(qū),其根本是沒(méi)有理解I/O口的結(jié)構(gòu)。
如果我們將一個(gè)讀數(shù)據(jù)用的輸入端接在輸出端(這就是上面疑惑的答案了),這樣就是一個(gè)IO口了(51的IO口就是這樣的結(jié)構(gòu),其中P0口內(nèi)部不帶上拉,而其它三個(gè)口帶內(nèi)部上拉),如圖4所示。當(dāng)我們要使用輸入功能時(shí),只要將輸出口設(shè)置為1即可,也就是要把下面的z=1,這樣就相當(dāng)于那個(gè)開(kāi)關(guān)斷開(kāi),而對(duì)于P0口來(lái)說(shuō),就是高阻態(tài)了。
到現(xiàn)在為止,已經(jīng)把輸入輸出端口原理已經(jīng)講明了了。如果理解了上面所講的,那么寫程序也就是的把對(duì)應(yīng)的端口進(jìn)行設(shè)置就OK了,比較簡(jiǎn)單的。如果不明白,可以問(wèn)我,QQ或者郵件都可以,最后我會(huì)留下聯(lián)系方式的。
評(píng)論