STM32F103同时配置两个外部中断

EXTI外部中断简介

EXTI—外部中断/事件控制器,管理了控制器的 19个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。另外在工程中的启动文件startup_stm32f10x_hd.s 中有对应的中断向量表,对与不同型号的芯片,中断向量表略有不同。

EXTI外部中断

每一个 IO 都可以作为外部中断的引脚,但是 IO 的中断是以组为一个单位的,同一时间只能使用同组的一个作为外部中断输入,例如我们要使用 PA0 为外部中断的输入 IO,这时由于 PA0,PB0,PC0,PD0,PE0 这些 IO 为同组,所有同一时间就不能使用 PB0,PC0,PD0,PE0 作为外部中断输入 IO 了。只能使用末端序号不同的外部中断 IO。每一组使用一个中断标志 EXTIx,EXTI0 – EXTI4 这 5 个外部中断有着自己的单独的中断响应函数,EXTI5-9 共用一个中断响应函数,EXTI10-15 共用一个中断响应函数。
在这里插述

NVIC中断控制

从 STM32 的中断向量表可以看出 STM32 有许多的中断,对于这些中断就需要控制器来管理。对于中断的控制,STM32 有一个专用的管理机构 NVIC(Nested Vectored Interrupt Controller)。STM32 采用中断分组的办法来确定中断优先级,分成两种优先级,一个为抢占优先级,一个为响应优先级。另外也将中断分为 5 组。在这里插片描述
中断分为 0-4 该分组的设置是由 SCB->AIRCR 寄存器的 bit10~8 来定义的。其中抢占优先级的级别高于响应优先级,数值越低优先级越高。
在程序中只能设置一个中断分组,不能同时设置两个分组。在 ST 库中通过调用函 数 NVIC_PriorityGroupConfig(uint32_tNVIC_PriorityGroup);来设置分组的,形参即为分组号。假如选择第2组,当设置中断1的抢占和相应优先级都是0,中断2的抢占和相应都是1,当二者都发生中断时,先比较抢占优先级,0比1优先,先执行中断1,如果当中断1和中断2的抢占优先级相同时,比较响应优先级,和上述比较一样,尤其注意,当俩个中断抢占优先级为同一级别,中断1响应优先级为0,中断2响应优先级为1,若此时中断2正在执行,那么中断1是不可以打断。

外部中断配置

void EXTInterrupt_Mode_Configuration(void) 
{
 EXTI_InitTypeDef EXTI_InitStructure;//结构体定义
 //中断PE.0
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource0);//PE.0 与中断0相映射
EXTI_InitStructure.EXTI_Line = EXTI_Line0;// PE.0 对应中断线 0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//外中断
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发中断
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能中断
EXTI_Init(&EXTI_InitStructure);

//中断PE.1
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource1);//PE.1 与中断1相映射
EXTI_InitStructure.EXTI_Line = EXTI_Line1;// PE.1 对应中断线 1
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//外中断
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发中断
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能中断
EXTI_Init(&EXTI_InitStructure);
}

第一个成员 EXTI_Line 是中断线,也就是选择外部中断线 EXTI_Line0~Line18 共 19 根线,由于本次实验使用 PE0 所有选择EXTI_Line0。第二个成员 EXTI_Mode 为中断模式,即中断请求,可以是 EXTI_Mode_Interrupt 中断请求。第三个成员 EXTI_Trigger 为触发方式,
其中有三种触发方式:上升沿触发 EXTI_Trigger_Rising、下降沿触发 EXTI_Trigger_Falling、上升沿下降沿触发 EXTI_Trigger_Rising_Falling,这里注意,如果你选择下降沿触发方式则在 IO 初始化的时候配置成上拉输入,这样才能产生一个有效的中断信号。

外中断嵌套中断向量配置

void NVIC_Configuration(void)
{
 NVIC_InitTypeDef NVIC_InitStructure;
 //中断PE.0
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置 NVIC 中断分组 2,其中 2 位抢占优先级,2 位响应优先级
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;// 选择外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级 0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//响应优先级 0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

// //中断PE.1
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;// 选择外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级 0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级 0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
} 

