STM32-外部中断

外部中断可产生中断和事件:

产生中断;报告NVIC模块

产生事件;外设触发器

外部中断有20个线;0~15对应IO的引脚

编写思路:

  • 使能IO口时钟,配置输入(AFIO来配置GPIO)
  • 开启AFIO时钟,设置IO与中断线的映射关系

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

  • 配置中断分组NVIC,使能中断

typedef struct

{

uint8_t NVIC_IRQChannel; 指定要使能或禁用的中断通道

例如: TIM3_IRQn表示定时器3中断

uint8_t NVIC_IRQChannelPreemptionPriority; 指定NVIC_IRQChannel对应的抢占优先级,值越小优先级越高, 抢占优先级决定了当多个中断同时发生时的响应顺序

uint8_t NVIC_IRQChannelSubPriority;//NVIC_IRQChannel对应的子优先级(响应优先级)

当多个中断的抢占优先级相同时,子优先级决定响应顺序

FunctionalState NVIC_IRQChannelCmd;//NVIC_IRQChannel定义的中断通道

设置为ENABLE时,该中断通道将被使能并可触发中断服务

} NVIC_InitTypeDef;

  • 初始化EXTI,选择触发方式
cs 复制代码
/**
  * @brief  配置外部中断/事件线路(EXTI Line)与GPIO引脚的映射关系
  * @param  GPIO_PortSource: 指定GPIO端口源,例如GPIO_PortSourceGPIOA、GPIO_PortSourceGPIOB等
  * @param  GPIO_PinSource: 指定GPIO引脚源,例如GPIO_PinSource0、GPIO_PinSource1等
  * @note   调用前需先使能AFIO时钟(RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE))
  * @note   功能:将指定端口的指定引脚连接到对应的EXTI Line(如PinSource2对应EXTI_Line2)
  * @example GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2); 
  *          → 将GPIOE的Pin2引脚映射到EXTI_Line2线路
  */
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
cs 复制代码
typedef struct
{
  uint32_t EXTI_Line; //指定要使能或禁用的EXTI线
                        多个线可用逻辑或组合(如EXTI_Line0 | EXTI_Line1)
   
  EXTIMode_TypeDef EXTI_Mode;//指定EXTI线的工作模式
                            // EXTI_Mode_Interrupt: 产生中断请求
                            //  EXTI_Mode_Event: 产生事件触发信号

  EXTITrigger_TypeDef EXTI_Trigger;//EXTI线的触发边沿类型
                                   //EXTI_Trigger_Rising: 上升沿触发
                                   // EXTI_Trigger_Falling: 下降沿触发
                                   // EXTI_Trigger_Rising_Falling: 双边沿触发 

  FunctionalState EXTI_LineCmd;// 指定所选EXTI线的新状态
                               // 设置为ENABLE时,对应的EXTI线将被激活 */ 
} EXTI_InitTypeDef;
  • 编写EXTI中断函数,查询中断标志位,执行函数,清除中断标志位
cs 复制代码
/**
  * @brief  检查指定EXTI线路的中断请求状态
  * @param  EXTI_Line: 指定要检查的EXTI线路,可使用逻辑或组合多条线路
  *                    例如: EXTI_Line0 或 (EXTI_Line0 | EXTI_Line1)
  * @retval ITStatus: 中断状态(SET = 中断挂起未处理; RESET = 无中断请求)
  * @note   通常在中断服务函数中调用此函数确认具体触发源
  * @note   读取EXTI_PR寄存器对应位的值来判断中断状态
  * @example if(EXTI_GetITStatus(EXTI_Line2) != RESET) { ... }
  */
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)//读取EXTI_PR寄存器对应位的值来判断中断状态
cs 复制代码
/**
  * @brief  清除指定EXTI线路的中断挂起标志
  * @param  EXTI_Line: 指定要清除的EXTI线路,可使用逻辑或组合多条线路
  *                    例如: EXTI_Line0 或 (EXTI_Line0 | EXTI_Line1)
  * @note   必须在中断处理完成后调用此函数,否则会持续触发中断
  * @note   通过向EXTI_PR寄存器的对应位写入1来清除标志(写入0无效)
  * @example EXTI_ClearITPendingBit(EXTI_Line2); // 清除EXTI2的中断标志
  */
void EXTI_ClearITPendingBit(uint32_t EXTI_Line)

代码实现(按键按下灯亮)

cs 复制代码
#include "exti.h"
#include "led.h"
#include "SysTick.h"
#include "key.h"
/*******************************************************************************
* 函 数 名         : My_EXTI_Init
* 函数功能		   : 外部中断初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void My_EXTI_Init(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	EXTI_InitTypeDef  EXTI_InitStructure;
	
	//时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);//选择GPIO管脚用作外部中断线路
		
	//NVIC初始化
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//选择中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//子优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//初始化VIC寄存器	
	
	//
	EXTI_InitStructure.EXTI_Line = EXTI_Line0;//指定要使能或禁用的EXTI线
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//指定EXTI线的工作模式-中断请求
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//触发边沿类型-双边沿
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;//激活
	EXTI_Init(&EXTI_InitStructure);
}
/*******************************************************************************
* 函 数 名         : EXTI0_IRQHandler
* 函数功能		   : 外部中断0函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void EXTI0_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line0) == 1)//查询标志位
	{
		delay_ms(10);//消抖
		if(KEY_UP==1)
		{
			LED2=0;
		}	
	}
	EXTI_ClearITPendingBit(EXTI_Line0);//清楚标志位
}
相关推荐
丁满与彭彭1 小时前
嵌入式学习笔记-MCU阶段-DAY01
笔记·单片机·学习
海海不掉头发2 小时前
【计算机组成原理】-CPU章节学习篇—笔记随笔
笔记·单片机·学习·考研·计算机组成原理
趣多多代言人2 小时前
从零开始手写嵌入式实时操作系统
开发语言·arm开发·单片机·嵌入式硬件·面试·职场和发展·嵌入式
h137286978693 小时前
Type-C PD快充协议智能芯片S312L详解
嵌入式硬件
不想学习\??!5 小时前
STM32-定时器
stm32·单片机·嵌入式硬件
LIN-JUN-WEI6 小时前
[ESP32]VSCODE+ESP-IDF环境搭建及blink例程尝试(win10 win11均配置成功)
c语言·开发语言·ide·vscode·单片机·学习·编辑器
LS_learner6 小时前
嵌入式系统中实现串口重定向
嵌入式硬件
景彡先生7 小时前
STM32中SPI协议详解
stm32·单片机·嵌入式硬件
趣多多代言人7 小时前
嵌入式面试八股文100题(二)
单片机·嵌入式硬件