什么是GPIO
GPIO全稱為General Purpose Input Output,中文理解為通用輸入輸出埠,它指的是編程可控制的引腳,即可以控制引腳是作為輸入來用,還是輸出功能,又或者是交給片上外設使用(復用),
GPIO結構框圖
理解GPIO硬體電路的實作,有助于編程的理解,下圖是官方手冊給出的GPIO框圖:

此框圖中只有最右端的I/O pin是板上外露可見的,其他部分均在芯片內部,該框圖結構被分為兩個部分,其一是輸出結構,主要由引腳(I/O pin)、保護二極管(protection diode)、雙MOS管(P-MOS+N-MOS)、輸出控制(output control)、輸出資料暫存器(output data register)、位置位/復位暫存器(bit set/reset register)組成 ;其二是輸入結構,由引腳、保護二極管、雙開關(on/off)、TTL肖特基觸發器(TTL Schmitt trigger)、輸入資料暫存器(input data register)組成,
保護二極管
兩個二極管構成了雙向限幅電路,當外部輸入電壓大于VDD時,上方二極管導通(全文皆忽略二極管和MOS管導通壓降),使得電壓限制在VDD左右;當外部輸入電壓低于VSS,下方二極管導通,電壓限制在VSS左右,然而這樣的保護并不能使引腳直接驅動大功率器件,例如電機,就需要外加驅動電路,
雙開關
這個雙開關電路與上拉、下拉和浮空模式有關,當處于上拉模式時上方開關閉合,下方斷開,除非引腳的外部輸入為低電平,否則輸入到肖特基觸發器的電平都是高電平;當處于下拉模式時上方開關斷開,下方閉合,除非引腳的外部輸入為高電平,否則輸入到肖特基觸發器的電平都是低電平;當處于浮空模式時開關全部斷開,電平默認為高阻態,輸入的電平完全取決于外部輸入,上下拉多用于按鍵檢測,而浮空則常用于ADC檢測,
肖特基觸發器
該觸發器主要是將模擬電壓轉為0/1數字信號,上圖中模擬輸入(Analog input)就取自觸發器之前,而輸入資料暫存器則取自觸發器之后的數字信號,
輸入資料暫存器
這個暫存器用來存盤各個引腳電平狀態,可通過讀取該暫存器內容,來獲取任意引腳狀態,
位置位/復位暫存器
通過讀寫該暫存器,可以間接地更改輸出資料暫存器的值,
輸出資料暫存器
可以直接讀寫該暫存器,來更改各個引腳的輸出狀態,當暫存器值保持不變時,每個引腳的電平也就不發生變化,
雙MOS管
雙MOS管組成一個推挽輸出(push-pull)電路,當輸出暫存器中值為1時,經過反相器,兩管的共柵極輸入低電平,則PMOS導通,NMOS截止,引腳輸出高電平;當輸出暫存器中值為0時,經過反相器,兩管的共柵極輸入高電平,則NMOS導通,PMOS截止,引腳輸出低電平,
當PMOS被禁用時,電路變為開漏輸出,引腳仍可輸出低電平,但無法正常輸出高電平,取而代之的是高阻態,如果此時想要輸出高電平,則必須接上拉電阻,開漏輸出僅在一些特殊場合下使用,更多的是推挽輸出,
GPIO暫存器
APB2外設時鐘使能暫存器(RCC_APB2ENR)
RCC_APB2ENR并不屬于GPIO的暫存器組,但是它控制著GPIO的引腳時鐘使能,芯片上電后,所有外設時鐘默認是關閉的,所以在使用GPIO前要先打開埠時鐘使能,該暫存器內容如下,我們只關心IOPxEN位,置1則開啟時鐘,


埠配置低位暫存器(GPIOx_CRL)
該暫存器可配置低8個GPIO引腳的作業模式:模擬輸入、浮空輸入、上拉\下拉輸入、通用推挽輸出、通用開漏輸出、復用推挽輸出、復用開漏輸出,復用輸入模式沒有單獨的配置,只要將引腳配置為浮空/上拉/下拉輸入模式,由片上外設驅動即可,CRL還可以在輸出模式下配置作業頻率,頻率越大,功耗越高,注意每個引腳模式配置占4bit,對于上拉\下拉輸入來說,是上拉還是下拉取決于ODR暫存器配置的值,

埠配置高位暫存器(GPIOx_CRH)
該暫存器同GPIOx_CRL,只是它控制的是高8個GPIO引腳的作業模式,

輸入資料暫存器(GPIOx_IDR)
該暫存器存盤了當前引腳的狀態,無論GPIO在哪種作業模式下,都可以讀取該暫存器——在復用模式下,一般選擇直接讀取外設暫存器,注意在模擬輸入模式下,IDR暫存器的值一直為0,

輸出資料暫存器(GPIOx_ODR)
在通用輸出模式下,該暫存器可用來控制輸出電平的高低;在復用模式下,ODR無效,此外,在上拉或下拉輸入模式下,ODR可決定是上拉還是下拉,

位置位/復位暫存器(GPIOx_BSRR)
通過該暫存器,可以單獨控制某個引腳的電平變化,因為向這個暫存器寫0的結果是無操作,寫1是置位或者復位,所以訪問該暫存器可以直接用=號;而ODR暫存器寫0則表示給低電平,寫1表示給高電平,為了不影響其他引腳,寫入必須用&=和|=號,另外還有個暫存器叫GPIOx_BRR,同該暫存器差不多,只不過BRR只能復位,高16位是保留的,

GPIO編程
GPIO最常用的就是通用推挽輸出和上拉/下拉輸入這兩種模式,一下程式實作功能為:
PA0為按鍵輸入,按下為低電平,PC13是led控制引腳,低電平點亮LED,當按下按鍵時,LED亮;松開按鍵時,LED滅,
程式代碼如下,根據GPIO原理,編程順序一般是:先開啟時鐘使能,配置引腳作業模式,最后給引腳電平信號,
int main(void)
{
uint32_t key_value;
//開啟GPIO外設時鐘使能
//PORTA,第三位置1
RCC->APB2ENR |= (1<<2);
//PORTC,第五位置1
RCC->APB2ENR |= (1<<4);
//GPIO輸入輸出模式配置
//清零PA0控制位
GPIOA->CRL &= ~((uint32_t)(0x0F)<<(4*0));
//設定PA0為上拉輸入
GPIOA->CRL |= (uint32_t)(0x08)<<(4*0);
GPIOA->ODR |= (uint32_t)(0x01)<<0;
//清零PC13控制位
GPIOC->CRH &= ~((uint32_t)(0x0F)<<(4*5));
//設定PC13為推免輸出
GPIOC->CRH |= (uint32_t)(0x01)<<(4*5);
while(1){
//獲取PA0電平狀態,key_value=https://www.cnblogs.com/kensporger/p/=1表示按鍵沒有按下
key_value = https://www.cnblogs.com/kensporger/p/(GPIOA->IDR & (uint32_t)(0x01)) == (uint32_t)(0x01);
//改變PC13電平
if (key_value=https://www.cnblogs.com/kensporger/p/=0)
//PC13低電平輸出
GPIOC->ODR &= ~((uint32_t)(0x01)<<13);
else
//PC13高電平輸出
GPIOC->ODR |= (uint32_t)(0x01)<<13;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/52988.html
標籤:C
下一篇:單鏈表實作
