- 中断
- 中断:暂停当前程序的运行,转而去处理更为要紧的程序,事后完好地恢复当前程序的运行,这个过程叫做中断。
- 中断的意义:
- 提高实时性
- 支持多任务处理
- 提高CPU利用率,降低功耗
- 中断控制器(NVIC)
- NVIC是ARM Cortex-M内核中的一个组件,用于管理中断和异常。
- NVIC作用是设置中断优先级分组,设置某个中断的中断优先级,使能或者失能某个中断
- 中断向量表
- 中断向量表是内存中的一个区域,包含了中断服务程序(ISR)的入口地址和中断优先级等。当中断发生时,处理器通过这个表跳转到相应的中断服务程序。
- 中断优先级
- 优先级
- 抢占优先级(pre):高抢占优先级可以打断正在执行的低抢占优先级中断;
- 响应优先级(sub):当抢占优先级相同时,响应优先级高的先执行,但是不能相互打断;
- 抢占优先级和响应优先级都相同的情况下,自然优先级(中断向量表内的优先级)越高的先执行;
- 优先级数字越小越高;
- 优先级分组
- 0 抢占0bit 响应4bit(2^4 = 16级)
- 1 抢占1bit 响应3bit
- 2 抢占2bit 响应2bit
- 3 抢占3bit 响应1bit
- 4 抢占4bit 响应0bit
- 中断服务函数
- 中断服务函数无参无返回值
- 所有中断源的中断服务函数都有定的弱定义,如果使用需要在程序中按照弱定义的函数名重新定义编写中断服务函数
- 中断服务函数应当尽量短小且保证可重入性
- 可重入:
- 可以被打断
- 可以被恢复
- 被恢复后完全从上次被打断处运行且数据不发生改变
- 可重入化处理:
- 尽量使用局部变量
- 如果一定要用,使用互斥信号量保护的全局变量
- 只使用可重入的系统调用
- 只使用可重入的其他函数
- 谨慎使用堆区内存
- 避免使用浮点运算
- 中断使用流程
- 在一个项目中进行一次中断优先级分组
- 在需要开启中断的函数中配置中断优先级
- 在需要开启中断的函数中使能对应中断
- 编写中断源对应的中断服务函数
- EXTI(外部中断)使用流程
- 工程中配置中断优先级分组
- 函数中配置中断优先级
- 函数中使能对应的EXIT中断
- 编写EXIT为中断源的中断服务函数
- 通过AFIO配置GPIO引脚与中断线之间的映射关系,使用GPIO_EXTILineConfig()函数配置GPIO为中断源。
- 配置EXTI线,包括触发方式(上升沿、下降沿或双边沿),使用EXTI_InitTypeDef结构体进行配置,并调用EXTI_Init()函数初始化。
- 例程:
void EXTI_Key_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
KEY1_INT_GPIO_CLK_ENABLE();
GPIO_InitStructure.Pin = KEY1_INT_GPIO_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStructure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);
HAL_NVIC_SetPriority(KEY1_INT_EXTI_IRQ, 0, 0);
HAL_NVIC_EnableIRQ(KEY1_INT_EXTI_IRQ);
}
void EXTI1_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line1) != RESET)
{
LED_TOGGLE();
EXTI_ClearITPendingBit(EXTI_Line1);
}
}