时间:2017/06/02 10:01
G15电装.王维鋆
一.优先级梳理
F429将优先级分为5个组,是由内核外设 SCB 的应用程序中断及复位控制寄存器 AIRCR 的
PRIGROUP[10:8]位决定的,主优先级即强占优先级,子优先级即响应优先级.
关于什么是抢占优先级和子优先级这里就不介绍了 函数已经封装好,我们只需了解优先级的取值范围,调用NVIC函数时不超过范围就ok,我们一般使用时,都配置为中断分组2,因为这时抢占子优先级范围都是0-3。设置方便,使用简单。
二. 抢占优先级
VS 子优先级
1.高优先级的抢占优先级是可以打断正在进行的低抢占优先级的(数字越小,优先级高)
2.抢占优先级相同的中断,高子优先级不可以打断低子优先级的中断.
3.抢占优先级相同的中断情况下,当两个中断同时发生时,那个子优先级高,谁就先执行
4.如果两个中断的抢占优先级与子优先级都一样,则谁先发生就先执行.
三. NVIC中断优先级设置步骤:
1.系统运行后先设置中断优先级分组,调用函数
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);整个系统中,只执行一次中断分组.
2.针对不同的中断源,设置对应的抢占优先级和子优先级,即初始化NVIC结构体.
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
3.如果需要挂起/解挂,查看中断当前状态等,调用相关函数即可.
四. EXTI外部中断
STM32F4的每个IO都可以作为外部中断的中断输入口,这点也是STM32F4的强大之处
STM32F429的中断控制器支持23个外部中断/事件线。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F407的23个外部中断
EXTI线0~15:对应外部IO口的输入中断。
EXTI线16:连接到PVD输出。
EXTI线17:连接到RTC闹钟事件。
EXTI线18:连接到USB OTG FS唤醒事件。
EXTI线19:连接到以太网唤醒事件。
EXTI线20:连接到USB OTG HS(在FS中配置)唤醒事件。
EXTI线21:连接到RTC入侵和时间戳事件。
EXTI线22:连接到RTC唤醒事件。
STM32F4是怎么把16个中断线和IO口一一对应联系起来的纳?
这里STM32F4就这样设计的:
GPIO的管脚GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G,H,I)分别对应中断线0~15。这样每个中断线对应了最多9个IO口,以挑战者PDF里面的线0映射关系图为例:
它对应了GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0,GPIOH.0,GPIOI.0。而中断线每次只能连接到1个IO口上,这样就需要通过配置来决定对应的中断线配置到哪个GPIO上.
至于EXTI初始化结构体函数成员这块我就不介绍了,很简单.理解了初始化结构体每个成员意义基本上就可以对该外设运用自如. stm32f4xx_exti.c 文件和.h文件多去梳理看看。
五.外部中断配置步骤:
1.初始化IO口为输入,使能IO口时钟(可以设置为上拉\下拉输入,具体看你硬件).
2.开启IO口复用时钟,设置IO口与中断线的映射关系.
这里必须用SYSCFG时钟(因为F4的外部中断复用功能必须使能SYSCFG时钟).
然后就设置IO口与中断线的映射关系:void SYSCFG_EXTILineConfig(uint8_t
EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex); 配置这个函数即可。
3.初始化线上的中断,即EXTI_InitTypeDef的成员初始化.设置触发条件
(可以设置成上升沿\下降沿触发,但不能设置为高电平\低电平触发)
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); //这里就不再介绍结构体初始化的过程了.
EXTI_InitTypeDef的成员变量:
typedef struct
{ uint32_t EXTI_Line; //中断线的标号,EXTI_Line0~EXTI_Line15
EXTIMode_TypeDef EXTI_Mode; //
中断模式选择
EXTITrigger_TypeDef EXTI_Trigger; //触发方式,上升沿\下降沿 任意电平
FunctionalState EXTI_LineCmd; //使能中断线
}EXTI_InitTypeDef;
4.配置NVIC中断分组,且使能中断
对NVIC中断优先级的设置步骤,上面有讲到。这里就不在重复了.
(对于STM32中断而言,只有配置了NVIC的设置,并开启了才能执行,否则是不会执行到中断服务函数里面去的.)
5.编写中断服务函数
位于stm32f4xx_it.c中,这里需要注意中断服务函数的函数名必须跟启动文件里面预先设置的一样,如果有异,系统是找不到中断服务函数的入口的
7个IO口外部中断函数名别弄错了:
EXPORT EXTI0_IRQHandler
EXPORT EXTI1_IRQHandler
EXPORT EXTI2_IRQHandler
EXPORT EXTI3_IRQHandler
EXPORT EXTI4_IRQHandler
EXPORT EXTI9_5_IRQHandler
EXPORT EXTI15_10_IRQHandler
中断线5-9共用中断函数EXTI9_5_IRQHandler,中断线10-15共用中断函数EXTI15_10_IRQHandler,中断线0到4就每个对应一个中断函数.
另外中断服务函数会常用的几个函数:
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);//中断线上标志位是否置位
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);//清除中断线中断标志位
/以下两个函数和上面的两个函数作用类似,但也有点不同
调用①函数会先判断这种中断是否使能,使能了才去判断中断标志位
而上面的EXTI_GetITStatus是直接用来判断标志位.
调用②也是同理可得.
*/
① EXTI_GetFlagStatus(uint32_t EXTI_Line);
② EXTI_ClearFlag(uint32_t EXTI_Line);