一、中断的一些基本概念
1、中断:
在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序(中断服务函数),处理完成后又返回原来被暂停的位置继续运行主程序,就好像主世界时间暂停,我们进入到异世界打怪,打通异世界后在回到主世界
2、中断优先级:
当有多个中断源同时申请中断时,CPU会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源,数字越小级别越高,中断优先级分组在一个工程中只分配一次,一般写主函数里
①、抢占优先级:在两个中断争抢运行时抢占优先级高的先运行
②、响应优先级:在两个抢占优先级相同时响应优先级高的先运行
分组方式 | 抢占优先级 | 响应优先级 |
---|---|---|
0 | 0位 取值为0 | 4位 取值为0~15 |
1 | 1位 取值位0~1 | 3位 取值为0~7 |
2 | 2位 取值为0~3 | 2位 取值为0~3 |
3 | 3位 取值为0~1 | 1位 取值位0~1 |
4 | 4位 取值为0~15 | 0位 取值为0 |
3、中断嵌套:
当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回
4、中断服务函数:
简单的说就是进入中断后将要执行的程序,在stm32中每一条中断都有他规定的中断服务函数名,具体在相应的启动文件中(如:system_stm32f10x.c),下图为stm32f1的部分中断服务函数名
5、STM32中断
68个可屏蔽中断通道,包含EXTI、TIM、ADC、USART、SPI、I2C、RTC等多个外设
使用NVIC统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级
二、EXTI外部中断
1、EXTI简介
EXTI(Extern Interrupt)外部中断 EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序
支持的触发方式:上升沿/下降沿/双边沿/软件触发
支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断,GPIOA~G0-->EXTI0、
通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒 触发响应方式:中断响应/事件响应
2、EXTI框图
3、EXTI基本结构
(1)、配置好相应的GPIO口引脚;
(2)、用APIO选择GPIO口的引脚对应到相应的EXTI线上;
(3)、配置好EXTI配置程序;
(4)、配置NVIC。
4、EXTI初始化代码示例
void Encoder_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能AFIO时钟
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);//afio设置
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);//afio设置
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1; // 第一和零条中断线
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 开启
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
EXTI_Init(&EXTI_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置向量分组2,两位抢占优先级,两位响应优先级
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级
NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //响应优先级
NVIC_Init(&NVIC_InitStructure);}