STM32F1与STM32CubeIDE快速入门-外部中断配置与功能实现
外部中断配置与功能实现
本次实例将实现通过STM32Cube IDE配置外部中断以及相关功能实现。关于STM32的中断、NVIC与EXTI请参考:
STM32F1与STM32CubeIDE快速入门-中断、NVIC与EXTI概述

1、外部中断配置
第一步、创建工程:

第二步、选择芯片:

第三步、配置系统时钟:


第四步:配置输出GPIO引脚:

将引脚PC6、PC7、PD6、PD13配置为GPIO_Output,并定义User_Label分别为:LED1、LED0、LED2、LED3
引脚的参数配置如下:

第五步、配置EXTI:

将引脚PE2、PE3、PE4、PE5配置为外部中断:GPIO_EXTI2、GPIO_EXIT3、GPIO_EXIT4、GPIO_EXIT9_5。其具体配置参数如下:



2、生成代码与功能实现
在配置完成之后,将配置保存并生成代码。我们将得到关键的代码如下:
1)GPIO初始化
在文件main.c得到如下生成代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| /\*\* \* @brief GPIO Initialization Function \* @param None \* @retval None \*/ static void MX\_GPIO\_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0};
/\* GPIO Ports Clock Enable \*/ \_\_HAL\_RCC\_GPIOE\_CLK\_ENABLE(); \_\_HAL\_RCC\_GPIOD\_CLK\_ENABLE(); \_\_HAL\_RCC\_GPIOC\_CLK\_ENABLE(); \_\_HAL\_RCC\_GPIOA\_CLK\_ENABLE();
/\*Configure GPIO pin Output Level \*/ HAL\_GPIO\_WritePin(GPIOD, LED3_Pin|LED2_Pin, GPIO_PIN_RESET);
/\*Configure GPIO pin Output Level \*/ HAL\_GPIO\_WritePin(GPIOC, LED1_Pin|LED0_Pin, GPIO_PIN_RESET);
/\*Configure GPIO pins : KEY1\_Pin KEY2\_Pin KEY3\_Pin KEY4\_Pin \*/ GPIO_InitStruct.Pin = KEY1_Pin|KEY2_Pin|KEY3_Pin|KEY4_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL\_GPIO\_Init(GPIOE, &GPIO_InitStruct);
/\*Configure GPIO pins : LED3\_Pin LED2\_Pin \*/ GPIO_InitStruct.Pin = LED3_Pin|LED2_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL\_GPIO\_Init(GPIOD, &GPIO_InitStruct);
/\*Configure GPIO pins : LED1\_Pin LED0\_Pin \*/ GPIO_InitStruct.Pin = LED1_Pin|LED0_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL\_GPIO\_Init(GPIOC, &GPIO_InitStruct);
}
|
2)中断初始化
在文件main.c得到如下生成代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| /\*\* \* @brief NVIC Configuration. \* @retval None \*/ static void MX\_NVIC\_Init(void) { /\* EXTI2\_IRQn interrupt configuration \*/ HAL\_NVIC\_SetPriority(EXTI2_IRQn, 2, 0); HAL\_NVIC\_EnableIRQ(EXTI2_IRQn); /\* EXTI3\_IRQn interrupt configuration \*/ HAL\_NVIC\_SetPriority(EXTI3_IRQn, 2, 0); HAL\_NVIC\_EnableIRQ(EXTI3_IRQn); /\* EXTI4\_IRQn interrupt configuration \*/ HAL\_NVIC\_SetPriority(EXTI4_IRQn, 2, 0); HAL\_NVIC\_EnableIRQ(EXTI4_IRQn); /\* EXTI9\_5\_IRQn interrupt configuration \*/ HAL\_NVIC\_SetPriority(EXTI9_5_IRQn, 2, 0); HAL\_NVIC\_EnableIRQ(EXTI9_5_IRQn); }
|
3)中断响应
在文件stm32f10xx_it.c得到如下生成代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| /\*\* \* @brief This function handles EXTI line4 interrupt. \*/ void EXTI4\_IRQHandler(void) { /\* USER CODE BEGIN EXTI4\_IRQn 0 \*/
/\* USER CODE END EXTI4\_IRQn 0 \*/ HAL\_GPIO\_EXTI\_IRQHandler(GPIO_PIN_4); /\* USER CODE BEGIN EXTI4\_IRQn 1 \*/
/\* USER CODE END EXTI4\_IRQn 1 \*/ }
/\*\* \* @brief This function handles EXTI line[9:5] interrupts. \*/ void EXTI9\_5\_IRQHandler(void) { /\* USER CODE BEGIN EXTI9\_5\_IRQn 0 \*/
/\* USER CODE END EXTI9\_5\_IRQn 0 \*/ HAL\_GPIO\_EXTI\_IRQHandler(GPIO_PIN_5); /\* USER CODE BEGIN EXTI9\_5\_IRQn 1 \*/
/\* USER CODE END EXTI9\_5\_IRQn 1 \*/ }
|
从中断响应函数可以看出,统一调用了HAL_GPIO_EXTI_IRQHandler函数。
函数void HAL_GPIO_EXTI_IRQHandler (uint16_t GPIO_Pin)处理 EXTI 中断请求。并在内部调用了void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| /\*\* \* @brief This function handles EXTI interrupt request. \* @param GPIO\_Pin: Specifies the pins connected EXTI line \* @retval None \*/ void HAL\_GPIO\_EXTI\_IRQHandler(uint16_t GPIO_Pin) { /\* EXTI line interrupt detected \*/ if (\_\_HAL\_GPIO\_EXTI\_GET\_IT(GPIO_Pin) != 0x00u) { \_\_HAL\_GPIO\_EXTI\_CLEAR\_IT(GPIO_Pin); HAL\_GPIO\_EXTI\_Callback(GPIO_Pin); } }
|
因此,我们只需要在void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)函数中实现相应的功能功能逻辑即可。该函数在stm32f10xx_it.c文件中实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| \* USER CODE BEGIN 1 \*/ void HAL\_GPIO\_EXTI\_Callback(uint16_t GPIO_Pin) { // KEY1按下 if (GPIO_Pin == KEY1_Pin) { // 自定义应用程程序 keyPressed = KEY1_PRESSED; } // KEY2按下 if (GPIO_Pin == KEY2_Pin) { keyPressed = KEY2_PRESSED; } // KEY3按下 if (GPIO_Pin == KEY3_Pin) { keyPressed = KEY3_PRESSED; } // KEY4按下 if (GPIO_Pin == KEY4_Pin) { keyPressed = KEY4_PRESSED; } } /\* USER CODE END 1 \*/
|
在main.c文件中实现按键处理逻辑如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| /\* USER CODE BEGIN 4 \*/ void Handle\_KeyPressed(void) { HAL\_Delay(50); // 延时去抖动处理 switch (keyPressed) { case KEY1_PRESSED: HAL\_GPIO\_TogglePin(LED0_GPIO_Port, LED0_Pin); break; case KEY2_PRESSED: HAL\_GPIO\_TogglePin(LED1_GPIO_Port, LED1_Pin); break; case KEY3_PRESSED: HAL\_GPIO\_TogglePin(LED2_GPIO_Port, LED2_Pin); break; case KEY4_PRESSED: HAL\_GPIO\_TogglePin(LED3_GPIO_Port, LED3_Pin); break; } keyPressed = KEY_PRESSED_NONE; } /\* USER CODE END 4 \*/
|
在main.c文件中调用实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| /\*\* \* @brief The application entry point. \* @retval int \*/ int main(void) { /\* USER CODE BEGIN 1 \*/
/\* USER CODE END 1 \*/
/\* MCU Configuration--------------------------------------------------------\*/
/\* Reset of all peripherals, Initializes the Flash interface and the Systick. \*/ HAL\_Init();
/\* USER CODE BEGIN Init \*/
/\* USER CODE END Init \*/
/\* Configure the system clock \*/ SystemClock\_Config();
/\* USER CODE BEGIN SysInit \*/
/\* USER CODE END SysInit \*/
/\* Initialize all configured peripherals \*/ MX\_GPIO\_Init();
/\* Initialize interrupts \*/ MX\_NVIC\_Init(); /\* USER CODE BEGIN 2 \*/
/\* USER CODE END 2 \*/
/\* Infinite loop \*/ /\* USER CODE BEGIN WHILE \*/ while (1) { /\* USER CODE END WHILE \*/
/\* USER CODE BEGIN 3 \*/ // 处理按键逻辑 Handle\_KeyPressed(); } /\* USER CODE END 3 \*/ }
|
3、硬件电路
1)LED驱动电路

2)按键驱动电路

文章来源: https://iotsmart.blog.csdn.net/article/details/123224769
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!