主要外設:
- GPIO:General Purpose I/O 一般用途IO
- EXIT:External Interrupt/Event Controller 外部中斷/事件控制器(STM32)
輔助外設:
- SYSCFG:System configuration controller系統配置控制器(STM32)
- NVIC:Nested Vectored Interrupt Controller嵌套向量中斷控制器(ARM)
- SCB:System Control Block系統控制塊(ARM)
IO引腳:
- 默認作為一般用途的引腳,引腳↔GPIO↔CPU
- 用代碼設為專用功能引腳,引腳↔GPIO↔片上外設的某個外部引腳(復用)(利用GPIO的輸入電路、輸出電路、增加少量控制單元)
GPIO中的基本電路
輸出電路
選擇輸出速度OSPEEDR→選擇推挽/開漏OTYPER→選擇上下拉電阻PUPDR→保護二極管→引腳
- 保護二極管:當輸入電壓過高或過低時,二極管導通,輸入電壓拉到VDD或GND,保護STM32 MCU
- 上下拉電阻 pull-up/pull-down:內部帶有很弱的上下拉電阻絕大多數情況不使用
- 輸出類型-推挽Push-Pull:絕大多數情況,可輸出VDD或GND
- 輸出類型-開漏Open Drain:很少情況,可輸出GND或浮空(輸出高電平需要外接電源和上拉電阻,用於輸出電平轉換、多個OD輸出並聯實現“線與”、I2C)
- 輸出速度:輸出驅動電路的響應速度,跟應用相匹配,速度配置越高,噪聲越大,功耗越大。
| GPIO寄存器 | 作用 | 數量x位寬 | 值 |
|---|---|---|---|
| OSPEEDR | 輸出速度 | 16x2bit | 0-低速2MHz、1-中速25MHz、2-快速50MHz、3-高速80MHz~100MHz |
| OTYPER | 輸出類型 | 16x1bit | 0-輸出推挽、1-輸出開漏 |
| PUPDR | 上下拉電阻 | 16x2bit | 0-無(浮空)、1-上拉、2-下拉 |
輸入電路
TTL施密特觸發器←選擇上下拉電阻PUPDR←保護二極管←引腳
| GPIO寄存器 | 作用 | 數量x位寬 | 值 |
|---|---|---|---|
| PUPDR | 上下拉電阻 | 16x2bit | 0-無(浮空)、1-上拉、2-下拉 |
- TTL施密特觸發器:信號進行數字采樣
一、GPIO_Output:通用輸出模式
主要功能:CPU寫入BSRR或ODR寄存器,控制引腳輸出高低電平
數據通路:
CPU→...→[選擇置位/復位BSSR]→選擇輸出電平ODR→輸出電路→引腳GPIO_Output
| GPIO寄存器 | 作用 | 數量x位寬 | 值 |
|---|---|---|---|
| MODER | 模式 | 16x2bit | 0-輸入、1-通用輸出、2-復用功能、3-模擬 |
| BSRR | 置位/復位 | 16x2bit | BitReset:0-無操作、1-復位 BitSet:0-無操作、1-置位 |
| ODR | 輸出數據 | 16x1bit | 0-低電平、1-高電平 |
User Label(可選):用來給引腳起別名,提高代碼可讀性、移植性(更換引腳時只修改宏),對GPIO端口和引腳定義宏
//在main.h中
#define XXX_GPIO_Port GPIOx
#define XXX_Pin GPIO_PIN_y
硬件設計
PA5外接高電平驅動方式的指示燈電路(驅動指示燈:高電平)
CubeMX的配置
- 引腳分配Pinout View
- 搜索PA5 設置為GPIO_Output
- 外設配置
- System Core-GPIO-引腳清單(單擊) → PA5配置 → 用戶標簽=LED2、(工作)模式=Output Push Pull、(初始)輸出電平=low、最大輸出(翻轉)速度=low、上下拉電阻=No
用戶代碼
//USER CODE3:后台程序(無限循環)
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);//輸出高電平
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);//輸出低電平
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);//輸出電平翻轉
HAL_Delay(1000);
二、GPIO_input:輸入模式(輪詢)
主要功能:CPU讀取IDR寄存器,讀取引腳電平
- 輪詢、CPU忙等、效率低
- 作為復位后的默認工作模式
數據通路:
CPU←...←APB外設總線←存儲輸入電平IDR←輸入電路←引腳GPIO_input
| GPIO寄存器 | 作用 | 數量x位寬 | 值 |
|---|---|---|---|
| MODER | 模式 | 16x2bit | 0-輸入、1-通用輸出、2-復用功能、3-模擬 |
| IDR | 輸入數據 | 16x1bit | 0-低電平、1-高電平 |
硬件設計
PC13外接上拉式按鍵(按鍵控制:按下為低電平)
CubeMX的配置
- 引腳分配Pinout View
- 搜索PC13 設置為GPIO_Input
- 外設配置
- System Core-GPIO-引腳清單(單擊) → PC13配置 →用戶標簽=KEY1、(工作)模式=input mode、上下拉電阻=No
用戶代碼
//USER CODE3:后台程序(無限循環)
if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)==GPIO_PIN_RESET){//按鍵按下
HAL_Delay(10);//延遲去抖動
if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)==GPIO_PIN_RESET){//按鍵仍然按下
//TODO 執行按鍵按下后的操作
}
}
//等待釋放:知道引腳變為高電平
while(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)==GPIO_PIN_RESET);
三、GPIO_Exit:輸入模式(中斷)
主要功能:先將GPIO和EXIT建立連接,再由EXIT、NVIC的配置,決定CPU何時調用中斷回調函數(外部中斷External Interrupte)
數據通路:
中斷回調函數←...←CPU←...←NVIC←...←APB外設總線←掛起請求PR←中斷屏蔽IMR←[軟件觸發SWIER]←邊沿監測RTSR和FTSR←Exit輸入線(0~15號)←SYSCFG_EXTICR(引腳分組)←輸入電路←引腳GPIO_Exit
- GPIO在GPIO_Input模式下:接收外部輸入
- SYSCFG的EXTICR位:負責將GPIO的輸入電路和EXIT的輸入線連接
- EXIT:設置觸發條件(上升沿RTSR、下降沿FTSR、雙邊沿、軟件觸發SWIER)、中斷屏蔽IMR、保存中斷標記PR(是否觸發的狀態)、發送給NVIC
- PR寄存器的注意事項:軟件寫1清0,方便對其他bit寫0不變 (若寫0清0的話,會導致其他狀態位的掛起狀態也被清空)
| GPIO寄存器 | 作用 | 數量x位寬 | 值 |
|---|---|---|---|
| MODER | 模式 | 16x2bit | 0-輸入、1-通用輸出、2-復用功能、3-模擬 |
| SYSCFG寄存器 | 作用 | 數量x位寬 | 值 |
|---|---|---|---|
| EXTICR1~4 | 外部中斷配置 | 16x4bit | IO引腳→(9-1 MUX)→EXIT輸入線 0-PA口 1-PB口 2-PC口 3-PD口 4-PE口 5-PF口 6-PG口 7-PH口 8-PI口 |
| EXIT寄存器 | 作用 | 數量x位寬 | 值 |
|---|---|---|---|
| RTSR | 上升沿觸發選擇(中斷觸發條件) | 0-禁止、1-允許 | |
| FTSR | 下降沿觸發器選擇(中斷觸發條件) | 0-禁止、1-允許 | |
| SWIER | 軟件中斷/事件(中斷觸發條件) | 0-無操作、1-軟件觸發 | |
| IMR | 輸入線的中斷請求(中斷屏蔽) | 23x1 | 0-禁止、1-允許 |
| PR | 掛起請求(中斷標志位) | 0-沒有觸發或有觸發且被CPU處理、1-有觸發且尚未被CPU處理(掛起狀態)、 軟件寫1清0或更改RTSR、FTSR時清0 |
16個輸入線→EXIT→NVIC(7個中斷通道)
EXIT 0~4分別具有獨立的中斷通道
- EXIT 0→EXTI0_IRQHandler
- EXIT 1→EXTI1_IRQHandler
- EXIT 2→EXTI2_IRQHandler
- EXIT 3→EXTI3_IRQHandler
- EXIT 4→EXTI4_IRQHandler
EXTI5~EXIT9共享同一個中斷通道
- EXIT 5~9→EXTI9_5_IRQHandler
EXTI10~EXIT15共享同一個中斷通道
-
EXIT 10~15→EXTI15_10_IRQHandler
-
NVIC:中斷優先級分組、中斷優先級設置、中斷使能(判定優先級、中斷屏蔽、決定是否發給CPU)
-
CPU:並進行中斷響應、調用中斷函數
-
CPU調用中斷服務程序:先判斷EXIT的PR是否有掛起中斷,若有掛起中斷、則先清中斷(EXIT的PR寫1清0)、再調用用戶自定義的中斷回調函數
-
EXTIx_IRQHandler:重寫了匯編啟動文件中EXTIx_IRQHandler(在stm32f4xx_it.c中CubeMX自動生成)
-
HAL_GPIO_EXTI_IRQHandler(GPIO_Pin):定義中斷回調函數的統一入口,包含EXIT中斷的不同外設相同處理的部分(在stm32f4xx_hal_gpio.c中HAL庫定義)
- __HAL_GPIO_EXTI_GET_IT(GPIO_Pin):獲取EXIT的PR狀態(在stm32f4xx_hal_gpio.h中HAL庫定義)
- __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin):清中斷(EXIT的PR寫1清0)(在stm32f4xx_hal_gpio.h中HAL庫定義)
-
HAL_GPIO_EXTI_Callback(GPIO_Pin):EXIT中斷的不同外設不同處理的部分,中斷回調函數的業務邏輯(在main.c中用戶自定義)
硬件設計
PC13外接上拉式按鍵(按鍵控制:按下為低電平)
在按下時產生下降沿,PC13的外部中斷功能→外部中斷線EXTI1
CubeMX的配置
- 引腳分配Pinout View:搜索PC13 設置為GPIO_EXTI13
- 外設配置
- System Core-GPIO-引腳清單(單擊) → PC13配置 → 用戶標簽=KEY1、(工作)模式=外部中斷模式 with 下降沿觸發、上下拉電阻=No
- System Core-NVIC-NVIC中斷表 → EXTI Line[15:10] interrupts → 勾選使能、搶占優先級=15,子優先級=0
用戶代碼
//USER CODE4:定義中斷回調函數
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if( GPIO_Pin == GPIO_PIN_13 ){ // 判斷外部中斷源
//TODO 執行按鍵按下后的操作
}
}
四、GPIO_Exit:輸入模式(事件)
主要功能:使用事件屏蔽,產生事件脈沖,發送給片上外設的某個外部引腳 (外部事件External Event)
數據通路:
片上外設的某個外部引腳←產生事件脈沖←事件屏蔽EMR←[軟件觸發SWIER]←邊沿監測RTSR和FTSR←Exit輸入線(0~15號)←SYSCFG_EXTICR(引腳分組)←輸入電路←引腳GPIO_Exit
| EXIT寄存器 | 作用 | 數量x位寬 | 值 |
|---|---|---|---|
| EMR | 輸入線的事件請求(屏蔽) | 23x1 | 0-禁止、1-允許 |
五、GPIO_Analog:模擬模式
主要功能:引腳作為模擬IO引腳、功率最低(ADC或DAC↔“導線”↔引腳)
數據通路:
ADC或DAC↔上下拉電阻(無)↔保護二極管↔引腳GPIO_Analog
| GPIO寄存器 | 作用 | 數量x位寬 | 值 |
|---|---|---|---|
| MODER | 模式 | 16x2bit | 0-輸入、1-通用輸出、2-復用功能、3-模擬 |
- 模擬IO引腳無須上下拉電阻
六、GPIO_AF:復用功能模式
主要功能:將引腳設為某個外設的專用功能引腳
數據通路:
片上外設的某個外部引腳↔16選1的復用器AF↔輸入電路/輸出電路↔引腳GPIO_AF
| GPIO寄存器 | 作用 | 數量x位寬 | 值 |
|---|---|---|---|
| MODER | 模式 | 16x2bit | 0-輸入、1-通用輸出、2-復用功能、3-模擬 |
| AFR[2] | 復用功能 | 16x4bit | 引腳分配一個復用功能,連接到指定外設,作為(16選1的MUX) |
16選1的復用器:負責將GPIO和外設的某個外部引腳連接
- 1根線端:GPIO引腳
- 16根線端:AF0為系統默認的GPIO功能、AF1~AF13作為其他外設的專用功能的數字IO引腳、AF15為EVENTOUT
- 選擇端:AFR中的4bit
七、HAL庫
GPIO_InitTypeDef
- GPIO_init->Pin:用於在寄存器內部定位bit
- GPIO_Init->Mode:是否為GPIO_input的中斷模式(SYSGFG:外部中斷映射配置、EXIT:中斷屏蔽、事件屏蔽、是否上升沿觸發、是否下降沿觸發)、GPIO模式(GPIO:工作模式、輸出模式)
- GPIO_Init->Speed 設置GPIO的輸出速度
- GPIO_Init->Pull 設置GPIO的上下拉電阻
- GPIO_Init->Alternate 設置GPIO的AFR
HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init):外設初始化函數
- 檢查參數
- 遍歷GPIO所有引腳:根據GPIO_init->Pin定位,是否進行配置
- 若GPIO工作模式為輸出模式或復用功能模式:根據GPIO_Init->Mode、Speed,設置GPIO的OSPEEDR、OTYPE
- 若GPIO工作模式非模擬模式:根據GPIO_Init->Pull,設置GPIO的PUPDR
- 若GPIO工作模式為復用模式:根據GPIO_Init->Alternate,設置GPIO的AFR
- 設置GPIO的MODER
- 若為GPIO_input的中斷模式:清理EXIT的IMR、EMR、RTSR、FTSR的配置、根據GPIO_Init->Mode,設置SYSGFG的EXITCR、設置EXIT的IMR、EMR、RTSR、FTSR
