STM32F103知識點小結—GPIO功能設定

2020-08-11 20:29:06

STM32F103知識點小結—GPIO功能設定

STM32F1系列的微控制器具有豐富的外設,其中最基礎的就是GPIO的使用。

IO口模式的分類

IO口模式可大致分爲8類。按基本功能可以分爲

(1).輸入功能

1.浮空輸入
2.上拉輸入
3.下拉輸入
4.模擬輸入

(2)輸出功能

1.開漏輸出:可以輸出高、低電平,連線數位器件
2.推輓輸出:適合做電流型驅動,驅動能力較強

相關暫存器

TM32 的每個 IO 埠都有 7 個暫存器來控制。他們分別是:設定模式的 2 個 32 位的埠 設定暫存器 CRL 和 CRH; 2 個 32 位的數據暫存器 IDR 和 ODR; 1 個 32 位的置位/復位暫存器BSRR;一個 16 位的復位暫存器 BRR; 1 個 32 位的鎖存暫存器 LCKR。
1.CRL 和 CRH 控制着每個 IO 口的模式及輸出速率 (在韌體庫開發中, 操作暫存器 CRH 和 CRL 來設定 IO 口的模式和速度是通過 GPIO 初始化函數完成:)

 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

2.IDR:IDR 是一個埠輸入數據暫存器,只用了低 16 位。該暫存器爲只讀暫存器,並且只能以
16 位的形式讀出。在韌體庫中操作 IDR 暫存器讀取 IO 埠數據是通過GPIO_ReadInputDataBit 函數實現的:

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 

返回值是 1(Bit_SET)或者 0(Bit_RESET);

3.ODR 是一個埠輸出數據暫存器,也只用了低 16 位。該暫存器爲可讀寫,從該暫存器讀出來的數據可以用於判斷當前 IO 口的輸出狀態。而向該暫存器寫數據,則可以控制某個 IO 口的輸出電平。 在韌體庫中設定 ODR 暫存器的值來控制 IO 口的輸出狀態是通過函數 GPIO_Write 來實現的:

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

該函數一般用來往一次性一個 GPIO 的多個埠設值。
4.BSRR 暫存器是埠位設定/清除暫存器。 該暫存器和 ODR 暫存器具有類似的作用,都可以用來設定 GPIO 埠的輸出位是 1 還是 0。暫存器通過舉例子可以很清楚瞭解它的使用方法。 例如你要設定 GPIOA 的第 1 個埠值爲 1,那麼你只需要往暫存器 BSRR 的低 16 位對應位寫 1 即可:

GPIOA->BSRR=1<<1;

如果你要設定 GPIOA 的第 1 個埠值爲 0, 你只需要往暫存器高 16 位對應爲寫 1 即可:

GPIOA->BSRR=1<<(16+1)

該暫存器往相應位寫 0 是無影響的,所以我們要設定某些位,我們不用管其他位的值。
5.BRR 暫存器是埠位清除暫存器。該暫存器的作用跟 BSRR 的高 16 位雷同,這裏就不做詳細講解。 在 STM32 韌體庫中, 通過 BSRR 和 BRR 暫存器設定 GPIO 埠輸出是通過函數
GPIO_SetBits()和函數 GPIO_ResetBits()來完成的。

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 

GPIO埠初始化流程

1.定義初始化結構體
2.使能IO時鐘(AHPB2)
3.IO模式設定:(1).IO引腳選擇
(2).輸入、輸出、複用功能模式選擇
(3).IO速度設定
4.利用已經定義賦值好的初始化結構體進行初始化:GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO口呼叫範例

GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|
RCC_APB2Periph_GPIOE, ENABLE); //使能 PB,PE 埠時鐘
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;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 輸出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 推輓輸出
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE,GPIO_Pin_5); /PE.5 輸出高