【STM32】按键(外部中断)控制LED亮灭实验——EXTI外部中断控制器、NVIC中断分组

外部中断实验

通常来说,外部中断可以理解为是通过一个独立按钮,发送一个中断信号,后发生一系列活动。
外部中断实验就是在独立按键实验的基础上,添加外部中断模块而实现的。
在这里插入图片描述
在这里插入图片描述

EXTI

      EXTI_InitTypeDef    EXTI_InitStructure; 
      EXTI_InitStructure.EXTI_Line=EXTI_Line4; //中断线的标号,取值范围为EXTI_Line0~EXTI_Line15
      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  //中断模式,可选值为中断EXTI_Mode_Interrupt和事件 EXTI_Mode_Event
      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //中断触发方式,下降沿触发 EXTI_Trigger_Falling,上升沿触发 EXTI_Trigger_Rising,或者任意电平(上升沿和下降沿)触发EXTI_Trigger_Rising_Falling
      EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断线
      EXTI_Init(&EXTI_InitStructure);       //根据 EXTI_InitStruct 中指定的 
//参数初始化外设 EXTI 寄存器 

从定义可以看出,有 4 个参数需要设置。
第一个参数是中断线的标号,取值范围为EXTI_Line0~EXTI_Line15。也就是说,这个函数配置的是某个中断线上的中断参数。
第二个参数是中断模式,可选值
中断 EXTI_Mode_Interrupt
和事件EXTI_Mode_Event。

第三个参数是触发方式,可以是
下降沿触发 EXTI_Trigger_Falling,
上升沿触发 EXTI_Trigger_Rising,
任意电平(上升沿和下降沿)触发EXTI_Trigger_Rising_Falling。

最后一个参数就是使能中断线了。

NVIC

NVIC_InitTypeDef NVIC_InitStructure; 
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//使能按键外部中断通道线2 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,   
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级 2 
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //外部中断通道使能
NVIC_Init(&NVIC_InitStructure);//根据上面指定的参数初始化NVIC寄存器 中断优先级分组初始化 

中断优先级设置的步骤:

  1. 系统运行开始的时候设置中断分组。确定组号,也就是确定抢占优先级子优先级分配位数。调用函数为 NVIC_PriorityGroupConfig();
  2. 设置所用到的中断的中断优先级别。对每个中断调用函数为 NVIC_Init();

中断线 0-4 每个中断线对应一个中断函数,中断线 5-9 共用中断函数 EXTI9_5_IRQHandler,中
断线 10-15 共用中断函数 EXTI15_10_IRQHandler。在编写中断服务函数的时候会经常使用到两
个函数,第一个函数是判断某个中断线上的中断是否发生(标志位是否置位):

一共16条中断线,对应6个中断函数

外部中断的对应关系

GPIOA_0~GPIOG_0————中断线 0对应一个中断函数EXTI0_IRQHandler
GPIOA_1~GPIOG_1————中断线 1对应一个中断函数EXTI1_IRQHandler
GPIOA_2~GPIOG_2————中断线 2对应一个中断函数EXTI2_IRQHandler
GPIOA_3~GPIOG_3————中断线 3对应一个中断函数EXTI3_IRQHandler
GPIOA_4~GPIOG_4————中断线 4对应一个中断函数EXTI4_IRQHandler

GPIOA_5~GPIOG_5————中断线5
GPIOA_6~GPIOG_6————中断线6
GPIOA_7~GPIOG_7————中断线7————中断线5-9 共用中断函数 EXTI9_5_IRQHandler
GPIOA_8~GPIOG_8————中断线8
GPIOA_9~GPIOG_9————中断线9

GPIOA_10~GPIOG_10————中断线10
GPIOA_11~GPIOG_11————中断线11
GPIOA_12~GPIOG_12————中断线12
GPIOA_13~GPIOG_13————中断线13————中断线10-15 共用中断函数 EXTI15_10_IRQHandler
GPIOA_14~GPIOG_14————中断线14
GPIOA_15~GPIOG_15————中断线15

常用的中断服务函数格式为:

void EXTI2_IRQHandler(void) 
{ 
if(EXTI_GetITStatus(EXTI_Line2)!=RESET)//判断某个线上的中断是否发生       
  { 
    中断逻辑… 
    EXTI_ClearITPendingBit(EXTI_Line2);//清除 LINE 上的中断标志位     
  }       
} 

使用 IO 口外部中断的一般步骤:
1)初始化 IO 口为输入。
2)开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。
3)初始化线上中断,设置触发条件等。
4)配置中断分组(NVIC),并使能中断。
5)编写中断服务函数。

实验目的

PC5按键KEY0 控制 DS0,按一次亮,再按一次,就灭。
PA15按键KEY1 控制 DS1,按一次亮,再按一次,就灭。。
PA0按键WK_UP 按键则同时控制 DS0 和 DS1,按一次,他们的状态就翻转一次。

实验过程

硬件部分

本实验用到的硬件资源有:
1) 指示灯 DS0、DS1
2) 3 个按键:KEY0、KEY1 和 KEY_UP。
DS0、DS1 和 STM32 的连接在上一章已经介绍了,在 MiniSTM32 开发板上的按键 KEY0连接在 PC5 上、KEY1 连接在 PA15 上、WK_UP 连接在 PA0 上。
在这里插入图片描述
这里需要注意的是:KEY0 和 KEY1 是低电平有效的,而 WK_UP 是高电平有效的,除了
KEY1 有上拉电阻(与 JTDI 共用),其他两个都没有上下拉电阻,所以,需要在 STM32 内部设
置上下拉。

软件部分

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,针对你的问题,我可以给出以下的回答: 在 STM32外部中断中,可以通过设置 GPIO 的输出状态来控制 LED亮灭。具体方法如下: 1. 配置 EXTI 外部中断线,使其与 GPIO 相关联; 2. 在 EXTI中断处理函数中,检测 GPIO 的输入状态,根据输入状态设置 GPIO 的输出状态,从而控制 LED亮灭。 以下是代码示例: ```c #include "stm32f10x.h" void EXTI0_IRQHandler(void) { if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_RESET) // 检测 PA0 的输入状态 { GPIO_SetBits(GPIOB, GPIO_Pin_0); // 设置 PB0 输出高电平,LED 亮 } else { GPIO_ResetBits(GPIOB, GPIO_Pin_0); // 设置 PB0 输出低电平,LED 灭 } EXTI_ClearITPendingBit(EXTI_Line0); // 清除 EXTI0 的中断标志位 } int main(void) { GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // 使能 GPIOA 和 GPIOB 时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); // 配置 PA0 为输入引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置 PB0 为输出引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // 配置 EXTI0 为中断源 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); // 配置 EXTI0 的中断优先级 NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); while (1) { // 循环处理 } } ``` 以上代码中,PA0 被配置为输入引脚,当 PA0 的输入状态发生变化时,触发 EXTI0 的中断。在 EXTI0 的中断处理函数中,检测 PA0 的输入状态,并根据状态设置 PB0 的输出状态,从而控制 LED亮灭。需要注意的是,此处使用了下降沿触发方式,即当 PA0 从高电平变为低电平时触发中断
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值