为什么使用中断
当我们运行主程序时,常常会遇到需要突发情况需要CPU立刻解决,但解决完突发情况后要能够继续之前的程序,此时就会用到中断。当接收到中断信号时,CPU会立即停下当前的程序,并运行中断程序,当中断程序完成后,会返回之前断点,继续运行主程序。
怎么使用中断
中断有很多的中断通道,包含EXTI、TIM、ADC、USART等多个外设,每个外设会有多个通道。
对于这些通道,stm32使用NVIC(嵌套中断向量控制器)来进行管理。
NVIC是一个内核外设,可以考虑为CPU的秘书,当有多个中断输入时,NVIC可以根据优先级,将这些中断有条理地一个一个地传给CPU,再让CPU进行处理。
抢占优先级和响应优先级
NVIC的中断优先级分为抢占优先级和响应优先级,由优先级寄存器的四位决定,最高优先级为0。
抢占优先级能产生中断嵌套,抢占优先级高的可以在抢占优先级低的程序中被触发。
响应优先级是在相同抢占优先级的基础上进行的,响应优先级越高越先被执行。
当抢占优先级和响应优先级相同时,根据中断号进行排队。
EXTI
EXTI,外部中断,可以检测指定GPIO的电平信号,当指定的GPIO口产生电平变化时,EXTI会立即向NVIC发出中断申请,通过NVIC中断CPU然后由CPU执行中断程序。
触发响应方式分为中断响应和事件响应。事件响应是指当外部检测到引脚电平变化时,中断信号不会通向CPU,反而会通过其他外设。
如何配置中断
- 打开RCC
- 配置GPIO,选择为输入模式
- 配置AFIO,选择使用的GPIO并连接到后面的EXTI
- 配置EXTI,选择边沿触发方式(上升沿或者下降沿)
- 选择触发的响应方式(中断响应和事件响应)
- 配置NVIC,选择合适的优先级
//开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//配置GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//对于外部中断来说,需要选择浮空输入、上拉输入、下拉输入
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_14;//配置为PB14
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//50MHz
GPIO_Init(GPIOB,&GPIO_InitStructure);
//配置AFIO
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
//配置EXTI
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line14;//14号线
EXTI_InitStructure.EXTI_LineCmd=ENABLE;//使能
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//中断模式
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿触发
EXTI_Init(&EXTI_InitStructure);
//配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//程序的分组方式需要选择同一种
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;//位置
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级,根据NVIC的配置,范围为0~3
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//响应优先级,根据NVIC的配置,范围为0~3
NVIC_Init(&NVIC_InitStructure);
中断函数的函数名是固有的,可以通过启动文件进行查询。
void EXTI15_10_IRQHandler(void)//中断函数的名字是固定的,要去启动文件startup_stm32f10x_md.s中找到对应的函数名字
{
//中断标志位的判断,确保是想要的判断
if(EXTI_GetITStatus(EXTI_Line14)== SET)//判断是否为14号,该条件代表"是"
{
Count++;
EXTI_ClearITPendingBit(EXTI_Line14);//如果不进行标志位的清除,程序会一直运行中断函数
}
}