stm32f10x_exti

STM32F10x EXTI(External Interrupt/Event Controller)外部中断/事件控制器是STM32微控制器中用于处理外部中断和事件的重要外设。本文档详细介绍STM32F10x标准库中EXTI相关的函数、结构体和数据类型。

数据类型定义

枚举类型

EXTI_Mode_TypeDef - EXTI模式枚举

typedef enum
{
  EXTI_Mode_Interrupt = 0x00,  /* 中断模式 */
  EXTI_Mode_Event = 0x04       /* 事件模式 */
} EXTIMode_TypeDef;

说明:

  • EXTI_Mode_Interrupt:配置为中断模式,当检测到触发条件时会产生中断
  • EXTI_Mode_Event:配置为事件模式,当检测到触发条件时会产生事件(不产生中断)

EXTI_Trigger_TypeDef - EXTI触发方式枚举

typedef enum
{
  EXTI_Trigger_Rising = 0x08,        /* 上升沿触发 */
  EXTI_Trigger_Falling = 0x0C,       /* 下降沿触发 */
  EXTI_Trigger_Rising_Falling = 0x10 /* 上升沿和下降沿都触发 */
} EXTITrigger_TypeDef;

说明:

  • EXTI_Trigger_Rising:仅在信号上升沿触发
  • EXTI_Trigger_Falling:仅在信号下降沿触发
  • EXTI_Trigger_Rising_Falling:在信号上升沿和下降沿都触发

结构体类型

EXTI_InitTypeDef - EXTI初始化结构体

typedef struct
{
  uint32_t EXTI_Line;               /* EXTI线路选择 */
  EXTIMode_TypeDef EXTI_Mode;       /* EXTI模式选择 */
  EXTITrigger_TypeDef EXTI_Trigger; /* EXTI触发方式选择 */
  FunctionalState EXTI_LineCmd;     /* EXTI线路使能状态 */
} EXTI_InitTypeDef;

成员说明:

  • EXTI_Line:指定要配置的EXTI线路,可以是单个线路或多个线路的组合
  • EXTI_Mode:指定EXTI的工作模式(中断模式或事件模式)
  • EXTI_Trigger:指定触发信号的边沿类型
  • EXTI_LineCmd:指定EXTI线路的使能状态(ENABLE或DISABLE)

EXTI线路定义

STM32F10x支持20条EXTI线路(Line0-Line19),每条线路都有特定的功能:

#define EXTI_Line0       ((uint32_t)0x00001)  /* 外部中断线路0 */
#define EXTI_Line1       ((uint32_t)0x00002)  /* 外部中断线路1 */
#define EXTI_Line2       ((uint32_t)0x00004)  /* 外部中断线路2 */
#define EXTI_Line3       ((uint32_t)0x00008)  /* 外部中断线路3 */
#define EXTI_Line4       ((uint32_t)0x00010)  /* 外部中断线路4 */
#define EXTI_Line5       ((uint32_t)0x00020)  /* 外部中断线路5 */
#define EXTI_Line6       ((uint32_t)0x00040)  /* 外部中断线路6 */
#define EXTI_Line7       ((uint32_t)0x00080)  /* 外部中断线路7 */
#define EXTI_Line8       ((uint32_t)0x00100)  /* 外部中断线路8 */
#define EXTI_Line9       ((uint32_t)0x00200)  /* 外部中断线路9 */
#define EXTI_Line10      ((uint32_t)0x00400)  /* 外部中断线路10 */
#define EXTI_Line11      ((uint32_t)0x00800)  /* 外部中断线路11 */
#define EXTI_Line12      ((uint32_t)0x01000)  /* 外部中断线路12 */
#define EXTI_Line13      ((uint32_t)0x02000)  /* 外部中断线路13 */
#define EXTI_Line14      ((uint32_t)0x04000)  /* 外部中断线路14 */
#define EXTI_Line15      ((uint32_t)0x08000)  /* 外部中断线路15 */
#define EXTI_Line16      ((uint32_t)0x10000)  /* 连接到PVD输出 */
#define EXTI_Line17      ((uint32_t)0x20000)  /* 连接到RTC闹钟事件 */
#define EXTI_Line18      ((uint32_t)0x40000)  /* 连接到USB设备/OTG FS从挂起唤醒事件 */
#define EXTI_Line19      ((uint32_t)0x80000)  /* 连接到以太网唤醒事件 */

标准库函数详解

1. EXTI_DeInit

/**
 * @brief  将 EXTI 所有寄存器恢复为复位默认值,用于重新配置前清空旧状态
 * @param
 * @retval
 * @example
 *     EXTI_DeInit();
 */
void EXTI_DeInit(void);

功能说明:

  • 清除所有线路的触发、模式和中断挂起状态
  • 重新映射 GPIO 到 EXTI 前可先 DeInit

2. EXTI_Init

