NVIC 中断优先级管理
Nested Vectored Interrupt Controller,嵌套向量中断控制器。
CM3支持256个中断,16个内核中断,240个外部中断,256级可编程中断设置。
STM32使用了其中一部分,16个内核中断,107系列有68个可屏蔽中断(103系列只有60个),16级可编程的中断优先级。
中断寄存器
ISER[8],Interrupt Set-Enable Registers,中断使能寄存器组,用8个32位寄存器控制(256个可编程中断),每个位控制一个中断。由于STM32f103只有60个可屏蔽中断,于是只用了 ISER[0] 和 ISER[1] 64个中断中的前60位。
ISER[0] 的 bit0 至 bit31 对应中断0至31,ISER[1] 的 bit0 至 bit27 对应中断32至59,使能某个中断就将对应的 ISER 置1
ICER[8],Interrupt Clear-Enable Register,中断除能寄存器组。中断对应与ISER相同,但作用是置1清除中断使能
ISPR[8],Interrupt Set-Pending Register,中断挂起控制寄存器组。置1将正在进行的中断挂起,暂停等待执行,执行同级或更高级别的中断
ICPR[8],Interrupt Clear-Pending Register,中断解挂控制寄存器组,置1将挂起的中断解挂
IABR[8],Interrupt Active Bit Register,中断激活标志位寄存器组,只读寄存器,为1表示该位对应的中断正在被执行
IP[240],Interrupt Priority Registers,中断优先级控制寄存器组,相当重要! STM32的中断分组与其密切相关。
IP[240]有240个8bit寄存器组成,每个可屏蔽中断占用8bit,总共可表示240个可屏蔽中断,STM32f1使用其中60个,IP[59]至IP[0]分别对应中断59至0。每个可屏蔽中断只用高4位,分为抢占优先级和响应优先级,抢占优先级在前、响应优先级在后,各占几位由SCB-》AIRCR中的中断分组设置。采用库函数==NVIC_PriorityGroupConfig () ==配置。
如果组设置为3,则每个中断的中断优先寄存器高4位中前3位是抢占优先级,优先级级别0-7;低1位是响应优先级,优先级级别0-1。
STM32的中断向量有抢占属性和响应属性,属性编号越小,优先级别越高。
抢占属性是打断其他中断的属性,有这个属性就有嵌套中断。由库函数NVIC_IRQChannelPreemptionPriority() 进行参数配置。
响应属性应用在抢占属性相同时(前提),两个中断向量的抢占优先级相同时,如果同时到达,则优先处理响应优先级高的中断。由库函数NVIC_IRQChannelSubPriority() 进行参数配置。
库函数配置
NVIC 中断管理函数声明在 misc.c 文件里
1. 中断优先级分组函数 NVIC_PriorityGroupConfig()
此函数在系统工程中只能被调用一次!一旦确定好中断分组就不能更改!
目前了解到的在主函数中调用该函数
按 F12 查看函数定义块:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
SCB-》AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}
可以看到,这个函数通过设置 SCB-》AIRCR 寄存器设置中断分组。
补充:
assert_param(),断言机制函数,在stm32f10x_conf.h文件中可以看到 assert_param() 是一个宏定义,作用就是检测传递给函数的参数是否是有效的参数,返回值是 0假 1真。
中断优先组配置示例:分组值为2,2优先2抢占:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 暂时看到的此函数调用都是在主函数里,以后看到其他程序结构再补充:
2. 中断初始化函数 NVIC_Init
函数定义:
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) 查看结构体 NVIC_InitTypeDef 的成员变量:
typedef struct
{
uint8_t NVIC_IRQChannel;
uint8_t NVIC_IRQChannelPreemptionPriority;
uint8_t NVIC_IRQChannelSubPriority;
FunctionalState NVIC_IRQChannelCmd;
}
NVIC_InitTypeDef;
NVIC_IRQChannel,定义初始化的是哪个中断,例如 USART1_IRQn
NVIC_IRQChannelPreemptionPriority,定义这个中断的抢占优先级别,级别数不超过2的“抢占优先级位数”次方。(一个是位数,一个是级别数)
NVIC_IRQChannelSubPriority,定义这个中断的响应优先级别,级别数不超过2的“响应优先级位数”次方。
NVIC_IRQChannelCmd,该中断是否使能
IRQ全称为Interrupt Request,即是“中断请求”的意思
中断初始化配置示例:
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
//串口 1 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;
// 抢占优先级为 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
// 响应优先级为 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//IRQ 通道使能
NVIC_Init(&NVIC_InitStructure);
//根据上面指定的参数初始化 NVIC 寄存器
通常如果写外部中断时,此代码块放在 exti.cEXTI_Init() 函数内部,每个端口配置结束都需要一个NVIC_Init(&NVIC_InitStructure);
小结
中断优先级设置的步骤:
系统运行开始的时候设置中断分组。确定组号,也就是确定抢占优先级和子优先级的分配位数。调用函数为 NVIC_PriorityGroupConfig();
设置所用到的中断的中断优先级别,对每个中断调用函数为 NVIC_Init();
STM32 外部中断
基础知识
STM32 外部 IO 口的中断功能
文件: stm32f10x_exti.c/h
每个 IO 口都可以作为外部中断的中断输入口,支持19个外部中断/事件请求,每个中断设有状态位、独立的触发/屏蔽设置。
19个外部中断为:
线 0-15:对应外部 IO 口的输入中断 (供 IO 口使用的中断线)
线 16 :连接到PVD输出(Programmable Votage Detector,可编程电压监测器)
线 17 :连接到RTC闹钟事件
线 18 :连接到USB唤醒事件
映射方式:
每个中断线对应最多7个IO口,但每次只能连接到一个IO口上,利用选择器的配置来决定中断线配置到哪个IO口上去。
库函数配置
1. 映射关系配置 GPIO_EXTILineConfig()
外部中断端口映射配置示例 (GPIOE_2 与 EXTI_2):
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
2. 中断初始化 EXTI_Init()
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
//结构体函数参数
查看一下结构体:
typedef struct
{
uint32_t EXTI_Line;
EXTIMode_TypeDef EXTI_Mode;
EXTITrigger_TypeDef EXTI_Trigger;
FunctionalState EXTI_LineCmd;
}EXTI_InitTypeDef;
有4个需要设置的参数:
中断线标号,EXTI_Line0~EXTI_Line15
中断模式,中断 EXTI_Mode_Interrupt 和事件 EXTI_Mode_Event
触发方式,下降沿触发 EXTI_Trigger_Falling,上升沿触发 EXTI_Trigger_Rising,任意电平(上升沿和下降沿)触发EXTI_Trigger_Rising_Falling
使能,ENABLE
中断和事件的区别
简而言之,中断是需要经过芯片内部程序处理,然后跳转的中断程序
事件是检测到某一动作(电平边沿)触发事件发生了,进而由提前设置好的相应的联动硬件自动完成产生的结果
中断是红线
事件是绿线
外部中断初始化配置示例:
EXTI_InitTypeDef EXTI_InitStructure;
//定义结构体
EXTI_InitStructure.EXTI_Line=EXTI_Line4;
//中断线4
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
//中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
//下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
//使能
EXTI_Init(&EXTI_InitStructure);
//根据 EXTI_InitStruct 中指定的参数初始化外设 EXTI 寄存器
3. 设置中断线2的中断优先级
优先级配置见第一部分NVIC的配置
NVIC_InitTypeDef NVIC_InitStructure;
//定义NVIC结构体
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
//使能按键外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
//抢占优先级 2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
//响应优先级 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
//中断优先级分组初始化
4. 中断服务函数
STM32一共15个IO口外部中断线,共有6个中断函数:
EXPORT EXTI0_IRQHandler
EXPORT EXTI1_IRQHandler
EXPORT EXTI2_IRQHandler
EXPORT EXTI3_IRQHandler
EXPORT EXTI4_IRQHandler
EXPORT EXTI9_5_IRQHandler
EXPORT EXTI15_10_IRQHandler
0-4每个中断线对应一个中断函数,5-9共用EXTI9_5_IRQHandler,10-15共用EXTI15_10_IRQHandler
当多线共用一个处理函数的时候,就必须写EXTI_GetITStatus()判断到底是哪一线中断请求
1. ITStatus EXTI_GetITStatus();
用在中断服务函数的开头,判断中断是否发生
EXTI_GetFlagStatus()与之的区别
EXTI_GetITStatus() 函数中会先判断这种中断是否使能,使能了才去判断中断标志位
而EXTI_GetFlagStatus() 直接用来判断状态标志位
2. EXTI_ClearITPendingBit(EXTI_Line0);
中断服务函数结束之前调用,清除某中断线上的中断标志位
EXTI_ClearFlag(),与之功能相同
常用的中断服务函数格式:
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2)!=RESET)
//判断某个线上的中断是否发生
{
中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line2);
//清除 LINE 上的中断标志位
}
}
外部中断配置示例
1. exit.c
包含4个函数:
EXTI_Init()
外部中断初始化,(以按键功能为例):
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//调用结构体
调用 KEY_Init 函数,来初始化外部中断输入的 IO 口。
KEY_Init();//初始化按键对应 io 模式
2.调用RCC_APB2PeriphClockCmd()函数来使能复用功能时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//外部中断,需要使能 AFIO 时钟
4.接着配置中断线和 GPIO 的映射关系。
//GPIOC.5 与中断线5映射
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
5.然后初始化中断线。
EXTI_InitStructure.EXTI_Line=EXTI_Line5;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
6.中断初始化、配置优先级
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI0_IRQHandler()
中断处理函数
void EXTI0_IRQHandler(void)
{
delay_ms(10);
if(WK_UP==1)//WK_UP在key.h文件中定义
{
LED0=!LED0;//LED0在led.h文件中定义
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line0);
//清除EXTI0线路挂起位
}
EXTI9_5_IRQHandler()
EXTI15_10_IRQHandler()
小结
使用 IO 口外部中断的一般步骤:
初始化 IO 口为输入。
开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。
初始化线上中断(EXTI),设置触发条件等。
配置中断分组(NVIC),并使能中断。
编写中断服务函数。
NVIC 中断优先级管理
Nested Vectored Interrupt Controller,嵌套向量中断控制器。
CM3支持256个中断,16个内核中断,240个外部中断,256级可编程中断设置。
STM32使用了其中一部分,16个内核中断,107系列有68个可屏蔽中断(103系列只有60个),16级可编程的中断优先级。
中断寄存器
ISER[8],Interrupt Set-Enable Registers,中断使能寄存器组,用8个32位寄存器控制(256个可编程中断),每个位控制一个中断。由于STM32f103只有60个可屏蔽中断,于是只用了 ISER[0] 和 ISER[1] 64个中断中的前60位。
ISER[0] 的 bit0 至 bit31 对应中断0至31,ISER[1] 的 bit0 至 bit27 对应中断32至59,使能某个中断就将对应的 ISER 置1
ICER[8],Interrupt Clear-Enable Register,中断除能寄存器组。中断对应与ISER相同,但作用是置1清除中断使能
ISPR[8],Interrupt Set-Pending Register,中断挂起控制寄存器组。置1将正在进行的中断挂起,暂停等待执行,执行同级或更高级别的中断
ICPR[8],Interrupt Clear-Pending Register,中断解挂控制寄存器组,置1将挂起的中断解挂
IABR[8],Interrupt Active Bit Register,中断激活标志位寄存器组,只读寄存器,为1表示该位对应的中断正在被执行
IP[240],Interrupt Priority Registers,中断优先级控制寄存器组,相当重要! STM32的中断分组与其密切相关。
IP[240]有240个8bit寄存器组成,每个可屏蔽中断占用8bit,总共可表示240个可屏蔽中断,STM32f1使用其中60个,IP[59]至IP[0]分别对应中断59至0。每个可屏蔽中断只用高4位,分为抢占优先级和响应优先级,抢占优先级在前、响应优先级在后,各占几位由SCB-》AIRCR中的中断分组设置。采用库函数==NVIC_PriorityGroupConfig () ==配置。
如果组设置为3,则每个中断的中断优先寄存器高4位中前3位是抢占优先级,优先级级别0-7;低1位是响应优先级,优先级级别0-1。
STM32的中断向量有抢占属性和响应属性,属性编号越小,优先级别越高。
抢占属性是打断其他中断的属性,有这个属性就有嵌套中断。由库函数NVIC_IRQChannelPreemptionPriority() 进行参数配置。
响应属性应用在抢占属性相同时(前提),两个中断向量的抢占优先级相同时,如果同时到达,则优先处理响应优先级高的中断。由库函数NVIC_IRQChannelSubPriority() 进行参数配置。
库函数配置
NVIC 中断管理函数声明在 misc.c 文件里
1. 中断优先级分组函数 NVIC_PriorityGroupConfig()
此函数在系统工程中只能被调用一次!一旦确定好中断分组就不能更改!
目前了解到的在主函数中调用该函数
按 F12 查看函数定义块:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
SCB-》AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}
可以看到,这个函数通过设置 SCB-》AIRCR 寄存器设置中断分组。
补充:
assert_param(),断言机制函数,在stm32f10x_conf.h文件中可以看到 assert_param() 是一个宏定义,作用就是检测传递给函数的参数是否是有效的参数,返回值是 0假 1真。
中断优先组配置示例:分组值为2,2优先2抢占:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 暂时看到的此函数调用都是在主函数里,以后看到其他程序结构再补充:
2. 中断初始化函数 NVIC_Init
函数定义:
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) 查看结构体 NVIC_InitTypeDef 的成员变量:
typedef struct
{
uint8_t NVIC_IRQChannel;
uint8_t NVIC_IRQChannelPreemptionPriority;
uint8_t NVIC_IRQChannelSubPriority;
FunctionalState NVIC_IRQChannelCmd;
}
NVIC_InitTypeDef;
NVIC_IRQChannel,定义初始化的是哪个中断,例如 USART1_IRQn
NVIC_IRQChannelPreemptionPriority,定义这个中断的抢占优先级别,级别数不超过2的“抢占优先级位数”次方。(一个是位数,一个是级别数)
NVIC_IRQChannelSubPriority,定义这个中断的响应优先级别,级别数不超过2的“响应优先级位数”次方。
NVIC_IRQChannelCmd,该中断是否使能
IRQ全称为Interrupt Request,即是“中断请求”的意思
中断初始化配置示例:
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
//串口 1 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;
// 抢占优先级为 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
// 响应优先级为 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//IRQ 通道使能
NVIC_Init(&NVIC_InitStructure);
//根据上面指定的参数初始化 NVIC 寄存器
通常如果写外部中断时,此代码块放在 exti.cEXTI_Init() 函数内部,每个端口配置结束都需要一个NVIC_Init(&NVIC_InitStructure);
小结
中断优先级设置的步骤:
系统运行开始的时候设置中断分组。确定组号,也就是确定抢占优先级和子优先级的分配位数。调用函数为 NVIC_PriorityGroupConfig();
设置所用到的中断的中断优先级别,对每个中断调用函数为 NVIC_Init();
STM32 外部中断
基础知识
STM32 外部 IO 口的中断功能
文件: stm32f10x_exti.c/h
每个 IO 口都可以作为外部中断的中断输入口,支持19个外部中断/事件请求,每个中断设有状态位、独立的触发/屏蔽设置。
19个外部中断为:
线 0-15:对应外部 IO 口的输入中断 (供 IO 口使用的中断线)
线 16 :连接到PVD输出(Programmable Votage Detector,可编程电压监测器)
线 17 :连接到RTC闹钟事件
线 18 :连接到USB唤醒事件
映射方式:
每个中断线对应最多7个IO口,但每次只能连接到一个IO口上,利用选择器的配置来决定中断线配置到哪个IO口上去。
库函数配置
1. 映射关系配置 GPIO_EXTILineConfig()
外部中断端口映射配置示例 (GPIOE_2 与 EXTI_2):
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
2. 中断初始化 EXTI_Init()
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
//结构体函数参数
查看一下结构体:
typedef struct
{
uint32_t EXTI_Line;
EXTIMode_TypeDef EXTI_Mode;
EXTITrigger_TypeDef EXTI_Trigger;
FunctionalState EXTI_LineCmd;
}EXTI_InitTypeDef;
有4个需要设置的参数:
中断线标号,EXTI_Line0~EXTI_Line15
中断模式,中断 EXTI_Mode_Interrupt 和事件 EXTI_Mode_Event
触发方式,下降沿触发 EXTI_Trigger_Falling,上升沿触发 EXTI_Trigger_Rising,任意电平(上升沿和下降沿)触发EXTI_Trigger_Rising_Falling
使能,ENABLE
中断和事件的区别
简而言之,中断是需要经过芯片内部程序处理,然后跳转的中断程序
事件是检测到某一动作(电平边沿)触发事件发生了,进而由提前设置好的相应的联动硬件自动完成产生的结果
中断是红线
事件是绿线
外部中断初始化配置示例:
EXTI_InitTypeDef EXTI_InitStructure;
//定义结构体
EXTI_InitStructure.EXTI_Line=EXTI_Line4;
//中断线4
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
//中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
//下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
//使能
EXTI_Init(&EXTI_InitStructure);
//根据 EXTI_InitStruct 中指定的参数初始化外设 EXTI 寄存器
3. 设置中断线2的中断优先级
优先级配置见第一部分NVIC的配置
NVIC_InitTypeDef NVIC_InitStructure;
//定义NVIC结构体
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
//使能按键外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
//抢占优先级 2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
//响应优先级 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
//中断优先级分组初始化
4. 中断服务函数
STM32一共15个IO口外部中断线,共有6个中断函数:
EXPORT EXTI0_IRQHandler
EXPORT EXTI1_IRQHandler
EXPORT EXTI2_IRQHandler
EXPORT EXTI3_IRQHandler
EXPORT EXTI4_IRQHandler
EXPORT EXTI9_5_IRQHandler
EXPORT EXTI15_10_IRQHandler
0-4每个中断线对应一个中断函数,5-9共用EXTI9_5_IRQHandler,10-15共用EXTI15_10_IRQHandler
当多线共用一个处理函数的时候,就必须写EXTI_GetITStatus()判断到底是哪一线中断请求
1. ITStatus EXTI_GetITStatus();
用在中断服务函数的开头,判断中断是否发生
EXTI_GetFlagStatus()与之的区别
EXTI_GetITStatus() 函数中会先判断这种中断是否使能,使能了才去判断中断标志位
而EXTI_GetFlagStatus() 直接用来判断状态标志位
2. EXTI_ClearITPendingBit(EXTI_Line0);
中断服务函数结束之前调用,清除某中断线上的中断标志位
EXTI_ClearFlag(),与之功能相同
常用的中断服务函数格式:
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2)!=RESET)
//判断某个线上的中断是否发生
{
中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line2);
//清除 LINE 上的中断标志位
}
}
外部中断配置示例
1. exit.c
包含4个函数:
EXTI_Init()
外部中断初始化,(以按键功能为例):
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//调用结构体
调用 KEY_Init 函数,来初始化外部中断输入的 IO 口。
KEY_Init();//初始化按键对应 io 模式
2.调用RCC_APB2PeriphClockCmd()函数来使能复用功能时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//外部中断,需要使能 AFIO 时钟
4.接着配置中断线和 GPIO 的映射关系。
//GPIOC.5 与中断线5映射
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
5.然后初始化中断线。
EXTI_InitStructure.EXTI_Line=EXTI_Line5;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
6.中断初始化、配置优先级
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI0_IRQHandler()
中断处理函数
void EXTI0_IRQHandler(void)
{
delay_ms(10);
if(WK_UP==1)//WK_UP在key.h文件中定义
{
LED0=!LED0;//LED0在led.h文件中定义
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line0);
//清除EXTI0线路挂起位
}
EXTI9_5_IRQHandler()
EXTI15_10_IRQHandler()
小结
使用 IO 口外部中断的一般步骤:
初始化 IO 口为输入。
开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。
初始化线上中断(EXTI),设置触发条件等。
配置中断分组(NVIC),并使能中断。
编写中断服务函数。
举报