EXTI 学习过程中总结

文章详细介绍了STM32中的EXTI(外部中断/事件控制器)理论,包括其功能、中断线配置,并解析了EXTI初始化结构体的各个字段。接着,文章阐述了NVIC(NestedVectorInterruptController)初始化结构体,以及如何配置中断优先级。实践中,作者以STM32F103为例,演示了如何初始化GPIO、EXTI和NVIC,以及编写中断服务函数来响应按键中断,实现LED灯的翻转功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

EXTI理论部分

介绍EXTI初始化结构体

介绍NVIC初始化结构体 

实践部分

编程思路

1、初始化GPIO

2、初始化EXTI

2.1 初始化EXTI中断/事件线

2.2 初始化EXTI结构体

 2.3 调用EXTI初始化函数

3、初始化NVIC 

4、编写中断服务函数 

5、在main函数中编写

 文章中涉及的部分专业词汇


EXTI理论部分

EXTI(External interrupt/event controller)— 外部中断/事件控制器,管理了控制器的 20 个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿 检测和下降沿的检测。EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为 中断或者事件,以及触发事件的属性。

上面讲到EXTI有20个中断/事件线,其中16个是GPIO,剩下分别是PVD、RTC、USB这些外设的

 

介绍EXTI初始化结构体

typedef struct
{
  uint32_t EXTI_Line;              
   
  EXTIMode_TypeDef EXTI_Mode;      

  EXTITrigger_TypeDef EXTI_Trigger;

  FunctionalState EXTI_LineCmd;    
} EXTI_InitTypeDef;

  1、uint32_t EXTI_Line, 用设置中断屏蔽寄存器相对应位,可以在 stm32f10x_exti.h文件中找到相对应的初始化值,如下图2,联想到EXTI结构框图,便知道此处的作用(开放请求)

图像1

图像2
​​​​​

 2、EXTIMode_TypeDef EXTI_Mode, 用于设置相应中断/事件线到底是发出中断还是事件,对应值如下图

 3、EXTITrigger_TypeDef EXTI_Trigger, 在EXTI结构框图中第二步可以看到,边沿检测电路是需要相应寄存器来设置的,可以设置为上升沿触发、下降沿触发以及同时触发产生两个中断。

 4、FunctionalState EXTI_LineCmd,配置是否使能EXTI线,参数有:ENABLE、DISABLE

介绍NVIC初始化结构体 

typedef struct
{
  uint8_t NVIC_IRQChannel;                    

  uint8_t NVIC_IRQChannelPreemptionPriority;  

  uint8_t NVIC_IRQChannelSubPriority;       

  FunctionalState NVIC_IRQChannelCmd;   
} NVIC_InitTypeDef;

1、 NVIC_IRQChannel、选择中断源

2、NVIC_IRQChannelPreemptionPriority, 配置抢占优先级(也叫主优先级)

3、NVIC_IRQChannelSubPriority, 配置子优先级

4、NVIC_IRQChannelCmd, 使能外设

实践部分

      本实践以stm32f103位基础,编写key1产生中断

编程思路

  1. 初始化要连接到EXTI的GPIO
  2. 初始化EXTI用于产生中断/事件
  3. 初始化NVIC,用于处理中断
  4. 编写中断服务函数
  5. 编写main函数

1、初始化GPIO

// 初始化GPIO
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( KEY1_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN;	
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   
GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);

2、初始化EXTI

2.1 初始化EXTI中断/事件线

GPIO_EXTILineConfig( GPIO_PortSourceGPIOA, GPIO_PinSource0);

   在这里曾产生过一个疑问,这里的实参GPIO_PortSourceGPIOA,是否就是GPIOA,后来发现GPIO_PortSourceGPIOA这个参数和GPIOA不一样,因为这个函数是操作AFIO_EXTICRx(x=1...4),GPIO_PortSourceGPIOA是用来配置这个寄存器的,而GPIOA则是一个变量,这样子就说的清了,同理 GPIO_PinSource0 也是用来配置AFIO_EXTICR这类寄存器相应位的

2.2 初始化EXTI结构体

// 初始化EXTI结构体
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

 2.3 调用EXTI初始化函数

// 在函数开始有定义声明 EXTI_InitTypeDef EXTI_InitStructure;
EXTI_Init( &EXTI_InitStructure );

3、初始化NVIC 

以注释的方式写在代码段里了。

void NVIC_IQRPriority_Config(void)
{
    //创建NVIC初始化结构体
	NVIC_InitTypeDef NVIC_InitStructure;
	//配置中断优先级分组
	NVIC_PriorityGroupConfig( NVIC_PriorityGroup_1);
	选择哪个中断/事件线
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    //打开NVIC外设
    //NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	//分别配置主、子中断优先级为1、7
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =  1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;
	//调用初始化函数,注意要的参数是地址
	NVIC_Init( &NVIC_InitStructure );
}

4、编写中断服务函数 

需要注意一点,中断服务函数的名字是固定的,在启动文件里的向量表中有各个中断服务函数的地址,可以在启动文件中找到相应的函数名,这里使用EXTI0_IQRhandler。

//这里实现让LED灯翻转的操作
void EXTI0_IRQHandler( )
{

    //在中断打开的情况下操作
    if ( EXTI_GetITStatus(EXTI_Line0 != RESET ) ) {
        LED_G_TOGGLE;
    }
    //清除中断位,不然一直中断
    EXTI_ClearITPendingBit( EXTI_Line0 );
}

5、在main函数中编写

 

 

 最终实现的效果就是按下开关灭,再按就亮

 文章中涉及的部分专业词汇

上升沿:指电信号从低电平(0)转到高电平(1)的一个过程。

下降沿:指电信号从高电平(1)转到低电平(0)的一个过程。

中断:中断是需要CPU参与的,需要软件的中断服务函数才能完成中断后产生的结果;

事件:是靠脉冲发生器产生一个脉冲,进而由硬件自动完成这个事件产生的结果

区别:事件是不需要CPU参与,降低了CPU的负荷

参考:

STM32之中断与事件---中断与事件的区别_flydream0的博客-CSDN博客_嵌入式中断和事件的区别

BSP(板级支持包),介于硬件和操作系统之间的为上层驱动程序提供访问硬件寄存器的函数包

参考:BSP板级支持包(board support package)_aFakeProgramer的博客-CSDN博客_bsp(board support package)BSP板级支持包(board support package),是介于主板硬件和操作系统中驱动层程序之间的一层,一般认为它属于操作系统一部分,主要是实现对操作系统的支持,为上层的驱动程序提供访问硬件设备寄存器的函数包,使之能够更好的运行于硬件主板。在嵌入式系统软件的组成中,就有BSP。BSP是相对于操作系统而言的,不同的操作系统对应于不同定义形式的BSP,例如VxWorks的BSP和Linux的BSP相对于某一CPU来说尽管实现的功能一样,可是写法和接口定义是完全不同的,所以写BSP一定要按照该系统BS_1671465600https://blog.csdn.net/usstmiracle/article/details/108647265?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167371050116782425189745%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167371050116782425189745&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-108647265-null-null.142%5Ev71%5Ewechat,201%5Ev4%5Eadd_ask&utm_term=bsp%E6%9D%BF%E7%BA%A7%E6%94%AF%E6%8C%81%E5%8C%85&spm=1018.2226.3001.4187

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值