GPIO簡介
GPIO是通用輸入輸出端口的簡稱,也是CKS32可控制的引腳,CKS32芯片的GPIO引腳與外部設(shè)備連接起來,從而實現(xiàn)與外部通訊、控制以及數(shù)據(jù)采集的功能。CKS32芯片的GPIO被分成很多組,每組有16個引腳,如型號為CKS2F107VET6型號的芯片有GPIOA、GPIOB、GPIOC至GPIOE共5組GPIO,芯片一共100個引腳,其中GPIO就占了一大部分,所有的GPIO引腳都有基本的輸入輸出功能。
最基本的輸出功能是由CKS32控制引腳輸出高、低電平,實現(xiàn)開關(guān)控制,如把GPIO引腳接入到LED燈,那就可以控制LED燈的亮滅,引腳接入到繼電器或三極管,那就可以通過繼電器或三極管控制外部大功率電路的通斷。最基本的輸入功能是檢測外部輸入電平,如把 GPIO引腳連接到按鍵,通過電平高低區(qū)分按鍵是否被按下。
GPIO框圖結(jié)構(gòu)分析
CKS32F107系列MCU的GPIO內(nèi)部硬件結(jié)構(gòu)如下圖所示,通過GPIO硬件結(jié)構(gòu)框圖,可以從整體上深入了解GPIO外設(shè)及它的各種應(yīng)用模式。該圖從最右端看起,最右端就是代表 MCU引出的 GPIO引腳,其余部件都位于MCU芯片內(nèi)部。
圖1 GPIO硬件結(jié)構(gòu)框圖
序號①是引腳的兩個保護(hù)二級管,可以防止引腳外部過高或過低的電壓輸入,當(dāng)引腳電壓高于VDD時,上方的二極管導(dǎo)通,當(dāng)引腳電壓低于VSS時,下方的二極管導(dǎo)通,防止不正常電壓引入芯片導(dǎo)致芯片燒毀。盡管有這樣的保護(hù),并不意味著CKS32的GPIO能直接外接大功率驅(qū)動器件,如直接驅(qū)動電機(jī),如果強(qiáng)制驅(qū)動可能會造成電機(jī)不轉(zhuǎn)或者導(dǎo)致芯片燒壞,必須要在GPIO和電機(jī)之間增加大功率及隔離電路驅(qū)動。
序號②是GPIO引腳線路經(jīng)過兩個保護(hù)二極管后,下方“輸出模式”電路中的一個由P-MOS和N-MOS管組成的結(jié)構(gòu)單元。這個結(jié)構(gòu)使GPIO具有了“推挽輸出”和“開漏輸出”兩種模式,輸出模式是根據(jù)這兩個MOS管的工作方式來命名的。在該結(jié)構(gòu)中輸入高電平時,經(jīng)過反向后,上方的P-MOS導(dǎo)通,下方的N-MOS關(guān)閉,對外輸出高電平;而在該結(jié)構(gòu)中輸入低電平時,經(jīng)過反向后,N-MOS管導(dǎo)通,P-MOS關(guān)閉,對外輸出低電平。當(dāng)引腳高低電平切換時,兩個管子輪流導(dǎo)通,P管負(fù)責(zé)灌電流,N管負(fù)責(zé)拉電流,使其負(fù)載能力和開關(guān)速度都比普通的方式有很大的提高。推挽輸出的低電平為0伏,高電平為3.3伏,推挽等效電路如下圖(左)。推挽輸出模式一般應(yīng)用在輸出電平為0和3.3伏而且需要高速切換開關(guān)狀態(tài)的場合。在實際應(yīng)用中,除了必須用開漏模式的場合,一般都習(xí)慣使用推挽輸出模式。
圖2 GPIO硬件結(jié)構(gòu)框圖
在開漏輸出模式時,上方的P-MOS管完全不工作。如果我們控制輸出為0低電平,則 P-MOS管關(guān)閉,N-MOS管導(dǎo)通,使輸出接地,若控制輸出為1 (它無法直接輸出高電平) 時,則P-MOS管和N-MOS管都關(guān)閉,所以引腳既不輸出高電平,也不輸出低電平,為高阻態(tài),因此正常使用時必須外部接上拉電阻。開漏等效電路如上圖(右),它具有“線與”特性,若有很多個開漏模式引腳連接到一起時,只有當(dāng)所有引腳都輸出高阻態(tài),才由上拉電阻提供高電平。若其中一個引腳為低電平,那線路就相當(dāng)于短路接地,使得整條線路都為低電平0伏。開漏輸出一般應(yīng)用在I2C、SMBUS通訊等需要“線與”功能的總線電路中。除此之外,還用在電平不匹配的場合,如需要輸出5伏的高電平,就可以在外部接一個上拉電阻,上拉電源為5伏,并且把GPIO設(shè)置為開漏模式,當(dāng)輸出高阻態(tài)時,由上拉電阻和電源向外輸出5伏的電平。
序號③是GPIO輸出數(shù)據(jù)寄存器組,前面提到的雙MOS管結(jié)構(gòu)電路輸入信號,就是由這個寄存器組中的GPIOx_ODR提供的,因此我們通過修改輸出數(shù)據(jù)寄存器的值就可以修改GPIO引腳的輸出電平。而“置位/復(fù)位寄存器GPIOx_BSRR”可以通過修改輸出數(shù)據(jù)寄存器的值從而影響電路的輸出。
序號④是連接MCU片內(nèi)外設(shè)和GPIO引腳的復(fù)用功能輸出模塊,通過此功能可以將GPIO引腳用作指定外設(shè)功能的一部分,算是GPIO的第二用途。從其它外設(shè)引出來的“復(fù)用功能輸出信號”與GPIO本身的數(shù)據(jù)據(jù)寄存器都連接到雙MOS管結(jié)構(gòu)的輸入中,通過內(nèi)部開關(guān)切換選擇。例如我們使用USART串口通訊時,需要用到某個GPIO引腳作為通訊發(fā)送引腳,這個時候就可以把該GPIO引腳配置成USART串口復(fù)用功能,由串口外設(shè)控制該引腳發(fā)送數(shù)據(jù)。
序號⑤是輸入數(shù)據(jù)寄存器組,位于GPIO結(jié)構(gòu)框圖的上半部分,GPIO引腳經(jīng)過內(nèi)部的上、下拉電阻,可以配置成上/下拉輸入,然后再連接到施密特觸發(fā)器,信號經(jīng)過觸發(fā)器后,模擬信號轉(zhuǎn)化為0/1數(shù)字信號,然后存儲在“輸入數(shù)據(jù)寄存器GPIOx_IDR”中,通過讀取該寄存器就可以獲取GPIO引腳的電平狀態(tài)。
序號⑥是連接MCU片內(nèi)外設(shè)和GPIO引腳的復(fù)用功能輸入模塊,與序號④類似,在“復(fù)用功能輸入模式”時,GPIO引腳的信號傳輸?shù)街付ㄆ瑑?nèi)外設(shè),由該外設(shè)讀取引腳狀態(tài)。例如我們使用USART串口通訊時,需要用到某個GPIO引腳作為通訊接收引腳,這個時候就可以把該GPIO引腳配置成USART串口復(fù)用功能,由串口外設(shè)控制該引腳接收外部數(shù)據(jù)。
序號⑦是用于ADC采集電壓輸入通道的專用“模擬輸入”功能,由于ADC外設(shè)要采集到原始的模擬信號,所以輸入信號不經(jīng)過施密特觸發(fā)器,因為經(jīng)過施密特觸發(fā)器后信號只有0/1兩種狀態(tài)。類似地,當(dāng)GPIO引腳作為“模擬輸出”功能用于DAC模擬電壓輸出通道時,模擬信號輸出也不經(jīng)過雙MOS管結(jié)構(gòu)而直接輸出到GPIO引腳。
GPIO工作模式總結(jié)
根據(jù)上述結(jié)構(gòu)分析,可以總結(jié)出在固件庫中GPIO可以配置成如下8種工作模式,且大致歸為三類。
//Configuration Mode enumeration
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;
第一類是輸入模式(模擬/浮空/上拉/下拉),在輸入模式時,施密特觸發(fā)器打開,輸出被禁止,可通過輸入數(shù)據(jù)寄存器GPIOx_IDR讀取I/O狀態(tài)。其中輸入模式,可設(shè)置為上拉、下拉、浮空和模擬輸入四種。上拉和下拉輸入很好理解,默認(rèn)的電平由上拉或者下拉決定。浮空輸入的電平是不確定的,完全由外部的輸入決定,一般接按鍵的時候用的是這個模式。模擬輸入則專用于ADC采集。
第二類是輸出模式(推挽/開漏),在推挽模式時雙MOS管以輪流方式工作,輸出數(shù)據(jù)寄存器GPIOx_ODR可控制I/O輸出高低電平。開漏模式時,只有N-MOS管工作,輸出數(shù)據(jù)寄存器可控制I/O輸出高阻態(tài)或低電平。輸出速度可配置,此處的輸出速度即I/O支持的高低電平狀態(tài)最高切換頻率,支持的頻率越高,功耗越大。在輸出模式時施密特觸發(fā)器是打開的,即輸入可用,通過輸入數(shù)據(jù)寄存器GPIOx_IDR可讀取I/O的實際狀態(tài)。
第三類是復(fù)用功能模式(推挽/開漏),復(fù)用功能模式中,輸出使能,輸出速度可配置,可工作在開漏及推挽模式,但是輸出信號源于其它外設(shè),輸出數(shù)據(jù)寄存器GPIOx_ODR無效;輸入可用,通過輸入數(shù)據(jù)寄存器可獲取I/O實際狀態(tài),但一般直接用外設(shè)的寄存器來獲取該數(shù)據(jù)信號。
以上各類型的GPIO口每一個都可以自由編程,此外,CKS32F107的很多IO口都是5V兼容的,這些IO口在與5V電平的外設(shè)連接的時候很有優(yōu)勢,具體哪些IO口是5V兼容的,可以從該芯片的數(shù)據(jù)手冊管腳描述章節(jié)查到(I/O Level標(biāo)FT的就是5V電平兼容的)。
GPIO寄存器
CKS32的GPIO口寄存器必須要按32位字被訪問,每個IO端口都有7個寄存器來控制。分別是:配置模式的2個32位的端口配置寄存器CRL和CRH;2個32位的數(shù)據(jù)寄存器IDR和ODR;1個32位的置位/復(fù)位寄存器BSRR;一個16位的復(fù)位寄存器BRR;1個32位的鎖存寄存器LCKR。如果想要了解每個寄存器的詳細(xì)使用方法,可以參考《CKS32F107參考手冊》。
(1)CRL和CRH控制著每個IO口的模式及輸出速率,本文以CRL為例,看看端口低配置寄存器的描述,如下圖所示。該寄存器的復(fù)位值為0x44444444,從圖中可以看到,復(fù)位值其實就是配置端口為浮空輸入模式。從下圖還可以得出:CRL控制著每組IO端口的低8位模式。每個IO端口的位占用CRL的4個位,高兩位為CNF,低兩位為MODE。這里我們可以記住幾個常用的配置,比如0x0表示模擬輸入模式(ADC用)、0x3表示推挽輸出模式(做輸出口用,50M速率)、0x8表示上/下拉輸入模式(做輸入口用)、0xB表示復(fù)用輸出(使用IO口的第二功能,50M速率)。CRH的作用和CRL完全一樣,只是CRL控制的是低8位輸出口,而CRH控制的是高8位輸出口。這里我們對CRH就不做詳細(xì)介紹了。
圖3 GPIOx_CRL寄存器
(2)IDR是一個端口輸入數(shù)據(jù)寄存器,低16位有效。該寄存器為只讀寄存器,并且只能以16位的形式讀出。該寄存器各位的描述如下圖所示:
圖4 GPIOx_CRL寄存器
(3)ODR是一個端口輸出數(shù)據(jù)寄存器,也只用了低16位。該寄存器為可讀寫,從該寄存器讀出來的數(shù)據(jù)可以用于判斷當(dāng)前IO口的輸出狀態(tài)。而向該寄存器寫數(shù)據(jù),則可以控制某個IO口的輸出電平。該寄存器的各位描述如下圖所示:
圖5 GPIOx_CRL寄存器
(4)BSRR寄存器是端口位設(shè)置/清除寄存器。該寄存器和ODR寄存器具有類似的作用,都可以用來設(shè)置GPIO端口的輸出位是1還是0。
圖6 GPIOx_CRL寄存器
通過固件庫操作GPIO
CKS32F107系列GPIO相關(guān)的函數(shù)和定義分布在固件庫文件cks32f10x_gpio.c和頭文件 cks32f10x_gpio.h文件中。在固件庫開發(fā)中,操作寄存器CRH和CRL來配置IO口的模式和速度是通過GPIO初始化函數(shù)完成的。
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
這個函數(shù)有兩個參數(shù),第一個參數(shù)是用來指定GPIO,取值范圍為GPIOA~GPIOG。第二個參數(shù)為初始化參數(shù)結(jié)構(gòu)體指針,結(jié)構(gòu)體類型為GPIO_InitTypeDef。結(jié)構(gòu)體的定義如下:
typedef struct
{
uint16_t GPIO_Pin;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOMode_TypeDef GPIO_Mode;
}GPIO_InitTypeDef;
下面通過一個GPIO初始化實例來講解這個結(jié)構(gòu)體的成員變量的含義。代碼的意思是設(shè)置GPIOB的第5個端口為推挽輸出模式,同時速度為50M。結(jié)構(gòu)體GPIO_InitStructure的第一個成員變量GPIO_Pin用來設(shè)置是要初始化哪個或者哪些IO口;第二個成員變量GPIO_Mode是用來設(shè)置對應(yīng)IO端口的輸出輸入模式;第三個參數(shù)是IO口速度設(shè)置。
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PB5端口配置
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
在固件庫中操作IDR寄存器讀取IO端口數(shù)據(jù)是通過GPIO_ReadInputDataBit函數(shù)實現(xiàn)的。比如我要讀GPIOA5的電平狀態(tài),那么方法是:
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5);
在固件庫中設(shè)置ODR寄存器的值來控制IO口的輸出狀態(tài)是通過函數(shù)GPIO_Write來實現(xiàn)的,該函數(shù)一般用來一次性往一個GPIO的多個端口設(shè)值。
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
該寄存器通過舉例子可以很清楚了解它的使用方法。例如你要設(shè)置GPIOA的第1個端口值為1,那么你只需要往寄存器BSRR的低16位對應(yīng)位寫1即可。該寄存器往相應(yīng)位寫0是無影響的,所以我們要設(shè)置某些位,我們不用管其他位的值。
GPIOA->BSRR=1<1;?
在固件庫中,通過BSRR和BRR寄存器設(shè)置GPIO端口輸出是通過函數(shù)GPIO_SetBits()和函數(shù)GPIO_ResetBits()來完成的。在多數(shù)情況下,我們都是采用這兩個函數(shù)來設(shè)置GPIO端口的輸入和輸出狀態(tài)。比如我們要設(shè)置GPIOB5輸出1和0,那么方法為:
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
GPIO_SetBits(GPIOB, GPIO_Pin_5);
GPIO_ResetBits(GPIOB, GPIO_Pin_5);
GPIO相關(guān)的庫函數(shù)我們先講解到這里。雖然IO操作步驟很簡單,這里還是做個概括總結(jié),操作步驟為:(1)使能IO口時鐘,調(diào)用函數(shù)RCC_APB2PeriphClockCmd();(2)初始化IO參數(shù),調(diào)用函數(shù)GPIO_Init();(3)操作IO。下面我們來講解一個基于CKS32F107VxT6開發(fā)板的GPIO按鍵輸入和GPIO輸出實驗軟件例程。
實驗例程
編程要點
(1)使能GPIO端口時鐘;
(2)初始化GPIO按鍵引腳為輸入模式(上拉輸入);
(3)初始化GPIO LED引腳為輸出模式(推挽輸出);
(4)編寫簡單測試程序,檢測按鍵的狀態(tài),實現(xiàn)按鍵控制LED燈。
代碼分析
(1)按鍵檢測引腳相關(guān)宏定義
// 引腳定義
#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOC
#define KEY1_GPIO_PORT GPIOC
#define KEY1_GPIO_PIN GPIO_Pin_0
#define LED1_GPIO_PORT GPIOB
#define LED1_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED1_GPIO_PIN GPIO_Pin_15
(2)按鍵GPIO初始化函數(shù)
void Key_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*開啟按鍵端口的時鐘*/
RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK,ENABLE);
//選擇按鍵的引腳
GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN;
// 設(shè)置按鍵的引腳為浮空輸入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//使用結(jié)構(gòu)體初始化按鍵
GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);
}
(3)LED GPIO初始化函數(shù)
void LED_GPIO_Config(void)
{
/*定義一個GPIO_InitTypeDef類型的結(jié)構(gòu)體*/
GPIO_InitTypeDef GPIO_InitStructure;
/*開啟LED相關(guān)的GPIO外設(shè)時鐘*/
RCC_APB2PeriphClockCmd(LED1_GPIO_CLK, ENABLE);
/*選擇要控制的GPIO引腳*/
GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN;
/*設(shè)置引腳模式為通用推挽輸出*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/*設(shè)置引腳速率為50MHz */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*調(diào)用庫函數(shù),初始化GPIO*/
GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);
/* 關(guān)閉led燈 */
GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
}
(4)主函數(shù)
int main(void)
{
/* LED端口初始化 */
LED_GPIO_Config();
/* 按鍵端口初始化 */
Key_GPIO_Config();
/* 輪詢按鍵狀態(tài),若按鍵按下則反轉(zhuǎn)LED */
while(1)
{
if(GPIO_ReadInputDataBit(KEY1_GPIO_PORT, KEY1_GPIO_PIN) == Bit_RESET)
{
GPIO_WriteBit(LED1_GPIO_PORT, LED1_GPIO_PIN, Bit_SET);
}
else
{
GPIO_WriteBit(LED1_GPIO_PORT, LED1_GPIO_PIN, Bit_RESET);
}
}
}
代碼中先初始化LED燈及按鍵后,在while函數(shù)里不斷讀取查詢并判斷按鍵是否按下,若返回值表示按鍵按下,則反轉(zhuǎn)LED燈的狀態(tài)。
-
三極管
+關(guān)注
關(guān)注
143文章
3627瀏覽量
122488 -
繼電器
+關(guān)注
關(guān)注
132文章
5363瀏覽量
149636 -
mcu
+關(guān)注
關(guān)注
146文章
17359瀏覽量
352834 -
GPIO
+關(guān)注
關(guān)注
16文章
1217瀏覽量
52445
原文標(biāo)題:MCU微課堂|CKS32F107xx系列GPIO配置
文章出處:【微信號:中科芯MCU,微信公眾號:中科芯MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
MCU微課堂|CKS32F4xx系列產(chǎn)品時鐘配置
CKS32F4xx系列MCU的低功耗模式之睡眠模式
![<b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b><b class='flag-5'>MCU</b>的低功耗<b class='flag-5'>模式</b>之睡眠<b class='flag-5'>模式</b>](https://file1.elecfans.com/web2/M00/8B/6B/wKgaomSY8kCAKDJ7AABYMDSOazU095.png)
基于CKS32F4xx系列的MCU互補(bǔ)PWM方案
![基于<b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>的<b class='flag-5'>MCU</b>互補(bǔ)PWM方案](https://file1.elecfans.com/web2/M00/B2/4C/wKgaomVqkziAQHJYAAAPr857xR4112.png)
CKS32F4xx系列mcu的GPIO口配置方法
CKS32F4xx系列RNG功能設(shè)置
![<b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>RNG功能設(shè)置](https://file1.elecfans.com/web2/M00/A3/86/wKgaomT6gH2AHojwAAAPwIIu7n0544.jpg)
CKS32F107xx系列時鐘系統(tǒng)具體配置方法講解
![<b class='flag-5'>CKS32F107xx</b><b class='flag-5'>系列</b>時鐘系統(tǒng)具體配置方法講解](https://file1.elecfans.com/web2/M00/E9/BD/wKgZomZVPGSAL6k9AAAmjlc44W0511.png)
CKS32F107xx系列MCU中ADC介紹
CKS32F107xx系列MCU的雙重ADC模式
![<b class='flag-5'>CKS32F107xx</b><b class='flag-5'>系列</b><b class='flag-5'>MCU</b>的雙重ADC<b class='flag-5'>模式</b>](https://file1.elecfans.com/web2/M00/FD/9E/wKgZomadtGuAVDluAABObkCTZNU278.png)
CKS32F107xx系列MCU的中斷和事件
![<b class='flag-5'>CKS32F107xx</b><b class='flag-5'>系列</b><b class='flag-5'>MCU</b>的中斷和事件](https://file1.elecfans.com/web2/M00/FE/86/wKgaomadthKAVRbMAAEE9O3njnc706.png)
詳解CKS32F107xx系列的定時器同步功能
![詳解<b class='flag-5'>CKS32F107xx</b><b class='flag-5'>系列</b>的定時器同步功能](https://file1.elecfans.com/web3/M00/00/04/wKgZO2dFmo2AEGVaAAAmt1_ZZbs531.png)
評論