点击获取笔记和代码文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Jk4vePW-1671689970669)(https://typora-1309501826.cos.ap-nanjing.myqcloud.com//CSDN/Untitled.png)]
处理器根据不同中断的重要程序设置不同的优先等级。
不同优先级中断的处理原则是:高级中断可以打断低级中断;低级中断不能打断高级中断。
NVIC属于Cortex-M内核的组件,管理所有的中断和异常,为中断源分配中断通道
中断向量表
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD WWDG_IRQHandler ; Window Watchdog
DCD PVD_IRQHandler ; PVD through EXTI Line detect
DCD TAMPER_IRQHandler ; Tamper
DCD RTC_IRQHandler ; RTC
DCD FLASH_IRQHandler ; Flash
DCD RCC_IRQHandler ; RCC
DCD EXTI0_IRQHandler ; EXTI Line 0
DCD EXTI1_IRQHandler ; EXTI Line 1
DCD EXTI2_IRQHandler ; EXTI Line 2
DCD EXTI3_IRQHandler ; EXTI Line 3
DCD EXTI4_IRQHandler ; EXTI Line 4
DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
DCD ADC1_2_IRQHandler ; ADC1_2
DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
DCD CAN1_RX1_IRQHandler ; CAN1 RX1
DCD CAN1_SCE_IRQHandler ; CAN1 SCE
DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
DCD TIM1_BRK_IRQHandler ; TIM1 Break
DCD TIM1_UP_IRQHandler ; TIM1 Update
DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
DCD TIM2_IRQHandler ; TIM2
DCD TIM3_IRQHandler ; TIM3
DCD TIM4_IRQHandler ; TIM4
DCD I2C1_EV_IRQHandler ; I2C1 Event
DCD I2C1_ER_IRQHandler ; I2C1 Error
DCD I2C2_EV_IRQHandler ; I2C2 Event
DCD I2C2_ER_IRQHandler ; I2C2 Error
DCD SPI1_IRQHandler ; SPI1
DCD SPI2_IRQHandler ; SPI2
DCD USART1_IRQHandler ; USART1
DCD USART2_IRQHandler ; USART2
DCD USART3_IRQHandler ; USART3
DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
__Vectors_End
微控制器片内集成了很多外设,对于单个外设而言,它通常具备若干个可以引起中断的中断源,而该外设的所有中断源只能通过指定的中断通道向内核申请中断。
以STM32F103芯片为例,它支持43个可屏蔽中断通道(不包括16个Cortex-M3的中断线),已经固定分配给相应的片内外设。由于中断源数量较多,而中断通道有限,会出现多个中断源共享同一个中断通道的情况。
中断嵌套:
多个中断同时提出中断申请时
HAL库初始化函数HAL_Init将优先级分组设置为第4组,即有0~15,共16级抢占优先级,没有子优先级。编号越小的优先级越高:0号为最高,15号为最低。
触发方式:
引脚分组:
中断通道:
在STM32CubeMX中完成
HAL库的接口函数完成
HAL_PPP_IRQHandler
。HAL_PPP_IRQHandler
完成了中断标志的判断和清除。startup_stm32fxxx.s
**weak
”。weak
属性的函数表示:如果该函数没有在其他文件中定义,则使用该函数;如果用户在其他地方定义了该函数,则使用用户定义的函数。stm32fxxx_it.c
该文件存放在User组中,用于存放各个中断的中断服务程序;
在使用CubeMX软件进行初始化配置时,如果使能了某一个外设的中断功能,那么在生成代码时,相对应的外设中断服务程序HAL_PPP_IRQHandler
就会自动添加到该文件中,用户只需要在该函数中添加相应的中断处理代码即可。
外部中断所对应的中断服务程序
外部中断线 | 中断服务程序的函数名称 |
---|---|
外部中断线0(EXTI Line 0) | EXTI0_IRQHandler |
外部中断线1(EXTI Line 1) | EXTI1_IRQHandler |
外部中断线2(EXTI Line 2) | EXTI2_IRQHandler |
外部中断线3(EXTI Line 3) | EXTI3_IRQHandler |
外部中断线4(EXTI Line 4) | EXTI4_IRQHandler |
外部中断线5~9(EXTI Line[9:5]) | EXTI9_5_IRQHandler |
外部中断线10~15(EXTI Line[15:10]) | EXTI15_10_IRQHandler |
例如
/**
* @brief This function handles EXTI line0 interrupt.
*/
void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
/* USER CODE END EXTI0_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
/* USER CODE BEGIN EXTI0_IRQn 1 */
/* USER CODE END EXTI0_IRQn 1 */
}
假设微控制器芯片为STM32F103,设置引脚PA0为外部中断功能。当引脚PA0出现脉冲边沿时,将触发外部中断。
由于外部中断主要是利用GPIO引脚实现,因此外部中断数据类型的定义放在stm32f1xx_hal_gpio.h
文件中,外部中断接口函数的实现放在stm32f1xx_hal_gpio.c
文件中。
引脚初始化
成员变量Mode的取值范围
GPIO_MODE_IT_RISING
上升沿触发GPIO_MODE_IT_FALLING
下降沿触发GPIO_MODE_IT_RISING_FALLING
双边沿触发外部中断通用处理函数HAL_GPIO_EXTI_IRQHandler
/**
* @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_IRQHandler(uint16_t GPIO_Pin) |
---|---|
功能描述 | 作为所有外部中断发生后的通用处理函数 |
入口参数 | GPIO_Pin:连接到对应外部中断线的引脚,范围是 GPIO_PIN_0~GPIO_PIN_15 |
返回值 | 无 |
注意事项 | 1. 所有外部中断服务程序均调用该函数完成中断处理 |
外部中断回调函数HAL_GPIO_EXTI_Callback
/**
* @brief EXTI line detection callbacks.
* @param GPIO_Pin: Specifies the pins connected EXTI line
* @retval None
*/
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(GPIO_Pin);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_GPIO_EXTI_Callback could be implemented in the user file
*/
}
函数原型 | void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) |
---|---|
功能描述 | 外部中断回调函数,用于处理具体的中断任务 |
入口参数 | GPIO_Pin:连接到对应外部中断线的引脚,范围是 GPIO_PIN_0~GPIO_PIN_15 |
返回值 | 无 |
注意事项 | 1. 该函数由外部中断通用处理函数HAL_GPIO_EXTI_IRQHandler调用,完成所有外部中断的任务处理 |
利用按键KEY1改变指示灯LED1的闪烁频率,闪烁频率设置为3档:
配置PA0为GPIO_EXIT0,PA1为GPIO_Output
PA1保持默认GPIO输出模式即可
PA0配置为下降沿触发,上拉模式
使能外部中断线
配置中断优先级分组为第四组16级抢占优先级,没有子优先级
以上步骤生成如下代码:
stm32f1xx_hal_gpio.c
中生成GPIO引脚配置代码,并在main.c中调用
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
/*Configure GPIO pin : PA0 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PA1 */
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}
**stm32fxxx_it.c
**中生成外设中断服务程序
/**
* @brief This function handles EXTI line0 interrupt.
*/
void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
/* USER CODE END EXTI0_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
/* USER CODE BEGIN EXTI0_IRQn 1 */
/* USER CODE END EXTI0_IRQn 1 */
}
编写程序
在main.c
中定义指示灯闪烁频率,0代表1Hz,1代表5Hz,2代表20Hz
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
volatile uint8_t Speed = 0;
/* USER CODE END PV */
在main.c
中编写应用代码
/* USER CODE BEGIN 3 */
if (Speed == 0)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1);
HAL_Delay(1000);
}
else if (Speed == 1)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1);
HAL_Delay(200);
}
else
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1);
HAL_Delay(50);
}
}
/* USER CODE END 3 */
在main.c
中外部中断回调函数HAL_GPIO_EXTI_Callback
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_0)
{
Speed++;
if (Speed == 3)
{
Speed = 0;
}
}
}
/* USER CODE END 4 */