STM32:外部中断

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

一、外部中断示例

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

STM32:外部中断_第1张图片

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

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

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

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

STM32:外部中断_第2张图片

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

...
 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为"中断"英文缩写)

......
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 */
}
......

编译,生成结果。   

二、外部中断原理

STM32:外部中断_第3张图片

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

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

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

STM32:外部中断_第4张图片

        在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...

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

STM32:外部中断_第5张图片

例如在上述示例中,我们把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。

STM32:外部中断_第6张图片

 在中断函数中,有系统自动生成的代码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位确定为响应优先级(子优先级)。

STM32:外部中断_第7张图片

你可能感兴趣的:(嵌入式开发,stm32,嵌入式硬件,单片机)