/**
 * @brief  初始化 EXTI 线路(模式、触发边沿、使能),配置外部信号如何产生中断/事件
 * @param  EXTI_InitStruct: 指向EXTI_InitTypeDef结构体的指针,包含EXTI的配置信息
 * @retval
 * @example
 *     EXTI_InitTypeDef EXTI_InitStructure;
 *     EXTI_InitStructure.EXTI_Line = EXTI_Line0;
 *     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
 *     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
 *     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
 *     EXTI_Init(&EXTI_InitStructure);
 */
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

功能说明:

  • 一次性配置线路、中断/事件模式、触发边沿
  • 需配合 GPIO_EXTILineConfig 和 NVIC 才能完整工作
  • 按键、传感器等外部信号检测的核心配置函数

3. EXTI_StructInit

/**
 * @brief  将 EXTI_InitTypeDef 成员填为安全默认值,避免未赋值字段导致随机配置
 * @param  EXTI_InitStruct: 指向EXTI_InitTypeDef结构体的指针,将被填充默认值
 * @retval
 * @example
 *     EXTI_InitTypeDef EXTI_InitStructure;
 *     EXTI_StructInit(&EXTI_InitStructure);
 */
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);

功能说明:

  • 默认 Line0、中断模式、上升沿、DISABLE
  • 填充后再按需修改个别成员即可

4. EXTI_GenerateSWInterrupt

/**
 * @brief  软件触发指定 EXTI 线路中断,无需外部引脚信号
 * @param  EXTI_Line: 指定要产生软件中断的EXTI线路
 * @retval
 * @example
 *     EXTI_GenerateSWInterrupt(EXTI_Line0);
 */
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);

功能说明:

  • 用于测试 ISR 或跨模块触发中断
  • 目标线路须已配置为中断模式并使能

5. EXTI_GetFlagStatus

/**
 * @brief  查询指定 EXTI 线路标志位,用于轮询方式检测外部事件
 * @param  EXTI_Line: 指定要检查的EXTI线路
 * @retval FlagStatus: 返回EXTI线路的状态(SET或RESET)
 * @example
 *     if(EXTI_GetFlagStatus(EXTI_Line0) == SET)
 *     {
 *         // 处理中断事件
 *     }
 */
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);

功能说明:

  • 返回 SET 表示该线路有挂起事件
  • 轮询模式下使用,不检查中断使能位

6. EXTI_ClearFlag

/**
 * @brief  清除指定 EXTI 线路标志位,轮询处理完成后需调用
 * @param  EXTI_Line: 指定要清除标志位的EXTI线路
 * @retval
 * @example
 *     EXTI_ClearFlag(EXTI_Line0);
 */
void EXTI_ClearFlag(uint32_t EXTI_Line);

功能说明:

  • 清除后标志恢复 RESET
  • 轮询模式下处理完事件后调用

7. EXTI_GetITStatus

/**
 * @brief  查询指定 EXTI 中断是否挂起,用于 ISR 中判断中断源
 * @param  EXTI_Line: 指定要检查的EXTI线路
 * @retval ITStatus: 返回中断状态(SET或RESET)
 * @example
 *     if(EXTI_GetITStatus(EXTI_Line0) == SET)
 *     {
 *         // 中断已发生
 *     }
 */
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);

功能说明:

  • 同时检查中断使能位和标志位
  • 比 GetFlagStatus 更适合在中断服务程序中使用

8. EXTI_ClearITPendingBit

/**
 * @brief  清除 EXTI 中断挂起位,ISR 结束前必须调用
 * @param  EXTI_Line: 指定要清除挂起位的EXTI线路
 * @retval
 * @example
 *     EXTI_ClearITPendingBit(EXTI_Line0);
 */
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

功能说明:

  • 不清除会导致中断反复进入
  • 通常与 GetITStatus 配对使用

使用示例

基本配置示例

void EXTI_Configuration(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    
    // 使能AFIO时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    
    // 配置EXTI线路0为中断模式,上升沿触发
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    
    // 配置GPIO连接到EXTI线路0
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
    
    // 使能NVIC中断
    NVIC_EnableIRQ(EXTI0_IRQn);
}

中断服务程序示例

void EXTI0_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line0) == SET)
    {
        // 处理中断事件
        LED_Toggle();  // 翻转LED状态
        
        // 清除中断挂起位
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

注意事项

  1. 时钟使能:使用EXTI前需要使能AFIO时钟
  2. GPIO配置:需要将GPIO引脚连接到对应的EXTI线路
  3. 中断优先级:合理设置中断优先级避免中断嵌套问题
  4. 标志位清除:在中断服务程序中必须清除中断标志位
  5. 线路限制:同一时刻一个GPIO端口只能有一个引脚连接到特定的EXTI线路

总结

STM32F10x EXTI标准库提供了完整的外部中断配置和处理功能,通过合理使用这些函数和结构体,可以轻松实现外部信号的检测和响应。掌握这些API的使用方法,对于开发基于STM32的嵌入式应用具有重要意义。