【STM32-学习笔记-2-】外部中断

文章目录

外部中断

Ⅰ、EXIT函数

c 复制代码
// 重置所有EXTI(外部中断/事件控制器)为默认值
void EXTI_DeInit(void);

// 初始化EXTI,根据初始化结构体配置参数
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

// 初始化EXTI初始化结构体的默认值
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);

// 生成指定EXTI线的软件中断
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);

// 获取指定EXTI线的标志状态
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
// 清除指定EXTI线的标志
void EXTI_ClearFlag(uint32_t EXTI_Line);

// 获取指定EXTI线的中断状态
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
// 清除指定EXTI线的中断待处理位
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

Ⅱ、EXTI_InitTypeDef结构体参数

①、EXTI_Line

指定要启用或禁用的EXTI线(中断线)

  • 该参数可以是@ref EXTI_Lines:

    • 宏定义解释

      这些宏定义用于选择特定的外部中断线。每个宏定义一个特定的中断线,值为该中断线对应的位掩码

      • EXTI_Line0 到 EXTI_Line19
        • 值 :从 ((uint32_t)0x00001) 到 ((uint32_t)0x80000)
        • 描述 :分别表示选择外部中断线0到19。每个宏定义的值是该中断线对应的位掩码,例如 EXTI_Line0 的值为 0x00001,表示第0位被设置为1,其他位为0

      特殊中断线:

      • EXTI_Line16:连接到PVD(可编程电压检测器)输出
      • EXTI_Line17:连接到RTC(实时时钟)报警事件
      • EXTI_Line18:连接到USB设备/USB OTG FS从挂起状态唤醒事件
      • EXTI_Line19:连接到以太网唤醒事件

      宏函数

      1. IS_EXTI_LINE(LINE)
        • 描述:检查给定的中断线选择是否有效
        • 参数 :LINE,代表外部中断线选择
        • 功能 :检查LINE是否为有效的中断线组合。具体来说,检查LINE的高16位是否为0,且不为0
        • 返回值 :如果LINE有效,返回1(真),否则返回0(假)
      2. IS_GET_EXTI_LINE(LINE)
        • 描述:检查给定的中断线选择是否为单个中断线
        • 参数 :LINE,代表外部中断线选择
        • 功能 :检查LINE是否等于预定义的单个中断线选择宏中的任一个
        • 返回值 :如果LINE为单个中断线,返回1(真),否则返回0(假)

      表格:

      宏定义 值 描述
      EXTI_Line0~EXTI_Line15 0x00001~0x08000 选择外部中断线0~15
      EXTI_Line16 0x10000 连接到PVD输出的中断线
      EXTI_Line17 0x20000 连接到RTC报警事件的中断线
      EXTI_Line18 0x40000 连接到USB唤醒事件的中断线
      EXTI_Line19 0x80000 连接到以太网唤醒事件的中断线
      宏函数 描述
      IS_EXTI_LINE(LINE) 检查LINE是否为有效的外部中断线选择
      IS_GET_EXTI_LINE(LINE) 检查LINE是否为单个外部中断线选择

②、EXTI_LineCmd

指定所选EXTI线(中断线)的新状态

  • ENABLE:使能
  • DISABLE:失能

③、EXTI_Mode

指定EXIT的模式

  • 该参数可以是@ref EXTIMode_TypeDef:

    • 枚举类型定义

      c 复制代码
      typedef enum
      {
       EXTI_Mode_Interrupt = 0x00, /*!< 配置为中断模式 */
       EXTI_Mode_Event = 0x04      /*!< 配置为事件模式 */
      } EXTIMode_TypeDef;
      • EXTI_Mode_Interrupt :值为 0x00,表示配置为中断模式。
        • 在这种模式下,当外部信号触发中断时,会生成一个中断请求,可以中断当前的CPU操作,执行中断服务程序(ISR)
      • EXTI_Mode_Event :值为 0x04,表示配置为事件模式。
        • 在这种模式下,当外部信号触发事件时,不会生成中断请求,但可以用于触发其他硬件操作,如启动DMA传输

      宏函数

      c 复制代码
      #define IS_EXTI_MODE(MODE) (((MODE) == EXTI_Mode_Interrupt) || ((MODE) == EXTI_Mode_Event))
      • 描述:检查给定的模式是否为有效的EXTI模式
      • 参数 :MODE,代表EXTI模式
      • 功能 :检查MODE是否等于预定义的模式中的任一个
      • 返回值 :如果MODE有效,返回1(真),否则返回0(假)

