中断
中断就是突发紧急事件需要去处理,计算机暂时放下当前做的事情去处理中断,在处理完中断后,再处理发生中断之前处理的事情。
中断分为不可屏蔽中断和可屏蔽中断。不可屏蔽中断就是CPU必须响应的中断;可屏蔽中断就是CPU可以选择不响应的中断。
中断还分为内部中断和外部中断。内部中断为CPU内部发生的中断;外部中断为CPU外部发生的中断。
中断是分优先级的,高优先级可以打断低优先级。
其意义就是可以实时控制,能够在第一时间产生相应的动作。
STM中断架构
内部中断和外部中断传入NVIC嵌套向量中断控制器,由NVIC传入内核指令执行单元,经内核查询各中断对应的中断向量表,然后按照中断向量表的顺序执行中断。
片内外设产生的中断为外部中断。
EXTI外部中断/事件控制器
External(Extended) interrupt/event Controller,外部(扩展)中断事件控制器,作用是检测、管理、配置事件/中断请求。
中断:要进入NVIC,有相应的中断服务函数,需要CPU处理
事件:不进入NVIC,仅用于内部硬件自动控制的,如:TIM、DMA、ADC
中断/事件控制器框图
输入线的电平变化输入边沿检测电路,在检测电路内经上升沿/下降沿触发选择寄存器比较后,选择是否输出高电平,高电平通过或门使请求挂起寄存器相应的位置1,输出至NVIC的与门,只要开启对应的中断,电平就会输出至NVIC。
EXTI线0~15选择一个引脚号后,其他端口的该引脚就不能再触发外部中断。例如GPIOA0配置为EXTI0,那么其他端口的引脚0就不能再配置为EXTI0了。
不是所有的中断线都有自己的中断函数,例如EXTI0-EXTI4,都有自己对应的中断函数EXTIx_IRQHandle();但是EXTI5-EXTI9,共用一个中断函数EXTI9_5_IRQHandle();EXTI10-EXTI15,共用一个ISR中断函数EXTI15_10_IRQHandle()。
嵌套向量中断控制器NVIC
NVIC(Nested Vectored Interrupt Controller)管理所有中断,68个可屏蔽中断,10个系统中断,可屏蔽中断和部分系统中断可以配置优先级,总共有16个可编程的优先级(4位中断优先级)。
分为抢占,响应,自然优先级,数字越小,优先级越高。
抢占优先级:判断一个中断是否可以打断另外一个中断的中断服务程序抢先运行。优先级高的服务可以打断优先级低的服务,优先运行。
响应优先级:如果几个抢占优先相同的中断同时触发,那么响应优先级高的优先运行。
自然优先级:由厂家进行设置的优先级,记录在中断向量表内。
判断中断的优先级,先看抢占优先级,抢占优先级高的中断优先级别高。抢占优先级相同的情况下,响应优先高的中断优先级别高。抢占优先级和响应优先级相同的情况下,根据中断向量表确定。
抢占优先级 | 响应优先级 |
4位 | 0位 |
3位 | 1位 |
2位 | 2位 |
1位 | 3位 |
0位 | 4位 |
系统中断
可屏蔽中断
具体请查看参考手册。
HAL库驱动函数
TM32f1xx_HAL_Cortex.h中查看NVIC配置函数和。
函数名 | 功能 |
HAL_NVIC_SetPriorityGrouping() | 设置 4 位二进制数的优先级分组策略 |
HAL_NVIC_SetPriority() | 设置某个中断的抢占优先级和次优先级 |
HAL_NVIC_EnableIRQ() | 启用某个中断 |
HAL_NVIC_DisableIRQ() | 禁用某个中断 |
HAL_NVIC_GetPriorityGrouping() | 返回当前的优先级分组策略 |
HAL_NVIC_GetPriority() | 返回某个中断的抢占优先级、次优先级数值 |
HAL_NVIC_GetPendingIRQ() | 检查某个中断是否被挂起 |
HAL_NVIC_SetPendingIRQ() | 设置某个中断的挂起标志,表示发生了中断 |
HAL_NVIC_ClearPendingIRQ() | 清除某个中断的挂起标志 |
外部中断EXTI0~15
函数名 | 功能描述 |
__HAL_GPIO_EXTI_GET_IT() | 检查某个外部中断线是否有挂起(Pending)的中断 |
__HAL_GPIO_EXTI_CLEAR_IT() | 清除某个外部中断线的挂起标志位 |
__HAL_GPIO_EXTI_GET_FLAG() | 与__HAL_GPIO_EXTI_GET_IT () 的代码和功能完全相同 |
__HAL_GPIO_EXTI_CLEAR_FLAG() | 与__HAL_GPIO_EXTI_CLEAR_IT () 的代码和功能完全相同 |
__HAL_GPIO_EXTI_GENERATE_SWIT() | 在某个外部中断线上产生软中断 |
HAL_GPIO_EXTI_IRQHandler() | 外部中断 ISR 中调用的通用处理函数 |
HAL_GPIO_EXTI_Callback() | 外部中断处理的回调函数,需要用户重新实现 |
HAL库中断调用说明
ISR调用HAL_GPIO_EXTI_IRQHandler(),HAL_GPIO_EXTI_IRQHandler()调用HAL_GPIO_EXTI_CallBack();
我们只需要重定义HAL_GPIO_EXTI_CallBack()函数就可以实现中断。
Cubemx
1.配置引脚为中断触发引脚
2.引脚的具体配置(模式,上下拉,用户标签)
3.更改优先级
程序示范
Void HAL_GPIO_EXTI_Callback(uint6_t GPIO_Pin)
{
if(GPIO_PIN_1 == GPIO_Pin)
{
HAL_PIN_TogglePin(GPIOA, GPIO_PIN_0);
}
}
注意:不要在中断内调用延时函数,如需调用,请更改Time base:System tick timer的优先级,至少要高于调用延时函数的中断优先级