GPIO(General-purpose input/output)是通用輸入輸出端口的簡稱,CKS32F4xx系列產(chǎn)品通過GPIO引腳與外部設(shè)備連接起來,從而實(shí)現(xiàn)與外部通訊、控制以及數(shù)據(jù)采集的功能。最基本的輸出功能是由CKS32F4xx系列產(chǎn)品控制引腳輸出高、低電平,實(shí)現(xiàn)開關(guān)控制,如把GPIO引腳接入到LED燈,那就可以控制LED燈的亮滅,引腳接入到繼電器或三極管,那就可以通過繼電器或三極管控制外部大功率電路的通斷。最基本的輸入功能是檢測(cè)外部輸入電平,如把 GPIO引腳連接到按鍵,通過電平高低區(qū)分按鍵是否被按下。
GPIO硬件結(jié)構(gòu)框圖
該圖從最右端看起,最右端標(biāo)注著“I/O”的就是代表CKS32F4xx系列產(chǎn)品引出的GPIO引腳,其余部件都位于芯片內(nèi)部。引腳處的兩個(gè)保護(hù)二級(jí)管可以防止引腳外部過高或過低的電壓輸入,當(dāng)引腳電壓高于VDD_FT時(shí),上方的二極管導(dǎo)通,當(dāng)引腳電壓低于VSS時(shí),下方的二極管導(dǎo)通,由此可以防止不正常電壓引入芯片導(dǎo)致芯片的燒毀。這里要特別注意VDD_FT 代表IO口兼容3.3V和5V,如果沒有標(biāo)注“FT”,就代表著不兼容5V。在芯片數(shù)據(jù)手冊(cè)的引腳定義中,會(huì)看到有“電平I/O”一列,有FT標(biāo)注的即為支持5V,如下圖所示:
標(biāo)號(hào)1處是上拉、下拉電阻,從它的結(jié)構(gòu)我們可以看出,通過上、下拉對(duì)應(yīng)的開關(guān)配置,我們可以控制引腳默認(rèn)狀態(tài)下的電壓,開啟上拉的時(shí)候引腳電壓為高電平,開啟下拉的時(shí)候引腳電壓為低電平。同時(shí)也可以設(shè)置“既不上拉也不下拉模式”,我們也把這種狀態(tài)稱為浮空模式。
標(biāo)號(hào)2處是一個(gè)由P-MOS和N-MOS管組成的單元電路。這個(gè)結(jié)構(gòu)使GPIO具有了“推挽輸出”和“開漏輸出”兩種模式。上方的P-MOS管高電平導(dǎo)通,低電平關(guān)閉,下方的N-MOS低電平導(dǎo)通,高電平關(guān)閉。
標(biāo)號(hào)3處是輸出數(shù)據(jù)寄存器,它為標(biāo)號(hào)2處的雙MOS管結(jié)構(gòu)電路提供輸入控制信號(hào),因此通過修改輸出數(shù)據(jù)寄存器的值就可以修改GPIO引腳的輸出電平。而圖中“置位/復(fù)位寄存器 GPIOx_BSRR”可以通過修改輸出數(shù)據(jù)寄存器的值從而影響電路的輸出。
標(biāo)號(hào)4處是復(fù)用功能輸出,“復(fù)用”是指CKS32F4xx系列產(chǎn)品的其它片上外設(shè)可以對(duì)GPIO引腳進(jìn)行控制,此時(shí)GPIO引腳用作該外設(shè)功能的一部分,算是第二用途。例如我們使用USART串口通訊時(shí),需要用到某個(gè)GPIO引腳作為通訊發(fā)送引腳,這個(gè)時(shí)候就可以把該GPIO引腳配置成USART串口復(fù)用功能,由串口外設(shè)控制該引腳,發(fā)送數(shù)據(jù)。
標(biāo)號(hào)5處是輸入數(shù)據(jù)寄存器,它連接到圖中的TTL施密特觸發(fā)器,觸發(fā)器的基本原理是當(dāng)輸入電壓高于正向閾值電壓時(shí),輸出為高;當(dāng)輸入電壓低于負(fù)向閾值電壓時(shí),輸出為低;IO口信號(hào)經(jīng)過觸發(fā)器后,模擬信號(hào)轉(zhuǎn)化為0和1的數(shù)字信號(hào),也就是高低電平,并且是TTL電平協(xié)議, 然后存儲(chǔ)在“輸入數(shù)據(jù)寄存器。因此,通過讀取該寄存器就可以了解GPIO引腳的電平狀態(tài)。
標(biāo)號(hào)6處是復(fù)用功能輸入,與“復(fù)用功能輸出”模式類似,同樣,如果我們使用USART串口通訊時(shí),需要用到某個(gè)GPIO引腳作為通訊接收引腳,這個(gè)時(shí)候就可以把該GPIO引腳配置成USART串口復(fù)用功能,使USART可以通過該通訊引腳接收遠(yuǎn)端數(shù)據(jù)。
標(biāo)號(hào)7處是模擬輸入輸出,當(dāng) GPIO引腳用于ADC采集電壓的輸入通道時(shí),用作“模擬輸入”功能,此時(shí)信號(hào)是不經(jīng)過施密特觸發(fā)器的,因?yàn)榻?jīng)過施密特觸發(fā)器后信號(hào)只有0、1 兩種狀態(tài),所以ADC外設(shè)要采集到原始的模擬信號(hào),信號(hào)源輸入必須在施密特觸發(fā)器之前。同樣的,當(dāng) GPIO引腳用于DAC作為模擬電壓輸出通道時(shí),此時(shí)作為“模擬輸出”功能,DAC 的模擬信號(hào)輸出就不經(jīng)過雙MOS管結(jié)構(gòu)了,在GPIO結(jié)構(gòu)框圖的右下角處,模擬信號(hào)直接輸出到引腳。
GPIO的工作模式
- 4種輸入模式 -
1.浮空輸入
浮空輸入狀態(tài)下,IO的電平狀態(tài)是不確定的,完全由外部輸入決定。如果在該引腳懸空的情況下,讀取該端口的電平是不確定的。
2.上拉輸入
在該模式下,如果IO口外部沒有信號(hào)輸入或者引腳懸空,IO口默認(rèn)為高電平。如果I/O口輸入低電平,那么引腳就為低電平,MCU讀取到的就是低電平。
3.下拉輸入
在該模式下如果IO口外部沒有信號(hào)輸入或者引腳懸空,IO口默認(rèn)為低電平,如果I/O口輸入高電平,那么引腳就為高電平,MCU讀取到的就是高電平。
4.模擬功能
當(dāng)GPIO用于模擬功能時(shí),引腳的上、下拉電阻是不起作用的,這個(gè)時(shí)候即使配置了上拉或下拉模式,也不會(huì)影響到模擬信號(hào)的輸入輸出。除了ADC和DAC要將IO配置為模擬功能模式之外,其他外設(shè)功能一律要配置為復(fù)用功能模式。
- 4種輸出模式 -
1.開漏輸出(帶上拉或者下拉)
在該模式下,若MCU控制輸出為高電平1時(shí),輸出指令是不會(huì)起到作用的。此時(shí)I/O端口的電平就不會(huì)由輸出的高電平?jīng)Q定,而是由I/O端口外部的上拉或者下拉決定,如果沒有上拉或者下拉,IO口就處于高阻態(tài)。雖然通過軟件設(shè)置內(nèi)部上拉,也可以輸出高電平,但是CKS32F4xx系列產(chǎn)品內(nèi)部上拉是"弱上拉",即通過此上拉輸出的電流是很弱的,驅(qū)動(dòng)能力很弱。但是在該模式下,當(dāng)MCU控制輸出為低電平0時(shí),即使沒有上拉或者下拉,I/O端口也會(huì)輸出低電平。另一方面,在開漏模式下,施密特觸發(fā)器是打開的,即輸入可用,可以通過輸入數(shù)據(jù)寄存器GPIOx_IDR讀取I/O的實(shí)際狀態(tài)。開漏輸出主要有以下兩點(diǎn)作用:
a. I/O端口設(shè)置成開漏輸出模式時(shí),可以用來連接不同電平的器件,用來匹配電平,因?yàn)殚_漏引腳不連接外部的上拉電阻時(shí),只能輸出低電平,如果需要同時(shí)具備輸出高電平的功能,則需要接上拉電阻。因此我們通過改變上拉電源的電壓,便可以改變傳輸電平。比如通過加上上拉電阻就可以提供TTL電平-CMOS電平的輸出。
b.當(dāng)多個(gè)設(shè)置為開漏輸出的引腳連接到一條總線上時(shí)。通過外加一個(gè)上拉電阻,在不增加任何器件的情況下,這些引腳形成了“與邏輯”關(guān)系,即“線與”。如果有一個(gè)引腳輸出為邏輯0,相當(dāng)于接地,那么與之并聯(lián)的回路“相當(dāng)于被一根導(dǎo)線短路”,所以總線上的邏輯電平便為0。只有都為高電平時(shí),總線上的電平才為1。在IIC通信中,引腳通常設(shè)置為開漏輸出模式。
2.復(fù)用開漏輸出(帶上拉或者下拉)
此時(shí)GPIO復(fù)用為其他外設(shè),輸出數(shù)據(jù)寄存器GPIOx_ODR無效;即輸出的高低電平來源于其它外設(shè),除了輸出信號(hào)的來源改變之外,其他的與開漏輸出功能相同。
3.推挽輸出(帶上拉或者下拉)
在該模式下,如果我們控制輸出為0,低電平,則I/O端口的電平就是低電平。若控制輸出為1,高電平,則I/O端口的電平就是高電平。此時(shí),外部上拉和下拉的作用是控制在沒有輸出IO口的默認(rèn)電平。在該模式下,施密特觸發(fā)器也是打開的,即輸入可用,通過輸入數(shù)據(jù)寄存器GPIOx_IDR可讀取I/O的實(shí)際狀態(tài)。
4.復(fù)用推挽輸出(帶上拉或者下拉)
此時(shí)GPIO復(fù)用為其他外設(shè),輸出數(shù)據(jù)寄存器GPIOx_ODR無效;即輸出的高低電平來源于其它外設(shè),除了輸出信號(hào)的來源改變之外,其他的與推挽輸出功能相同。
- 4種輸出速度 -
1. 2MHZ(低速)
2. 25MHZ(中速)
3. 50MHZ(快速)
4. 100MHZ(高速)
GPIO的引腳速度又稱輸出驅(qū)動(dòng)電路的響應(yīng)速度,即一個(gè)驅(qū)動(dòng)電路可以不失真地通過信號(hào)的最大頻率。比如信號(hào)頻率為10MHz,而我們把GPIO速度配置成了2MHz,則10MHz的方波很可能就變成了正弦波,發(fā)生了失真。芯片內(nèi)部在I/O口的輸出部分安排了多個(gè)響應(yīng)速度不同的輸出驅(qū)動(dòng)電路,我們可以根據(jù)自己的需要選擇合適的驅(qū)動(dòng)電路,通過選擇速度來選擇不同的輸出驅(qū)動(dòng)模塊,達(dá)到最佳的噪聲控制和降低功耗的目的。因?yàn)镚PIO口的速度配置越高,噪聲越大,功耗也越大。比如在USART串口通信中,若最大波特率只需115.2k,那用2M的速度就夠了,既省電,噪聲也??;而在SPI接口中,若使用18M或9M的波特率,則需要選用50M的GPIO的引腳速度。
注意:CKS32F407用于配置PA13輸出速度的GPIOA_OSPEEDR寄存器的端口 13配置位(GPIOA_OSPEEDR_OSPEEDR13[1:0])初始值為00,即PA13的I/O輸出速度默認(rèn)為低速。因此客戶在實(shí)際使用CKS32F407時(shí),要按照參考手冊(cè)中的介紹來配置GPIOA_OSPEED寄存器中 OSPEEDR13[1:0]位,從而來選擇PA13的I/O輸出指定的速度。
GPIO的配置
接下來我們講解如何利用CKS32F4xx系列固件庫對(duì)GPIO口的工作模式進(jìn)行配置。首先,固件庫中定義了一個(gè)如下的結(jié)構(gòu)體:
typedefstruct { uint32_tGPIO_Pin; GPIOMode_TypeDefGPIO_Mode; GPIOSpeed_TypeDefGPIO_Speed; GPIOOType_TypeDefGPIO_OType; GPIOPuPd_TypeDefGPIO_PuPd; }GPIO_InitTypeDef;
通過對(duì)該結(jié)構(gòu)體成員中各個(gè)變量的初始化,就可以完成對(duì)2.2小節(jié)中所講的GPIO口的工作模式配置。結(jié)構(gòu)體中各個(gè)成員變量的介紹及初始化時(shí)可被賦的值如下:
1)GPIO_Pin:用來選擇要控制的GPIO引腳,在標(biāo)準(zhǔn)庫函數(shù)中可選擇的值及其定義如下:
#defineGPIO_Pin_0((uint16_t)0x0001) #defineGPIO_Pin_1((uint16_t)0x0002) #defineGPIO_Pin_2((uint16_t)0x0004) #defineGPIO_Pin_3((uint16_t)0x0008) #defineGPIO_Pin_4((uint16_t)0x0010) #defineGPIO_Pin_5((uint16_t)0x0020) #defineGPIO_Pin_6((uint16_t)0x0040) #defineGPIO_Pin_7((uint16_t)0x0080) #defineGPIO_Pin_8((uint16_t)0x0100) #defineGPIO_Pin_9((uint16_t)0x0200) #defineGPIO_Pin_10((uint16_t)0x0400) #defineGPIO_Pin_11((uint16_t)0x0800) #defineGPIO_Pin_12((uint16_t)0x1000) #defineGPIO_Pin_13((uint16_t)0x2000) #defineGPIO_Pin_14((uint16_t)0x4000) #defineGPIO_Pin_15((uint16_t)0x8000) #defineGPIO_Pin_All((uint16_t)0xFFFF)
2) GPIO_Mode:用來設(shè)置已經(jīng)選擇的GPIO引腳的模式,在標(biāo)準(zhǔn)庫函數(shù)中可選擇的值及其定義如下:
typedefenum { GPIO_Mode_IN=0x00,/*!設(shè)置為輸入模式*/ GPIO_Mode_OUT=0x01,/*!設(shè)置為輸出模式*/ GPIO_Mode_AF=0x02,/*!設(shè)置為復(fù)用模式*/ GPIO_Mode_AN=0x03/*!設(shè)置為模擬模式*/ }GPIOMode_TypeDef;
3) GPIO_Speed:用來設(shè)置已經(jīng)選擇的GPIO引腳的速度,在標(biāo)準(zhǔn)庫函數(shù)中可選擇的值及其定義如下:
#defineGPIO_Speed_2MHzGPIO_Low_Speed #defineGPIO_Speed_25MHzGPIO_Medium_Speed #defineGPIO_Speed_50MHzGPIO_Fast_Speed #defineGPIO_Speed_100MHzGPIO_High_Speed
4) GPIO_OType:用來設(shè)置已經(jīng)選擇的GPIO引腳的輸出模式,只有輸出模式才需要該配置,輸入模式下不需要該配置。在標(biāo)準(zhǔn)庫函數(shù)中可選擇的值及其定義如下:
typedefenum { GPIO_OType_PP=0x00,/*!設(shè)置為推挽輸出模式*/ GPIO_OType_OD=0x01/*!設(shè)置為開漏輸出模式*/ }GPIOOType_TypeDef;
5) GPIO_PuPd:用來設(shè)置已經(jīng)選擇的GPIO引腳的上下拉,在標(biāo)準(zhǔn)庫函數(shù)中可選擇的值及其定義如下:
typedefenum { GPIO_PuPd_NOPULL=0x00,/*!設(shè)置為既不上拉也不下拉/浮空模式*/ GPIO_PuPd_UP=0x01,/*!設(shè)置為上拉模式*/ GPIO_PuPd_DOWN=0x02/*!設(shè)置為下拉模式*/ }GPIOPuPd_TypeDef;
根據(jù)上面所講解的配置方法,我們講解標(biāo)準(zhǔn)庫下的3個(gè)實(shí)際配置實(shí)例。
1)作為普通的GPIO口輸出,控制LED燈的亮滅,其GPIO口初始化函數(shù)如下:
voidLED_GPIO_Init(void) { GPIO_InitTypeDefGPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//使能GPIOF時(shí)鐘 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;//LED1對(duì)應(yīng)的IO口 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//輸出模式 GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽模式 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度100MHz GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOF, GPIO_InitStructure);//初始化GPIO }
2) 復(fù)用為CAN外設(shè)的輸出。
voidCAN1_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能PORTA時(shí)鐘 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//復(fù)用功能 GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽輸出 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//100MHz GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉GPIO_Init(GPIOA, GPIO_InitStructure);//初始化PA11,PA12 GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1);//GPIOA11復(fù)用為CAN1 GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1);//GPIOA12復(fù)用為CAN1
3) 當(dāng)ADC采集的輸入通道,作為普通模擬輸入。
voidADC_Init(void) { GPIO_InitTypeDefGPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能GPIOA時(shí)鐘 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//PA5通道5 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;//模擬輸入 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;//不帶上下拉 GPIO_Init(GPIOA, GPIO_InitStructure);//初始化 }
來源:中科芯MCU
免責(zé)聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問題,請(qǐng)聯(lián)系小編進(jìn)行處理
審核編輯 黃宇
-
mcu
+關(guān)注
關(guān)注
146文章
17123瀏覽量
350978 -
GPIO
+關(guān)注
關(guān)注
16文章
1204瀏覽量
52051
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論