④、EXTI_Trigger

指定EXTI的触发条件

  • 该参数可以是@ref EXTITrigger_TypeDef:

    • 枚举类型定义

      c 复制代码
      typedef enum
      {
       EXTI_Trigger_Rising = 0x08,          /*!< 上升沿触发 */
       EXTI_Trigger_Falling = 0x0C,         /*!< 下降沿触发 */
       EXTI_Trigger_Rising_Falling = 0x10   /*!< 上升沿和下降沿都触发 */
      } EXTITrigger_TypeDef;
      • EXTI_Trigger_Rising :值为 0x08,表示配置为上升沿触发
        • 当外部信号从低电平变为高电平时,触发中断或事件
      • EXTI_Trigger_Falling :值为 0x0C,表示配置为下降沿触发
        • 当外部信号从高电平变为低电平时,触发中断或事件
      • EXTI_Trigger_Rising_Falling :值为 0x10,表示配置为上升沿和下降沿都触发
        • 当外部信号从低电平变为高电平或从高电平变为低电平时,触发中断或事件

      宏函数

      c 复制代码
      #define IS_EXTI_TRIGGER(TRIGGER) (((TRIGGER) == EXTI_Trigger_Rising) || \
                                        ((TRIGGER) == EXTI_Trigger_Falling) || \
                                        ((TRIGGER) == EXTI_Trigger_Rising_Falling))
      • 描述:检查给定的触发条件是否有效
      • 参数 :TRIGGER,代表EXTI的触发条件
      • 功能 :检查TRIGGER是否等于预定义的触发条件中的任一个
      • 返回值 :如果TRIGGER有效,返回1(真),否则返回0(假)

Ⅲ、NVIC函数

c 复制代码
// 配置NVIC(嵌套向量中断控制器)优先级分组
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

// 初始化NVIC,根据初始化结构体配置参数
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

// 设置NVIC中断向量表的位置和偏移量
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);

// 配置NVIC的系统低功耗模式
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);

Ⅳ、NVIC_InitTypeDef结构体参数

①、NVIC_IRQChannel

指定要启用或禁用的IRQ通道

  • 该参数可以是@ref IRQn_Type:

      • 描述:指定要启用或禁用的中断请求(IRQ)通道

      • 取值范围 :可以是IRQn_Type枚举类型中的任意值。IRQn_Type定义了STM32设备的所有中断通道。具体值可以参考stm32f10x.h文件中的定义

      • 示例:

        c 复制代码
        NVIC_IRQChannel = USART1_IRQn;  // 例如,启用USART1的中断

②、NVIC_IRQChannelCmd

配置NVIC_IRQChannel中定义的IRQ通道启用或禁用

  • ENABLE:使能(启用)
  • DISABLE:失能(禁用)

③、NVIC_IRQChannelPreemptionPriority

指定IRQ通道的抢占优先级

  • 在NVIC_IRQChannel中指定。该参数可以是一个值在0~15之间

      • 描述 :指定在NVIC_IRQChannel中指定的IRQ通道的抢占优先级

      • 取值范围:0到15。0表示最高优先级,15表示最低优先级

      • 示例:

        c 复制代码
        NVIC_IRQChannelPreemptionPriority = 0;  // 最高优先级

④、NVIC_IRQChannelSubPriority

指定IRQ通道的子优先级

  • 在NVIC_IRQChannel。该参数可以是一个值在0~15之间

      • 描述 :指定在NVIC_IRQChannel中指定的IRQ通道的子优先级

      • 取值范围:0到15。0表示最高优先级,15表示最低优先级

      • 示例:

        c 复制代码
        NVIC_IRQChannelSubPriority = 1;  // 子优先级为1
  • 抢占优先级:当多个中断同时发生时,抢占优先级高的中断会先被处理。如果抢占优先级相同,则子优先级高的中断先被处理
  • 子优先级:在抢占优先级相同的情况下,子优先级用于进一步区分中断的优先级

