標準51內核單片機的IO口:
P0口則為雙向三態輸入輸出口
P1\P2\P3是準雙向IO口,沒有方向控制,做輸入時需要先往端口數據寄存器寫1才行(也可看作此時為輸出,端口輸出高電平)。
初始狀態和復位狀態下準雙向口為1,雙向口為高阻狀態
P0口:雙向8位三態I/O口
P1口:準雙向8位I/O口
P2口:準雙向8位I/O口
P3口:準雙向8位I/O口
這里特別要主要準雙向與雙向三態I/O的區別:
P1口,P2口,P3口是3個8位準雙向的I/O口,各口線在片內均有固定的上拉電阻,當這三個準雙向I/O口作輸入口使用時,要想該口先寫1,另外準雙向I/O口無高阻的“浮空”狀態。
而雙向口P0口線內無固定上拉電阻,由兩個MOS管串接,既可開漏輸出(開漏輸出,本博客有解釋)有可處于高阻的“浮空”狀態,故稱為雙向三態I/O口。
?。剩⒕褪牵⒒旧希⒌囊馑迹?/p>
P0口是雙向指的是它被用作地址/數據端口時,只有在這個時候,P0口才處于兩個開關管推挽狀態,當兩個開關管都關閉時,才會出現高阻狀態.
當P0口用于一般I/O口時,內部接Vcc的那個開關管是與引腳(端口)脫離聯系的,這個時候,只有拉地的那個開關管其作用,P0口作為輸出,是必須外接上拉電阻的,不然就無法輸出高電平;如果P0口作為輸入,則必須先對端口寫1,使拉地的開關管斷開,這個時候,如果不接上拉電阻,則是高阻狀態,就是一個雙向口,如果接上拉電阻,則本身輸出高電平,對輸入信號的邏輯無影響(注意是對邏輯無影響,對實際參數有無影響我不確定,但是我認為是有的).
雙向與準雙向,根本原則是雙向包含了高阻這個狀態,而不在于是否需要先寫1或者不寫,P1~P3口因為有內部上拉電阻,因此無論如何不是雙向;P0口內部無上拉電阻,在處于數據/地址功能時,自動完成3態的轉換,是雙向,處于一般I/O口時,如果不接外部上拉,而且先向端口寫了1,那么就處于高阻狀態,此時,它也是一個人為的雙向口,這與它處于地址/數據功能時的自動雙向有區別,以及與P1~P3處于輸入時輸出鎖存器為1是有區別的。
簡單說:
?。?) P0口無固定上拉電阻。P1,P2,P3有。
?。?) 就是P0口作為輸入輸出口時,為了能讓內部1能正確輸出,要接上拉電阻(如果不接的話,內部D=1的時候,Q非=0,V1被截止,V1,V2都處于截止狀態,不能正確反映1,所以需要上拉電阻。),在讀取輸入的時候,因為此時P0口是作為一個準雙向口,所以得先向外寫1,不然的話,如果鎖存器曾經鎖存過0,則V1被導通,PO.x被鉗制在低電平,不能正確反映輸入。
(3)P0口作為地址/數據口的時候,由于訪問外部存儲器期間,CPU會自動向PO口的鎖存器寫入0FFH,對用戶而言,PO口此時才是真正的三態雙向口。
單片機I/O口的結構的詳解
我們先來說說集電極開路輸出的結構。集電極開路輸出的結構如圖1所示,右邊的那個三極管集電極什么都不接,所以叫做集電極開路(左邊的三極管為反相之用,使輸入為“0”時,輸出也為“0”)。對于圖1,當左端的輸入為“0”時,前面的三極管截止(即集電極c跟發射極e之間相當于斷開),所以5v電源通過1k電阻加到右邊的三極管上,右邊的三極管導通(即相當于一個開關閉合);當左端的輸入為“1”時,前面的三極管導通,而后面的三極管截止(相當于開關斷開)。
我們將圖1簡化成圖2的樣子。圖2中的開關受軟件控制,“1”時斷開,“0”時閉合。很明顯可以看出,當開關閉合時,輸出直接接地,所以輸出電平為0。而當開關斷開時,則輸出端懸空了,即高阻態。這時電平狀態未知,如果后面一個電阻負載(即使很輕的負載)到地,那么輸出端的電平就被這個負載拉到低電平了,所以這個電路是不能輸出高電平的。
再看圖三。圖三中那個1k的電阻即是上拉電阻。如果開關閉合,則有電流從1k電阻及開關上流過,但由于開關閉和時電阻為0(方便我們的討論,實際情況中開關電阻不為0,另外對于三極管還存在飽和壓降),所以在開關上的電壓為0,即輸出電平為0。如果開關斷開,則由于開關電阻為無窮大(同上,不考慮實際中的漏電流),所以流過的電流為0,因此在1k電阻上的壓降也為0,所以輸出端的電壓就是5v了,這樣就能輸出高電平了。但是這個輸出的內阻是比較大的(即1kω),如果接一個電阻為r的負載,通過分壓計算,就可以算得最后的輸出電壓為5*r/(r+1000)伏,即5/(1+1000/r)伏。所以,如果要達到一定的電壓的話,r就不能太小。如果r真的太小,而導致輸出電壓不夠的話,那我們只有通過減小那個1k的上拉電阻來增加驅動能力。但是,上拉電阻又不能取得太小,因為當開關閉合時,將產生電流,由于開關能流過的電流是有限的,因此限制了上拉電阻的取值,另外還需要考慮到,當輸出低電平時,負載可能還會給提供一部分電流從開關流過,因此要綜合這些電流考慮來選擇合適的上拉電阻。
如果我們將一個讀數據用的輸入端接在輸出端,這樣就是一個io口了(51的io口就是這樣的結構,其中p0口內部不帶上拉,而其它三個口帶內部上拉),當我們要使用輸入功能時,只要將輸出口設置為1即可,這樣就相當于那個開關斷開,而對于p0口來說,就是高阻態了。
對于漏極開路(od)輸出,跟集電極開路輸出是十分類似的。將上面的三極管換成場效應管即可。這樣集電極就變成了漏極,oc就變成了od,原理分析是一樣的。
另一種輸出結構是推挽輸出。推挽輸出的結構就是把上面的上拉電阻也換成一個開關,當要輸出高電平時,上面的開關通,下面的開關斷;而要輸出低電平時,則剛好相反。比起oc或者od來說,這樣的推挽結構高、低電平驅動能力都很強。如果兩個輸出不同電平的輸出口接在一起的話,就會產生很大的電流,有可能將輸出口燒壞。而上面說的oc或od輸出則不會有這樣的情況,因為上拉電阻提供的電流比較小。如果是推挽輸出的要設置為高阻態時,則兩個開關必須同時斷開(或者在輸出口上使用一個傳輸門),這樣可作為輸入狀態,avr單片機的一些io口就是這種結構。
.AVR單片機IO口的結構分析
AVR的IO是真正雙向IO結構,由于大部分網友都是從標準51轉過來的,受標準51的準雙向IO和布爾操作概念影響,沒能掌握AVR的IO操作,所以有必要撰文說明一下,其實采用真正雙向IO結構的新型MCU很多,常用的有增強型51,PIC,AVR等。
先簡單的回顧一下標準51的準雙向IO結構
這種準雙向IO結構的特點是
1 輸出結構類似 OC門,輸出低電平時,內部NMOS導通,驅動能力較強(800uA);輸出高電平靠內部上拉電阻,驅動能力弱(60uA)。
2 永遠有內部電阻上拉(P0口除外),高電平輸出電流能力很弱,所以即使IO口長時間短路到地也不會損壞IO口
?。ㄍ?,IO口低電平輸出能力較強,作低電平輸出時不能長時間短路到VCC)
3 作輸入時,因為OC門有“線與”特性,必須把IO口設為高電平(所以按鍵多為共地接法)
4 作輸出時,輸出低電平可以推動LED(也是很弱的),輸出高電平通常需要外接緩沖電路(所以LED多為共陽接法)
5 軟件模擬 OC結構的總線反而比較方便-----例如 IIC總線
* P0口比較特殊,做外部總線時,是推挽輸出,做普通IO時沒有內部上拉電阻,所以P0口做按鍵輸入需要外接上拉電阻。
* OC門:三極管的叫集電極開路,場效應管的叫漏極開路,簡稱開漏輸出。具備“線與”能力,有0得0。
* 為什么設計成輸出時高電平弱,低電平強----是考慮了當年流行的TTL器件輸入特性
相信我們大多數人都接觸過51單片機,51單片機的I/O口是準雙向I/O口。其實這種說法是不嚴謹的,我們知道,51單片機有4個I/O口,分別是P0、P1、P2、P3,這4個I/O口的結構并不完全一致,其中P0口是標準的雙向I/O口,而P1、P2、P3則是準雙向I/O口。
關于準雙向I/O口和雙向I/O口的區別請看另一篇文章“準雙向I/O口和標準雙向I/O口的區別”
AVR單片機的I/O口是標準的雙向I/O口,它的IO結構就就比51的I/O口復雜多了,單是控制端口的寄存器就有3個 PORTx(數據寄存器)、DDRx(數據方向寄存器)、PINx(端口輸入引腳);另外還有一個SFIOR(特殊功能I/O寄存器),這個寄存器中的PUD位控制全部I/O口的上拉電阻是允許還是被禁止。
下圖是AVR單片機通用I/O口結構示意圖:
從圖中可以看出,每組I/O口配備三個8位寄存器,它們分別是數據方向寄存器DDRx,數據寄存器PORTx,和輸入引腳寄存器PINx(x表示端口序號)。I/O口的工作方式和表現特征由這3個I/O口寄存器控制
數據方向寄存器DDRx用于控制I/O口的輸入輸出方向,即控制I/O口的工作方式為輸出方式還是輸入方式。
當DDRx=1時,I/O口處于輸出工作方式。此時數據寄存器PORTx中的數據通過一個推挽電路輸出到外部引腳,如下圖。AVR的輸出采用推挽電路提高了I/O口的輸出能力,當PORTx=1時,I/O引腳呈現高電平,同時可提供輸出20mA的電流;而當PORTx=0時,I/O引腳呈現低電平,同時可吸納20mA電流。因此,AVR的I/O在輸出方式下提供了比較大的驅動能力,可以直接驅動LED等小功率外圍器件。
當DDRx=0時,I/O處于輸入工作方式。此時引腳寄存器PINx中的數據就是外部引腳的實際電平,通過讀I/O指令可將物理引腳的真實數據讀入MCU。此外,當I/O口定義為輸入時(DDRx=0),通過PORTx的控制,可使用或不使用內部的上拉電阻,如下圖:
AVR單片機通用I/O端口的主要特點為:
雙向可獨立位控的I/O口
ATmega16的PA、PB、PC、PD四個端口都是8位雙向I/O口,每一位引腳都可以單獨的進行定義,相互不受影響。如用戶可以在定義PA口第0、2、3、4、5、6位用于輸入的同時定義第1、7位用于輸出,互不影響。
Push-Pull大電流驅動(最大40mA)
可控制的引腳內部上拉電阻
每一位引腳內部都有獨立的,可通過編程設置的,設定為上拉有效或無效的內部上拉電阻。當I/O口被用于輸入狀態,且內部上拉電阻被激活(有效)時,如果外部引腳被拉低,則構成電流源輸出電流(uA量級)。
DDRx可控的方向寄存器。
AVR的I/O端口結構同其它類型單片機的明顯區別是,AVR采用3個寄存器來控制I/O端口。一般單片機的I/O僅有數據寄存器和控制寄存器,而AVR還多了一個方向控制器,用于控制I/O的輸入輸出方向。由于輸入寄存器PINx實際不是一個寄存器,而是一個可選通的三態緩沖器,外部引腳通過該三態緩沖器與MCU的內部總線連接,因此,讀PINx時是讀取外部引腳上的真實和實際邏輯值,實現了外部信號的同步輸入。這種結構的I/O端口,具備了真正的讀-修改-寫(Read-Modify-Write)特性。
AVR單片機通用I/O口設計注意事項:
數據寄存器PORTx和數據方向寄存器DDRx為讀/ 寫寄存器,而端口輸入引腳PINx為只讀寄存器。
但是需要特別注意的是,對PINx 寄存器某一位寫入邏輯“1“ 將造成數據寄存器相應位的數據發生”0“ 與“1“ 的交替變化。
當寄存器MCUCR 的上拉電阻禁止位PUD置位時所有端口引腳的上拉電阻都被禁止。
在 高阻態和輸出高電平 兩種狀態之間進行切換時,上拉電阻使能或輸出低電平這兩種模式必然會有一個發生。編寫程序時要注意兩者的順序。
通常,上拉電阻使能是完全可以接受的,因為高阻狀態下強高電平輸出還是上拉輸出都是可以接受的。
如果使用情況不是這樣,可以通過置位SFIOR 寄存器的PUD 來禁止所有端口的上拉電阻。
在上拉輸入和輸出低電平之間切換也有同樣的問題。
用戶必須選擇高阻態或輸出高電平作為中間步驟。
不論如何配置DDxn,都可以通過讀取PINxn 寄存器來獲得引腳電平
PINxn寄存器的各個位與其前面的鎖存器組成了一個同步器。
這樣就可以避免在內部時鐘狀態發生改變的短時間范圍內由于引腳電平變化而造成的信號不穩定。
其缺點是引入了延遲。
AVR IO具備多種IO模式:
1 高阻態 ,多用于高阻模擬信號輸入,例如ADC數模轉換器輸入,模擬比較器輸入
2 弱上拉狀態(Rup=20K~50K),輸入用。為低電平信號輸入作了優化,省去外部上拉電阻,例如按鍵輸入,低電平中斷觸發信號輸入
3 推挽強輸出狀態,驅動能力特強(》20mA),可直接推動LED,而且高低驅動能力對稱。
使用注意事項:
寫用PORTx,讀取用PINx
實驗時,盡量不要把管腳直接接到GND/VCC,當設定不當,IO口將會輸出/灌入 80mA(Vcc=5V)的大電流,導致器件損壞。
作輸入時:
1、通常要使能內部上拉電阻,懸空(高阻態)將會很容易受干擾。(表面看好像是51的抗干擾能力強,是因為51永遠有內部電阻上拉,)
2、盡量不要讓輸入懸空或模擬輸入電平接近VCC/2,將會消耗太多的電流,特別是低功耗應用場合------CMOS電路的特點
3、如果先前I/O口為輸出狀態,設置為輸入狀態后,必須等待1個時鐘周期后才能正確的讀到外部引腳PINx的值。
4、功能模塊(中斷,定時器)的輸入可以是低電平觸發,也可以是上升沿觸發或下降沿觸發。
5、用于高阻模擬信號輸入,切記不要使能內部上拉電阻,影響精確度。例如ADC數模轉換器輸入,模擬比較器輸入
作輸出時:
采用必要的限流措施,例如驅動LED要串入限流電阻
復位時:
復位時內部上拉電阻將被禁用。如果應用中(例如電機控制)需要嚴格的電平控制,請使用外接電阻固定電平
休眠時:
作輸出的,依然維持狀態不變
作輸入的,一般無效,但如果使能了第二功能(中斷使能),其輸入功能有效。例如 外部中斷的喚醒功能。
AVR的C語言IO操作:
AVR的C語言基于ANSI C,沒有像51那樣擴展了位操作(布爾操作),雖然匯編指令里面有SBI/CBI/SBIC/SBIS指令, 所以需要采用 位邏輯運算來實現,這是必須要掌握的。
IO口和功能寄存器的操作方法一樣,但對于部分功能寄存器的讀寫有特殊要求,請參看手冊。
不必考慮代碼效率的問題,如果可能,GCCAVR會自動優化為SBI/CBI/SBIC/SBIS指令,跟匯編的效率是一樣的。
例如 iom16.h 里面定義了 #define PA7 7
(這標準頭文件定義了MCU的所有官方定義(包括寄存器,位,中斷入口等),但管腳的第二功能沒有定義)
想PA7為1 PORTA|=(1《《PA7);
想PA7為0 PORTA&=~(1《《PA7);
想PA7取反 PORTA^=(1《《PA7);
想檢測PA7是否為1 if (PINA&(1《《PA7)) { };
想檢測PA7是否為0 if ?。≒INA&(1《《PA7)) { };
* 《《 為左移運算符,不懂的就要好好復習C語言基礎了。
注意IO操作的順序:
//上電默認DDRx=0x00,PORTx=0x00 輸入,無上拉電阻
假設PA口驅動LED的負極,低電平燈亮
初始化方法1:
PORTA=0xFF; //內部上拉,高電平
DDRA=0xFF; //輸出高電平---------燈一直是滅的
初始化方法2:
DDRA=0xFF; //輸出低電平--------燈被錯誤點亮了
PORTA=0xFF; //輸出高電平--------馬上被熄滅了,時間很短(1個指令不到uS時間),燈閃了一下,眼睛無法察覺
但要是這個IO口是控制炸藥包的點火信號呢?工控場合要考慮可靠性的問題
模擬OC結構的IIC總線的技巧:
雖然AVR大多帶有硬件IIC接口,但也有需要使用軟件模擬IIC的情況
可以通過使用外部上拉電阻+控制DDRx的方法來實現OC結構的IIC總線。
IIC的速度跟上拉電阻有關,內部的上拉電阻阻值較大(Rup=20K~50K),只能用于低速的場合
#define SDA 0 //PC0
#define SCL 1 //PC1
?。ǔ绦虺跏蓟O定 SDA和SCL都是 PORT=0,DDR=0)
#define SDA_0() DDRA|=(1《《SDA) //輸出低電平
#define SDA_1() DDRA&=~(1《《SDA) //輸入,外部電阻上拉為高電平
#define SCL_0() DDRA|=(1《《SCL) //輸出低電平
#define SCL_1() DDRA&=~(1《《SCL) //輸入,外部電阻上拉為高電平
使用上面的SDA_0()/SDA_1()/SCL_0()/SCL_1()宏即可,直觀,而且效率跟匯編是一樣的
3.PIC單片機端口的概述
PIC單片機的IO口,特別是第二功能的AD口,當端口被配置為AD模擬輸入時,誤以為端口用作普通的IO口時,去讀取相應的端口,然而讀進來的數據不確定。(例如:用萬用表測量該管腳的電壓為4.0V,但是讀進來的數據始終為低電平),這是由于PIC單片機的IO口有一個弱上拉(用MOS 管的開關代替),當端口被配置為AD模擬輸入時,弱上拉disable,則單片機的IO口呈現為高阻狀態。(可參照PIC單片機的DATASHEET)
在數字電路中不用的輸入腳都要接固定電平,通過1k電阻接高電平或接地。
1. 電阻作用:
l 接電組就是為了防止輸入端懸空
l 減弱外部電流對芯片產生的干擾
l 保護cmos內的保護二極管,一般電流不大于10ma
l 上拉和下拉、限流
l 1. 改變電平的電位,常用在ttl-cmos匹配
2. 在引腳懸空時有確定的狀態
3.增加高電平輸出時的驅動能力。
4、為oc門提供電流
l 那要看輸出口驅動的是什么器件,如果該器件需要高電壓的話,而輸出口的輸出電壓又不夠,就需要加上拉電阻。
l 如果有上拉電阻那它的端口在默認值為高電平你要控制它必須用低電平才能控制如三態門電路三極管的集電極,或二極管正極去控制把上拉電阻的電流拉下來成為低電平。反之,
l 尤其用在接口電路中,為了得到確定的電平,一般采用這種方法,以保證正確的電路狀態,以免發生意外,比如,在電機控制中,逆變橋上下橋臂不能直通,如果它們都用同一個單片機來驅動,必須設置初始狀態。防止直通!
2、定義:
l 上拉就是將不確定的信號通過一個電阻嵌位在高電平!電阻同時起限流作用!下拉同理!
l 上拉是對器件注入電流,下拉是輸出電流
l 弱強只是上拉電阻的阻值不同,沒有什么嚴格區分
l 對于非集電極(或漏極)開路輸出型電路(如普通門電路)提升電流和電壓的能力是有限的,上拉電阻的功能主要是為集電極開路輸出型電路輸出電流通道。
3、為什么要使用拉電阻:
l 一般作單鍵觸發使用時,如果ic本身沒有內接電阻,為了使單鍵維持在不被觸發的狀態或是觸發后回到原狀態,必須在ic外部另接一電阻。
l 數字電路有三種狀態:高電平、低電平、和高阻狀態,有些應用場合不希望出現高阻狀態,可以通過上拉電阻或下拉電阻的方式使處于穩定狀態,具體視設計要求而定!
l 一般說的是i/o端口,有的可以設置,有的不可以設置,有的是內置,有的是需要外接,i/o端口的輸出類似與一個三極管的c,當c接通過一個電阻和電源連接在一起的時候,該電阻成為上c拉電阻,也就是說,如果該端口正常時為高電平,c通過一個電阻和地連接在一起的時候,該電阻稱為下拉電阻,使該端口平時為低電平,作用嗎:
比如:當一個接有上拉電阻的端口設為輸如狀態時,他的常態就為高電平,用于檢測低電平的輸入。
l 上拉電阻是用來解決總線驅動能力不足時提供電流的。一般說法是拉電流,下拉電阻是用來吸收電流的,也就是你同學說的灌電流
線驅動(差動輸出)
線驅動器是一個源電流輸出器件。在導通狀態時,線驅動器輸出為電源(vcc);在關斷狀態時,輸出懸空。因此,線驅動器需要一個灌電流輸入接口。下面表格中給出了一個簡單的線驅動器的原理圖。差動輸出(歐姆龍稱為線性驅動輸出)線性驅動輸出就是根據rs-422a的數據輸送回路??赏ㄟ^雙股攪合線電纜進行長距離輸送
集電極開路
集電極開路電路是灌電流輸出器件。在關斷狀態時,集電極開路輸出連到地;在導通狀態時,集電極開路輸出懸空。因此,集電極開路輸出需要一個源電流輸入接口。下面表格中給出了一個簡單的集電極開路輸出電路的原理圖。
推挽式
推挽式輸出結合了線驅動與集電極開路輸出,在關斷狀態時,推挽式輸出接地;在導通狀態時,推挽式輸出連到電源(vcc)。推挽輸出(歐姆龍稱為互補輸出)輸出回路有2種,即npn與pnp2種晶體管輸出。根據輸出信號h或l,2種晶體管輸出互相交叉進行on或off動作,使用時,正電源,0v分別為吸合,拉下互補輸出是輸出電流流出或流入2種動作,特征是信號的上升、下降速度快,可進行導線的長距離延長??膳c開路集電極輸入機器(npn/pnp)連接,另外還可以連接到電壓輸入機器上。但是為了能更好的發揮未來的性能,一般推薦在電壓輸入機器上使用電壓輸入的編碼器。
評論
查看更多