【STM32】【STM32CubeMX】STM32CubeMX的使用之二:外部中斷

Joseph Cooper發表於2020-09-30

前言

  今天我們來學習STM32CubeMX中外部中斷的使用,實現按下KEY0 KEY1 KEY2

中斷-->IO-->按鍵對映:
  EXTI2-->PE2-->KEY2
  EXTI3-->PE3-->KEY1
  EXTI4-->PE4-->KEY0
IO-->LED對映:
  PB5-->LED0
  PE5-->LED1


1、GPIO及RCC配置

在這裡插入圖片描述
  在配置GPIO之前需要先開啟HSE,並設定為晶振為時鐘源。
在這裡插入圖片描述
  而後就可以設定按鍵對應的管腳為外部中斷模式了。
在這裡插入圖片描述
  點選System Core中的GPIO選項後先選擇按鍵對映的GPIOGPIO mode [ 1 ] ^{[1]} [1]:其中有六個選項:
External Interupt Mode with Rising edge trigger detection
External Interupt Mode with Falling edge trigger detection
External Interrupt Mode with Rising/Faling edge trigger detection
External Event Mode with Rising edge trigger detection
External Event Mode with Falling edge trigger detection
External Event Mode with Rising/Faling edge trigger detection
  分別對應著外部中斷和外部事件的上升沿觸發、下降沿觸發和上升/下降沿觸發。
  如果按鍵沒有外接上拉電阻的話我們需要先選擇Pull up [ 2 ] ^{[2]} [2]開啟內建上拉電阻即可實現按鍵按下產生下降沿。
  在User Label [ 3 ] ^{[3]} [3]中我們可以自定義GPIO的名稱,這個名稱會在Pinout View介面做同步更改。

2、NVIC設定

在這裡插入圖片描述
  使用中斷,免不了配置NVIC我們可以參照下表來選擇Proority Group [ 1 ] ^{[1]} [1],然後選中要配置的EXTI linex interruptPreemption Priority [ 2 ] ^{[2]} [2]中選擇其搶佔優先順序和子優先順序,然後勾選Enable來使能中斷。
在這裡插入圖片描述
  在NVIC邊上還有一個Code generation選項卡在其中我們可以選擇我們想要排序的中斷,然後可以在Rank欄看到排序序號。
在這裡插入圖片描述

在這裡插入圖片描述

3、其他設定

3.1、時鐘設定、生成工程

  按照下圖選擇HSE作為主時鐘源來源即可。
在這裡插入圖片描述
  隨後按照流程填寫工程名,設定Code generation而後生成工程即可。

3.2、中斷後的操作

  中斷觸發後在HAL裡呼叫順序是這樣子的:
EXTI15_10_IRQHandler --> HAL_GPIO_EXTI_IRQHandler --> HAL_GPIO_EXTI_Callback
  而__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)函式是一個弱定義函式。
  函式名稱前面加上__weak修飾符,我們一般稱這個函式為“弱函式”。
  加上了__weak 修飾符的函式,使用者可以在使用者檔案中重新定義一個同名函式,最終編譯器編譯的時候,會選擇使用者定義的函式,如果使用者沒有重新定義這個函式,那麼編譯器就會執行__weak宣告的函式,並且編譯器不會報錯。所以我們可以在別的地方定義一個相同名字的函式,而不必也儘量不要修改之前的函式。
  ST官方這麼做即做到了響應外部中斷又做到了讓事件在清楚外部中斷標誌之後完成,從而避免了一些中斷巢狀
  我們可以在gpio.c檔案的最下方定義自己的HAL_GPIO_EXTI_Callback函式來完成在中斷中想做的操作
在這裡插入圖片描述

按鍵消抖:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin==GPIO_PIN_2)//KEY2
	{	
		HAL_Delay(20);//延時20ms
		if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2)==GPIO_PIN_RESET)
		{
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
			HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
		}
	}
	else if(GPIO_Pin==GPIO_PIN_3)//KEY1
	{	
		HAL_Delay(20);//延時20ms
		if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET)
		{
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
		}
	}
	else if(GPIO_Pin==GPIO_PIN_4)//KEY0
	{	
		HAL_Delay(20);//延時20ms
		if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==GPIO_PIN_RESET)
		{
			HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
		}
	}
}

相關文章