Ⅲ、EXIT基本结构

Ⅳ、配置外部中断

  1. 开启GPIO和AFIO的时钟
    • 启用AFIO,允许配置引脚的备用功能,比如将某些引脚用作外部中断输入
  2. 配置GPIO
  3. 将引脚配置为外部中断(EXTI)线的触发源
  4. 配置EXIT
  5. 配置嵌套向量中断控制器(NVIC)的优先级分组
  6. 配置NVIC
c 复制代码
#include "stm32f10x.h"                  // Device header

void CountSensor_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//启用AFIO,允许配置引脚的备用功能,比如将某些引脚用作外部中断输入
    //配置GPIO
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStruct);
  
    //配置EXIT外部中断
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);//将PB14引脚配置为外部中断(EXTI)线的触发源
    
    EXTI_InitTypeDef EXTI_InitStruct;
    EXTI_InitStruct.EXTI_Line = EXTI_Line14;//选择外部中断线14
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;//启用外部中断线14
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//设置外部中断模式为中断模式
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;//选择下降沿触发
    EXTI_Init(&EXTI_InitStruct);//初始化外部中断
  
    //设置NVIC
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置嵌套向量中断控制器(NVIC)的优先级分组
    
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;//选择外部中断15到10的IRQ通道
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//启用这个IRQ通道
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//设置抢占优先级为1
    NVIC_InitStruct.NVIC_IRQChannelSubPriority  = 1;//设置响应优先级为1
    NVIC_Init(&NVIC_InitStruct);
}
/*
//中断程序示例
void EXTI15_10_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line14) == SET)//判断是否进入中断
    {
        //执行中断程序 
        
        EXTI_ClearITPendingBit(EXTI_Line14);//清除中断标志位
    }
}
*/

//*****************************************************************
void EXTI0_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line0) == SET)//顺时针旋转触发外部中断
    {
        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)
        {
            Encoder_Count--;//逆时针旋转
        }
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

void EXTI1_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line1) == SET)//顺时针旋转触发外部中断
    {
        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 0)
        {
            Encoder_Count++;//顺时针旋转
        }
        EXTI_ClearITPendingBit(EXTI_Line1);
    }
}

void EXTI15_10_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line14) == SET)
    {
        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14) == 1)
        {
            Encoder_Count = 0;//按下旋转编码器计数清零
        }
        EXTI_ClearITPendingBit(EXTI_Line14);
    }
}
相关推荐
§ꦿCFོ༉28 分钟前
嵌入式八股—C语言入门学习(一)
c语言·编程语言·嵌入式八股文
Zhao-Jichao1 小时前
AI Prompting for Everyone 课程笔记 - P21 总结 Conclusion
人工智能·笔记
欢欢李2 小时前
【LTE L3 笔记 05】LTE同步信号
笔记·无线通信·物理层·lte·空口协议
沐晓时光2 小时前
C语言入门,字符串和字符串函数知识讲解
c语言·开发语言
La Pulga3 小时前
【FreeRTOS源码学习笔记】空闲任务与阻塞延时
笔记·mcu·学习·嵌入式·freertos·实时操作系统
蒸蒸yyyyzwd3 小时前
秋招学习笔记 day106
笔记·学习
小李不想当小白5 小时前
WDG看门狗(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
欢欢李5 小时前
【LTE L3 笔记 04】LTE帧结构
笔记·无线通信·物理层·lte·空口协议
youcans_6 小时前
【嵌入式软件AI编程】(3)面向 AI 协同开发的 STM32 硬件信息标准化
人工智能·stm32·嵌入式硬件·ai编程
Zhao-Jichao7 小时前
AI Prompting for Everyone 课程笔记 - P20 实验与期末项目 Lab and Final Project
前端·人工智能·笔记