STM32-中断,中断实验
NVIC
NVIC(Nested vectored interrupt controller)嵌套向量中断控制器。属于内核。NVIC支持外部中断和内部中断(内核中断)。无论是外部中断和内部中断都有对应的中断服务函数函数,
什么是中断服务函数?它是我们中断的入口,当我们的中断发生后需要执行相应的中断程序,中断程序的入口由中断服务函数提供。中断服务函数被定义在中断向量表里面。
什么是中断向量表?
它存放着中断服务函数的首地址。由四字节对齐。由地址找到我们对应的中断服务函数。中断向量表定义在启动文件中.s文件,当发生中断时,CPU会自动执行对应的中断服务函数。
STM32中断优先级基本概念
1,抢占优先级(pre):高抢占优先级可以打断正在执行的低抢占优先级中断
2,响应优先级(sub):当抢占优先级相同时,响应优先级高的先执行,但是不能互相打断
3,抢占和响应都相同的情况下,自然优先级越高的,先执行
4,自然优先级:中断向量表的优先级
5,数值越小,表示优先级越高
NVIC寄存器介绍
IPR是设置外部中断优先级的寄存器。SHPR是设置内核中断的寄存器。
中断优先级分组
NVIC使用
1,设置中断分组:AIRCR[10:8],HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2)//两位抢占优先级,两位响应优先级
2,设置中断优先级:IPRx bit[7:4],
HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority);
例如:
HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);
3,使能中断: ISERx,HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
HAL_NVIC_EnableIRQ(USART1_IRQn);
IRQn_Type是枚举类型,数值表示在中断向量表中的位置。该枚举定义在stm32f103xe.h中
以上三个函数都在stn32f1xx_hal_cortex.c中,stn32f1xx_hal_cortex.c是对core_cm3.h里面的函数进行再一次的封装。
EXTI
exti:External(Extended) interrupt/event Controller,外部(扩展)中断事件控制器。包含20个产生事件/中断请求的边沿检测器,即总共:20条EXTI线(F1)
中断与事件
什么是中断?:要进入NVIC,有相应的中断服务函数,需要CPU处理
什么是事件?:不进入NVIC,仅用于内部硬件自动控制的,如:TIM、DMA、ADC
EXTI工作原理
- 边沿检测
- 软件触发
- 中断屏蔽/清除
- 事件屏蔽
这里请求挂起寄存器EXTI_PR还不太了解。
AFIO
alternate Function IO,即复用功能IO,
EXTI与IO对应关系
AFIO_EXTICR1的 EXTI0[3:0]位控制(F1)
SYSCFG_EXTICR1的 EXTI0[3:0]位控制(F4/F7/H7)
Px0映射到EXTI0
Px1映射到EXTI1
…
Px14映射到EXTI14
Px15映射到EXTI15
中断发生过程
EXTI的配置步骤
HAL库中断回调处理机制介绍(掌握)
中断实验
exti.c GPIO端口触发中断。
void exti_init(void)
{
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_GPIOE_CLK_ENABLE();
gpio_init_struct.Pin = GPIO_PIN_4;
gpio_init_struct.Mode = GPIO_MODE_IT_FALLING; //中断上升沿触发模式
gpio_init_struct.Pull = GPIO_PULLUP; //输入上拉模式。
HAL_GPIO_Init(GPIOE, &gpio_init_struct);
HAL_NVIC_SetPriority(EXTI4_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
}
//中断服务函数,中断向量表中存储的函数,我们可以重写这个函数
void EXTI4_IRQHandler(void)
{
//HAL库中断处理公用函数
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);//
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_4);
}
//HAL库数据处理回调函数,在HAL_GPIO_EXTI_IRQHandler()函数中调用。
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
delay_ms(20);
if(GPIO_Pin == GPIO_PIN_4)
{
if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4)==0)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
}
}
}