前言
本文主要介绍与外部中断相关的内容。
本文主要参考文献为:
- ST.STM32 Cortex®-M4 MCUs and MPUs programming manual
- ST.RM0090 Reference manual
- 刘火良.STM32库开发实战指南——基于STM32F4.机械工业出版社
- 正点原子.STM32F429开发指南-HAL库版本_V1.1
- Joesph Yiu.ARM cortex-M3与cortex-M4权威指南(第三版).清华大学出版社
中断
本文不会特意区分中断和异常的概念。Conrtex-M处理器都提供嵌套向量中断控制器 (NVIC),顾名思义,在F429中,中断是支持嵌套的。关于中断相关的内容,可以学习的内容有很多,具体内容可以参考<ARM cortex-M3与cortex-M4权威指南(第三版)>。本文不再仅从实用的角度介绍在F429中中断的使用,以及中断中最重要的概念——优先级。
使用
在F429中,中断的配置比较简单。主要分成以下几个步骤:
一、 配置中断优先级组
/**
* @brief Sets the priority grouping field (preemption priority and subpriority)
* using the required unlock sequence.
* @param PriorityGroup: The priority grouping bits length.
* This parameter can be one of the following values:
* @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
* 4 bits for subpriority
* @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
* 3 bits for subpriority
* @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
* 2 bits for subpriority
* @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
* 1 bits for subpriority
* @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
* 0 bits for subpriority
* @note When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible.
* The pending IRQ priority will be managed only by the subpriority.
* @retval None
*/
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
/* Check the parameters */
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
/* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
NVIC_SetPriorityGrouping(PriorityGroup);
}
此函数在文件<stm32f4xx_hal_cortex.c>中,会被HAL_Init()
函数调用。
二、配置中断优先级
/**
* @brief Sets the priority of an interrupt.
* @param IRQn: External interrupt number.
* This parameter can be an enumerator of IRQn_Type enumeration
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
* @param PreemptPriority: The preemption priority for the IRQn channel.
* This parameter can be a value between 0 and 15
* A lower priority value indicates a higher priority
* @param SubPriority: the subpriority level for the IRQ channel.
* This parameter can be a value between 0 and 15
* A lower priority value indicates a higher priority.
* @retval None
*/
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
{
uint32_t prioritygroup = 0x00;
/* Check the parameters */
assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
prioritygroup = NVIC_GetPriorityGrouping();
NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
}
该函数在<stm32f4xx_hal_cortex.c>中定义,用于设置中断优先级。
三、使能中断
/**
* @brief Enables a device specific interrupt in the NVIC interrupt controller.
* @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
* function should be called before.
* @param IRQn External interrupt number.
* This parameter can be an enumerator of IRQn_Type enumeration
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h))
* @retval None
*/
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
/* Enable interrupt */
NVIC_EnableIRQ(IRQn);
}
该函数在<stm32f4xx_hal_cortex.c>中定义,用于使能中断。
四、配置中断源。
该功能与具体产生中断的外设相关,需要具体分析。
优先级
在中断配置中,最重要的就是配置优先级。所谓优先级,就是当同时触发多个中断需要响应的时候,响应的顺序是按照优先级来排列的。在F429中,支持中断嵌套,即更高优先级的中断(优先级编号更小)可以抢断低优先级(优先级编号更高)的中断。
在F429中,优先级通过4位寄存器来表现,如下图所示:
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
用途 | 用于表达优先级 | 未用,返回0 |
用于表达优先级的4位,还会被分为抢占优先级和子优先级。其中,抢断优先级又被成为主优先级或者分组优先级。而该分组的方式通过HAL_NVIC_SetPriorityGrouping()
函数实现。
优先级参数 | 主优先级位数(bit) | 子优先级位数(bit) |
---|---|---|
NVIC_PRIORITYGROUP_0 | 0 | 4 |
NVIC_PRIORITYGROUP_1 | 1 | 3 |
NVIC_PRIORITYGROUP_2 | 2 | 2 |
NVIC_PRIORITYGROUP_3 | 3 | 1 |
NVIC_PRIORITYGROUP_4 | 4 | 0 |
设定中断优先级分组和中断优先级后,中断响应顺序如下:
- 处理器已经在运行一个中断处理时,是否能被另一个中断抢断,这是有主优先级确定的。
- 子优先级只有在两个相同主优先级中断同时等待响应时,数值更小的子优先级先响应。
- 若两个优先级完全相同的中断在等待响应时,则中断编号更小的的中断响应优先级更高。
中断编号可以在编程参考手册< RM0090 Reference manual >查询。
外部中断
如上图所示,若想产生中断:
- 配置好外部中断接口,使能中断。
- 配置两个边缘触发器,以产生中断请求。
- 除了硬件产生中断信号之外,还可以通过配置软件中断事件寄存器(EXTI_SWIER)来产生外部中断信号。
- 在中断屏蔽寄存器的响应位(EXTI_IMR)写1,使能中断请求。
- 当产生中断请求时,挂起寄存器(EXTI_PR)会被置“1”。在挂起寄存器对应位写“1”,可以清除该中断请求。
- 事件与中断产生基本一致,在第3步之后,需要注意事件屏蔽寄存器(EXTI_EMR)设置正确。
事件与中断不同在于:中断最终的响应为中断服务函数,是一个软件级的响应。事件的响应位产生一个脉冲,给其他外设使用,是属于硬件级别。
外部中断的映射为: