STM32外部中断原理及应用

对于嵌入式系统开发者而言,STM32系列微控制器是一个强大而灵活的选择,而外部中断作为其中一项重要的功能,为实时响应外部事件提供了关键支持。本文将带领初学者深入理解STM32外部中断的原理和应用,让你能够轻松地在你的项目中使用它。

1. 理解外部中断的原理

外部中断是一种特殊的中断类型,它允许外部信号触发微控制器的中断。在STM32中,外部中断通常用于实现来自外部设备(例如按钮、传感器等)的事件响应。其原理是基于GPIO的状态变化,当GPIO引脚上的电平发生变化(例如从高电平变为低电平或从低电平变为高电平),外部中断将被触发。

2. STM32外部中断的应用场景

  • 按钮/开关控制: 当用户按下按钮或切换开关时,可以触发外部中断来响应用户的操作,例如控制LED的亮灭或执行特定功能。
  • 传感器触发: 当传感器检测到特定事件或条件发生时,可以触发外部中断来及时处理传感器数据,例如温度传感器、光敏传感器等。
  • 通信接口中断: 在串口通信或外部设备接口中,外部中断可以用于处理接收到的数据或监测通信状态的变化,例如UART、SPI、I2C等。

3. 如何在STM32中配置外部中断

在STM32中配置外部中断通常包括以下几个步骤:

  1. GPIO配置: 将外部中断对应的GPIO引脚配置为输入模式,并设置上拉或下拉电阻,以确保稳定的电平。
  2. 外部中断线配置: 配置外部中断线,将GPIO引脚与外部中断线关联起来,并设置触发方式(上升沿触发、下降沿触发等)。
  3. 中断优先级配置: 设置外部中断的抢占优先级和子优先级,以确保及时响应重要的外部事件。
  4. 编写中断服务程序: 编写外部中断的中断服务程序,处理外部中断事件,例如执行特定的功能或任务切换。

4.示例代码演示

以下是一个简单的示例代码,演示了如何在STM32中配置外部中断并实现LED的控制:

#include "stm32f4xx.h"

/* 外部中断服务程序 */
void EXTI0_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line0) != RESET) // 判断是否是PA0引脚的中断
    {
        GPIO_ToggleBits(GPIOA, GPIO_Pin_5); // 翻转PA5引脚的状态(LED)
        EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志位
    }
}

/* GPIO初始化函数 */
void GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    /* GPIO时钟使能 */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    /* 配置PA5引脚为输出 */
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* 配置PA0引脚为输入并使能外部中断 */
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* 外部中断线0配置 */
    EXTI_InitTypeDef EXTI_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;

    /* 配置外部中断线0对应的GPIO引脚 */
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

    /* 配置外部中断线0 */
    EXTI_InitStruct.EXTI_Line = EXTI_Line0;
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发中断
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStruct);

    /* 中断优先级设置 */
    NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00; // 抢占优先级为0
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00; // 子优先级为0
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);
}

int main(void)
{
    /* MCU初始化 */
    SystemInit();

    /* 初始化所有的GPIO引脚 */
    GPIO_Init();

    /* 死循环,等待外部中断触发 */
    while (1)
    {
    }
}

5.特别注意事项

下图为STM32的中断配置表

STM32外部中断原理及应用_第1张图片

这里要注意gpio9-gpio5,gpio15-gpio10是公用一根中断线,如果同时用到其中二个GPIO触发中断,需要在中断例程中判断,下面代码就是同时用到GPIO13和GPIO10的例子。


void EXTI15_10_IRQHandler(void)   
{
   ITStatus EXTI10_Status;
   ITStatus EXTI13_Status;
   EXTI10_Status = EXTI_GetITStatus(EXTI_Line10);    //获得外部中断10的状态
   EXTI13_Status = EXTI_GetITStatus(EXTI_Line13);     //获得外部中断13的状态
  if(EXTI10_Status == SET) 
  { 
    led_light_up(1); 
  } 
  if(EXTI13_Status == SET) 
  { 
    led_light_up(2); 
  }
  EXTI_ClearFlag(EXTI_Line10 | EXTI_Line13); /*清除外部中断10或者13的挂起位 */ 
}

还需要注意,下图每组的GIPOX都公用一根线,所有系统中GPIOX只能配置一个为中断源,比如配置了PA0,其他PB0到PF0就不能配置,因为PA0到PG0都公用一根中断线,PA1,PA2。。。。都是一样原理。

STM32外部中断原理及应用_第2张图片

你可能感兴趣的:(STM32,stm32,嵌入式硬件,单片机,STM32中断原理,外部中断)