STM32:外部中断

中断,顾名思义就是停止现在正在干的活,去干其他更紧急的事情。在通常的信息系统中,中断发生时,会先保留现场,即当前的运行情况和状态。在去做其他紧急事情。事情做完还要恢复原先中断前的状态继续干原来的活。在STM32中,例如指令出错,定时器结束,串口接收到数据,GPIO电平变化等都会产生中断。

一、外部中断示例

注:使用STM32F103CT6芯片,KEYSKING教程的开发板套件。开发板接口图如下

(1)示例:红灯正常闪烁,按下KEY1按钮,翻转绿灯亮灭。

在芯片设置界面中设置PA7,PB0口为GPIO_OUTPUT标签命名分别为greenLED,redLED.把PB12口设置为GPIO_EXIT12,命名为key1.

在属性设置面板中,System Core ->GPIO->PB12 进行详细设置,GPIO MODE 设置为下降沿(Falling Edge)触发.

而后属性设置面板中,点击中断向量控制NVIC 设置中断优先级,如图

关键代码如下:在main.c中编写红灯闪烁代码

cpp 复制代码
...
 MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
  int status =0 ;
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  status++ ;
	  status%=5;
	  if(status < 1){
	    HAL_GPIO_WritePin(redLED_GPIO_Port, redLED_Pin, GPIO_PIN_RESET);
	  }else{
		HAL_GPIO_WritePin(redLED_GPIO_Port, redLED_Pin, GPIO_PIN_SET);
	  }
	  HAL_Delay(300);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
.....

在stm32f1xx_it.c 中编写中断处理函数。(注:it为"中断"英文缩写)

cpp 复制代码
......
void EXTI15_10_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI15_10_IRQn 0 */
  HAL_Delay(10);
  if(HAL_GPIO_ReadPin(key1_GPIO_Port,key1_Pin) == GPIO_PIN_RESET){
	  //反转pin位,即按下key翻转绿灯亮灭
	  HAL_GPIO_TogglePin(greenLED_GPIO_Port, greenLED_Pin);
  }
  /* USER CODE END EXTI15_10_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(key1_Pin);
  /* USER CODE BEGIN EXTI15_10_IRQn 1 */

  /* USER CODE END EXTI15_10_IRQn 1 */
}
......

编译,生成结果。

二、外部中断原理

上图是GPIO的输入驱动器模块,电流从I/O引脚进入,到达上拉/下拉电阻,而后到达施密特触发器,而后流入输入数据寄存器或者片上外设。

(1).中断/事件控制器

再接下来,电平信号便会进入外部中断/事件控制器的输入线中。其框图如下所示。

在STM32中,这样的控制器在STM32F1系列芯片中由19个。这19个外部中断控制器公用一套寄存器,但是各个部件的连线都是独立的。每个部件之间的连线都有19组,每个外部中断都对应着其中1组线路。该线路也称为外部中断线。

这19个外部中断线的前16组(EXIT0 ~ EXIT15)分别对应着编号相同的GPIO口。也就是说PA0/PB0/PC0/PD0对应着EXIT0,PA1/PB1/PC1/PD1对应着EXIT1一直到PA15/PB15/PC15/PD15对应着EXIT15...

边沿检测电路可以检测输入的电平信号是否发生高低电平转换。如果出现电平转换后续就会发出一个高电平信号。

例如在上述示例中,我们把key1对应的PB12设置成了下降沿触发中断。那么当按下按钮时,下降沿触发选择寄存器就会置成1。而后发出高电平信号。经过一个或门到达请求挂起寄存器。请求挂起寄存器收到高电平信号后把满线路编号对应的bit位置为1。并向后续发出高电平信号。 到达了与门。而中断屏蔽器对应的bit位是否发出高电平信号,取决于STM32的端口是否设置为GPIO_EXIT,是则到达嵌套向量中断控制器NVIC.

(2).嵌套向量中断控制器NVIC

NVIC会根据中断信号,选择对应的处理函数。中断向量前5号对应着各自的中断处理函数。而5号到9号公用同一个处理函数EXIT9_5_IRQHandler。10号到15号公用同一个处理函数EXIT15_10_IRQHandler。在上述示例中,PB12对应的中断向量为EXIT12,对应的处理函数则为EXIT15_10_IRQHandler。

在中断函数中,有系统自动生成的代码HAL_GPIO_EXTI_IRQHandler();进入到其实现中发现有__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);函数,该函数就是用来重置中断寄存器中的bit位。

(3).中断优先级

当中断发生时如何确定哪个中断先执行呢?例如上述示例中,中断函数中调用了HAL_DELAY函数。该函数也会触发一个时钟滴答(Tick Timer)中断,如果设置的时钟滴答优先级比中断函数处理优先级低。当代码执行到HAL_DELAY时,由于有比HAL_DELAY优先级高的中断处理函数未完成那么系统就会进入"死锁"状态。

当两中断同时发生时,先比较抢占优先级,如果一样则比较响应优先级。如果还一样则取决于在中断向量表中的顺序。

当一个中断正在处理,而另一个中断信号发生。那么就只比较抢占优先级。

在STM32为每个中断向量准备了4个二进制位来存储优先级信息。在Cube中可以根据优先级组下拉框设置哪几个bit位用来确定抢占优先级(主优先级),剩下的bit位确定为响应优先级(子优先级)。

相关推荐
沉在嵌入式的鱼2 小时前
linux串口对0X0D、0X0A等特殊字符的处理
linux·stm32·单片机·特殊字符·串口配置
学习路上_write2 小时前
AD5293驱动学习
c语言·单片机·嵌入式硬件·学习
影阴2 小时前
存储器和寄存器
stm32·单片机·嵌入式硬件
吃西瓜的年年3 小时前
3. C语言核心语法2
c语言·嵌入式硬件·改行学it
李洛克073 小时前
RDMA CM UDP 通信完整指南
单片机·网络协议·udp
思茂信息4 小时前
CST电动车EMC仿真——电机控制器MCU滤波仿真
javascript·单片机·嵌入式硬件·cst·电磁仿真
小曹要微笑4 小时前
I2C总线技术解析(纯文字版)
单片机·嵌入式硬件·esp32·iic
我送炭你添花4 小时前
可编程逻辑器件(PLD)的发展历程、原理、开发与应用详解
嵌入式硬件·fpga开发
袖手蹲4 小时前
Arduino UNO Q 从 Arduino Cloud 远程控制闪烁 LED
人工智能·单片机·嵌入式硬件·电脑
平凡灵感码头5 小时前
第一次做蓝牙产品,从零开发 嵌入式开发日志(2)AC63NSDK 完整合并版目录说明
stm32·单片机·嵌入式硬件