首先调用 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);完成 NVIC 中断分组,这里使用第 2 组,接着是 NVIC 的配置,通过调用库
函数 NVIC_Init(&NVIC_InitStructure)切记每一次配置都要有初始化;完成 NVIC 的初始化,结构体中的第一个成员 NVIC_IRQChannel 为需要配置的中断向量,本程序使用的是外部中断 0,所以配置的中断向量为 EXTI0_IRQn(外部中断 0 -4是独立的四个中断,例如中断1需设置EXTI1_IRQn);第二个成员 NVIC_IRQChannelPreemptionPriority 为抢占优先级,这里设置为抢占优先级 0,;第三个成员 NVIC_IRQChannelSubPriority 为响应优先级,这里设置为响应优先级 0;第四个成员NVIC_IRQChannelCmd 为使能或失能,这里设置 ENABLE 使能。

中断服务函数

中断的参数配置完成接着看看中断服务函数的编写,在工程中的启动文件
startup_stm32f10x_hd.s 中可以看到 STM32 所有的中断响应函数名。由于外中断每一组中断线使用一个中断标志 EXTIx,其中 EXTI0~4 这 5 个外部中断有着自己的单独的中断响应函数 EXTIx_IRQHandler(void),( x=0、1、2、3、4),而 EXTI5~9 共用一个中断响应函数EXTI9_5_IRQHandler(void)。

void EXTI0_IRQHandler(void)
{
 if (EXTI_GetITStatus(EXTI_Line0) != RESET) // 判断是否发生了中断
  {
  if ((KEY1 == 0) || (KEY2 == 0) )
  {
    Delay_1ms(10); // 延时10ms去抖动
    if (KEY1 == 0) // KEY1按下
    {
      LED1_Toggle ;
      while (KEY1 == 0)
        ; // 松手检测
    }
    
    }
 EXTI_ClearITPendingBit(EXTI_Line0);
 }
 }
void EXTI1_IRQHandler(void)
{
 if (EXTI_GetITStatus(EXTI_Line1) != RESET) // 判断是否发生了中断
  {
  if (KEY2 == 0)
  {
    Delay_1ms(10); // 延时10ms去抖动
    
    if (KEY2 == 0)
    {
      LED2_Toggle ;
      while (KEY2 == 0)
        ;
    }
    }
 EXTI_ClearITPendingBit(EXTI_Line1);
 }
 }

确定是中断线 0触发的中断用户接着就可以处理用户自己编写的中断服务函数了,这里编写了两个服务函数两个独立按键控制LED灯,因为这是两个独立的中断,根据NVIC配置可以得出当PE0中断在执行时PE1是不会被执行的,执行完服务函数还要记得在程序的最后清除中断标志位,清除中断标志位通过调用EXTI_ClearITPendingBit(EXTI_Line0)来清除中断 0 的中断标志位。
以上是配置两个中断,均以中断0的配置为例,中断1和中断0的配置一样。

  • 15
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
stm32f103c8t6芯片支持外部中断和定时器功能。外部中断可与GPIO引脚配合使用,实现外部信号的触发响应。而定时器功能可以用于定时、输出比较、输入捕获和互补输出等功能。 对于外部中断stm32f103c8t6芯片有两个可用的外部中断线,分别是EXTI0和EXTI1。这两个外部中断线可以与GPIO引脚相连,用于检测外部触发信号的变化。具体的外部中断配置和使用方法可以参考引用中提到的《STM32的中断系统与外部中断基础》这本文献。 至于定时器,stm32f103c8t6芯片有四个定时器可供使用,分别是TIM1、TIM2、TIM3和TIM4。这些定时器可以用于实现定时功能、输出比较功能、输入捕获功能和互补输出功能。具体的定时器配置和使用方法可以参考引用中提到的《STM32的定时器开发基础》这本文献。 需要注意的是,stm32f103c8t6芯片中没有基本定时器,只有通用定时器和高级定时器。通用定时器包括TIM2、TIM3和TIM4,而高级定时器包括TIM1和TIM8。这些定时器的功能和特点有一些区别,具体的差异可以参考引用中提到的内容。 在使用定时器时,需要选择合适的时钟源。stm32f103c8t6芯片的高级定时器的时钟源有四种,分别是内部时钟源IN_CLK、外部时钟模式1(使用TIx引脚作为时钟源,x可以是1、2、3或4)、外部时钟模式2(使用ETR引脚作为时钟源)和内部触发输入(使用ITRx作为时钟源)。具体的时钟源配置方法可以参考引用中提到的内容。 综上所述,stm32f103c8t6芯片支持外部中断和定时器功能,外部中断可与GPIO引脚配合使用,定时器功能可实现定时、输出比较、输入捕获和互补输出等功能。具体的配置和使用方法可以参考引用和引用中提到的文献。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值