目录
中断框图
基本概念
1、中断:有某个事件发生并产生中断,并跳转到对应的中断处理程序中。
2、事件:是表示检测到某一动作(电平边沿)触发事件发生了。
- 中断可能会被更优先的中断屏蔽,而事件不会。
- 事件是中断的触发源,事件可以触发中断,也可以不触发,开放了对应的中断屏蔽位,则事件可以触发相应的中断。 事件还是其它一些操作的触发源,比如DMA,还有TIM中影子寄存器的传递与更新。简单点就是中断一定要有中断服务函数,但是事件却没有对应的函数。
- 事件可以在不需要CPU干预的情况下,执行这些操作,但是中断则必须要CPU介入。
- 事件本质上就是一个触发信号,是用来触发特定的外设模块或核心本身(唤醒)。
中断处理流程
1、图中的蓝色虚线箭头,标出了外部中断信号的传输路径。首先,外部信号从编号1的芯片管脚进入,经过编号2的边沿检测电路,通过编号3的或门进入中断挂起请求寄存器,最后经过编号4的与门输出到NVIC中断检测电路。
2、编号2的边沿检测电路:这个边沿检测电路受上升沿或下降沿选择寄存器控制,用户可以使用这两个寄存器控制需要哪一个边沿产生中断,因为选择上升沿或下降沿是分别受2个平行的寄存器控制,所以用户可以同时选择上升沿或下降沿,而如果只有一个寄存器控制,那么只能选择一个边沿了。
3、编号3的或门,这个或门的另一个输入是软件中断/事件寄存器,从这里可以看出,软件可以优先于外部信号请求一个中断或事件,即当软件中断/事件寄存器的对应位。为"1"时,不管外部信号如何,编号3的或门都会输出有效信号。然后,一个中断或事件请求信号经过编号3的或门后,进入挂起请求寄存器,到此之前,中断和事件的信号传输通路都是一致的,也就是说,挂起请求寄存器中记录了外部信号的电平变化。
4、外部请求信号最后经过编号4的与门,向NVIC中断控制器发出一个中断请求,如果中断屏蔽寄存器的对应位为"0",则该请求信号不能传输到与门的另一端,实现了中断的屏蔽。
事件与中断的区别
1、从外部激励信号来看,中断和事件的产生源都可以是一样的。之所以分为2个部分是由于中断是有CPU参与的,需要软件的中断服务函数才能完成中断后产生的结果。但是事件,是靠脉冲发生器产生一个脉冲,进而由硬件自动完成这个事件产生的结果,当然相应的联动部件需要先设置好,比如引起DMA操作,AD转换等。
2、事件机制提供了一个完全有硬件自动完成的触发到产生结果的通道,不要软件的参与,降低了CPU的负荷,节省了中断资源,提高了响应速度(硬件总快于软件),是利用硬件来提升CPU芯片处理事件能力的一个有效方法。
中断优先级
- 抢占优先级:具有抢占属性,可以打断正在执行的中断,实现中断的嵌套执行。
- 响应优先级:抢占优先级相同的情况下,响应优先级高的先执行。
- 优先顺序:
- 数字越小优先级越高。
- 抢占优先级越高(数字越小),越先执行,会打断优先级低的。
- 抢占优先级相同,响应优先级高的不能打断响应优先级低的,同时发生,响应优先级高的先执行。
- 响应优先级和抢占优先级都相同,按先后顺序执行。
-
抢占和响应优先级相同,且同时到达,按照中断向量表的顺序执行。
- 优先级分组:
- 用四位bit来表示优先级的分组。
- 第0组:所有4位用于指定响应优先级。
- 第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级。
- 第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级。
- 第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级。
- 第4组:所有4位用于指定抢占式优先级。
代码实现
这里只写出了外部中断的基本设置,具体应用还要看各位大哥的需求而进行改写。
HAL_Init()
{
.......
默认中断分组是4
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);//设置中断分组
HAL_MspInit();
{ .......
//设置中断分组,如果与外面重复就先不进行设置。
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
.......
}
......
}
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOD_CLK_ENABLE();//使能时钟线,时钟源为外部晶振HSE
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_SET);
/*Configure GPIO pins : PA0 PA1 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;//设置中断,且下降沿触发方式
GPIO_InitStruct.Pull = GPIO_NOPULL;//无上拉
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI0_IRQn, 6, 0);//设置中断抢占优先级6,响应优先级0
HAL_NVIC_EnableIRQ(EXTI0_IRQn);//使能中断
HAL_NVIC_SetPriority(EXTI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI1_IRQn);
}
void EXTI0_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);//中断处理函数
}
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);//外部中断都会调用到这个回调函数处理。
//在这个函数里进行改写
}
}
CubeMX配置
1、
2、
3、
4、
参考连接:【转】1-单片机STM32---中断与事件的区别 - Engraver - 博客园 (cnblogs.com)