關(guān)于GPIO你真的懂了嗎?這篇文章都給你整理好了!
一、前言
GPIO全稱General Purpose Input Output即通用輸入/輸出,其實(shí)GPIO的本質(zhì)就是芯片的一個(gè)引腳,通常在ARM中所有的I/O都是通用的。不過(guò)由于每個(gè)開發(fā)板上都會(huì)設(shè)計(jì)不同的外圍電路,這就造成GPIO的功能可能有所不同,大部分GPIO都是有復(fù)用功能的,比如有些GPIO可能是串口的TX或RX,也可能是I2C的SCL或SDA線。
所以我們不僅要知道GPIO能夠輸出高低電平,還要理解為什么有些GPIO可以復(fù)用某些功能,而其他的不可以。
二、GPIO內(nèi)部結(jié)構(gòu)
我們?cè)谑褂肎PIO的時(shí)候可能不會(huì)去想為什么我們通過(guò)寫代碼或者操作寄存器就可以控制一個(gè)引腳的高低電平。
今天就讓我們一起來(lái)看看為什么我們通過(guò)操作寄存器(其實(shí)寫代碼的過(guò)程就是在操作寄存器)就能控制引腳輸入或者輸出。
我們想要想控制一個(gè)GPIO口的需要操作7個(gè)寄存器,分別是CRL,CRH,IDR,ODR,BRR,BSRR,LCKR我們對(duì)GPIO的操作本質(zhì)上就是在對(duì)這些寄存器進(jìn)行讀寫操作,以下是這些寄存器的名稱:
GPIOx_CRL(x = A..E)端口配置低寄存器 32位寄存器 GPIOx_CRH(x = A..E)端口配置高寄存器 32位寄存器 GPIOx_IDR(x = A..E)端口輸入數(shù)據(jù)寄存器 32位寄存器但僅用低16位 GPIOx_ODR(x = A..E)端口輸出數(shù)據(jù)寄存器 32位寄存器但僅用低16位 GPIOx_BRR(x = A..E)端口位清除寄存器 16位寄存器 GPIOx_BSRR(x = A..E)端口位設(shè)置/清除寄存器 16位寄存器 GPIOx_LCKR(x = A..E)端口配置鎖定寄存器 32位寄存器
我們首先分析上面的結(jié)構(gòu)電路:
1、保護(hù)二極管: 保護(hù)二極管從它的名字就不難想到他是用來(lái)對(duì)系統(tǒng)進(jìn)行保護(hù)的,通過(guò)兩個(gè)二極管的導(dǎo)通可以防止引腳外部輸入電壓過(guò)低或過(guò)高。當(dāng)電壓過(guò)高時(shí),上方的保護(hù)二極管導(dǎo)通。當(dāng)電壓過(guò)低時(shí),下方的二極管導(dǎo)通,防止不正常電壓導(dǎo)入到芯片內(nèi)部造成芯片燒毀。
2、P·MOS管和N·MOS管: GPIO經(jīng)過(guò)兩個(gè)二極管的保護(hù)后向上流入輸入模式,向下流入輸出模式,而輸出模式的控制是由一個(gè)由P·MOS管和N·MOS管組成的單元電路,該電路主要是控制輸出的模式,由該結(jié)構(gòu)狗策劃給你的單元電路具有推挽輸出和開漏輸出兩種模式。
當(dāng)系統(tǒng)配置為推挽輸出模式時(shí):
-
若向該結(jié)構(gòu)中輸入高電平,經(jīng)過(guò)反向后,上方的P-MOS導(dǎo)通,下方的N-MOS關(guān)閉,對(duì)外輸出高電平;
-
若向該結(jié)構(gòu)中輸入低電平時(shí),經(jīng)過(guò)反向后,下方的N-MOS管導(dǎo)通,上方的P-MOS關(guān)閉,對(duì)外輸出低電平。
-
當(dāng)引腳高低電平切換時(shí),兩個(gè)MOS管輪流導(dǎo)通,P管負(fù)責(zé)灌電流,N管負(fù)責(zé)拉電流,使其負(fù)載能力和開關(guān)速度都比普通的方式有很大的提高。**推挽輸出的低電平為0V,高電平為3.3V**。
當(dāng)系統(tǒng)配置為開漏輸出模式時(shí):
-
上方的P-MOS管完全不工作;
-
如果我們控制輸出為0,低電平,則P-MOS管關(guān)閉,N-MOS管導(dǎo)通,使輸出接地;
-
若控制輸出為1(它無(wú)法直接輸出高電平)時(shí),則P-MOS管和N-MOS管都關(guān)閉,所以開漏輸出模式下引腳既不輸出高電平,也不輸出低電平,為高阻態(tài)。
推挽輸出模式一般應(yīng)用在輸出電平為0和3.3V而且需要高速切換開關(guān)狀態(tài)的場(chǎng)合。開漏輸出模式一般應(yīng)用在I2C、SMBUS通信等需要 線與功能的總線電路中。
在單片機(jī)中除了必須用開漏模式的場(chǎng)合,一般習(xí)慣使用推挽輸出模式
3、輸出數(shù)據(jù)寄存器:前面我們知道雙了MOS管結(jié)構(gòu)電路的輸入信號(hào),是由GPIO輸出數(shù)據(jù)寄存器GPIOx_ODR提供的,因此我們可以通過(guò)修改輸出數(shù)據(jù)寄存器的值,就可以修改GPIO引腳的輸出電平。而置位/復(fù)位寄存器GPIOx_BSRR可以通過(guò)修改輸出數(shù)據(jù)寄存器的值,從而影響電路的輸出。
4、復(fù)用功能輸出:復(fù)用功能輸出中的復(fù)用是指STM32的其他片上外設(shè)對(duì)GPIO引腳進(jìn)行控制,此時(shí)GPIO引腳用作該外設(shè)功能的一部分,算是第二用途。從其他外設(shè)引出來(lái)的復(fù)用功能輸出信號(hào)與GPIO本身的數(shù)據(jù)寄存器都連接到雙MOS管結(jié)構(gòu)的輸入中。
三、輸入輸出模式
GPIO共有8中輸入輸出模式,分別是:上拉輸入、下拉輸入、浮空輸入、模擬輸入、開漏輸出、推挽輸出、開漏復(fù)用輸出、推挽復(fù)用輸出,下面我們?cè)敿?xì)介紹以下上面的八種輸入輸出模式。
- 上拉輸入: GPIO_Mode_IPU
- 下拉輸入: GPIO_Mode_IPD
- 浮空輸入: GPIO_Mode_IN_FLOATING
- 模擬輸入: GPIO_Mode_AIN
- 開漏輸出: GPIO_Mode_Out_OD
- 推挽輸出: GPIO_Mode_Out_PP
- 開漏復(fù)用: GPIO_Mode_AF_OD
- 推完復(fù)用: GPIO_Mode_AF_PP
這里詳細(xì)講一下幾個(gè)常用的模式:
3.1 浮空輸入
浮空輸入模式下,I/O端口的電平信號(hào)直接進(jìn)入輸入數(shù)據(jù)寄存器。也就是說(shuō),I/O的電平狀態(tài)是不確定的,完全由外部輸入決定;如果在該引腳懸空(在無(wú)信號(hào)輸入)的情況下,讀取該端口的電平是不確定的,通常用于IIC、USART等總線設(shè)備上。
3.2 上拉輸入模式
上拉輸入模式下,I/O端口的電平信號(hào)直接進(jìn)入輸入數(shù)據(jù)寄存器。但是在I/O端口懸空(在無(wú)信號(hào)輸入)的情況下,輸入端的電平保持在高電平(并且在I/O端口輸入為低電平的時(shí)候,輸入端的電平也是低電平)
3.3 下拉輸入模式
下拉輸入模式下,I/O端口的電平信號(hào)直接進(jìn)入輸入數(shù)據(jù)寄存器。但是在I/O端口懸空(在無(wú)信號(hào)輸入)的情況下,輸入端的電平保持在低電平;并且在I/O端口輸入為高電平的時(shí)候,輸入端的電平也是高電平。
3.4 模擬輸入模式
模擬輸入模式下,I/O端口的模擬信號(hào)(電壓信號(hào),而非電平信號(hào))直接模擬輸入到片上外設(shè)模塊,比如ADC模塊等。
3.5 開漏輸出模式
見上面二中的詳細(xì)介紹;
3.6 開漏復(fù)用輸出模式
開漏復(fù)用輸出模式,與開漏輸出模式很是類似。只是輸出的高低電平的來(lái)源,不是讓CPU直接寫輸出數(shù)據(jù)寄存器,取而代之利用片上外設(shè)模塊的復(fù)用功能輸出來(lái)決定的,一般用于片內(nèi)外設(shè)功能:TX1,MOSI,MISO,SCK,SS
3.7 推挽輸出模式
見上面二中的詳細(xì)介紹;
3.8 推挽復(fù)用輸出模式
推挽復(fù)用輸出模式,與推挽輸出模式很是類似。只是輸出的高低電平的來(lái)源,不是讓CPU直接寫輸出數(shù)據(jù)寄存器,而是利用片上外設(shè)模塊的復(fù)用功能輸出來(lái)決定的,常見采用推挽輸出模式的一般為片內(nèi)外設(shè)功能IIC的SCL、SDL。
四、開漏輸出和推挽輸出的區(qū)別
開漏輸出和推挽輸出模式的區(qū)別主要是開漏輸出只可以輸出強(qiáng)低電平,高電平得靠外部電阻拉高。輸出端相當(dāng)于三極管的集電極,適合于做電流型的驅(qū)動(dòng),其吸收電流的能力相對(duì)強(qiáng)(一般20ma以內(nèi));推挽輸出可以輸出強(qiáng)高、低電平,連接數(shù)字器件。
五、STM32中GPIO的配置
在固件庫(kù)開發(fā)中,操作寄存器CRH和CRL來(lái)配置IO口的模式和速度是通過(guò)GPIO初始化函數(shù)完成:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); /*第一個(gè)參數(shù)是用來(lái)指定 GPIO,取值范圍為 GPIOA~GPIOG。
*第二個(gè)參數(shù)為初始化參數(shù)結(jié)構(gòu)體指針,結(jié)構(gòu)體類型為 GPIO_InitTypeDef
*/
初始化 GPIO 的常用格式是:
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-- PB.5 端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度 50MHz GPIO_Init(GPIOB, GPIO_InitStructure);//根據(jù)設(shè)定參數(shù)配置 GPIO
IO口速度設(shè)置有三個(gè)可選值:
typedef enum { GPIO_Speed_10MHz, GPIO_Speed_2MHz, GPIO_Speed_50MHz }GPIOSpeed_TypeDef;
模式則有8個(gè)可選定義如下:
typedef enum { GPIO_Mode_AIN = 0x0, //模擬輸入 GPIO_Mode_IN_FLOATING = 0x04, //浮空輸入 GPIO_Mode_IPD = 0x28, //下拉輸入 GPIO_Mode_IPU = 0x48, //上拉輸入 GPIO_Mode_Out_OD = 0x14, //開漏輸出 GPIO_Mode_Out_PP = 0x10, //通用推挽輸出 GPIO_Mode_AF_OD = 0x1C, //復(fù)用開漏輸出 GPIO_Mode_AF_PP = 0x18 //復(fù)用推挽 }GPIOMode_TypeDef;
六、總結(jié)
本文主要介紹了GPIO的定義和GPIO不同模式間的區(qū)別與實(shí)現(xiàn)方式,觀看完本文相信你對(duì)于GPIO會(huì)有一個(gè)更深的理解,我們?nèi)绻亲鲕浖目梢圆挥锰P(guān)注于GPIO是如何實(shí)現(xiàn)的,但是我們需要知道每個(gè)模式下GPIO的特點(diǎn)和應(yīng)用場(chǎng)合,只有這樣我們?cè)趯?shí)際應(yīng)用中才能更好的配置出最合適的那個(gè)。