当前位置:   article > 正文

(STM32笔记)十一、通过EXTI外部中断实现 按键控制LED

(STM32笔记)十一、通过EXTI外部中断实现 按键控制LED

我用的是正点的STM32F103来进行学习,板子和教程是野火指南者
之后的这个系列笔记开头未标明的话,用的也是这个板子和教程。

十一、通过EXTI外部中断实现 按键控制LED

1、按键模块

按键原理图

可以看到在未按下时,引脚是低电平,按下之后变成高电平。
在这里插入图片描述

按键程序思路

在这里插入图片描述

  1. 初始化Key1 Key2所在GPIO的时钟

void RCC_APB2PeriphClockCmd(u32 RCC_APB2Periph, FunctionalState NewState)

第一个参数为设置何处时钟,第二个参数为ENABLE或者DISABLE
在这里插入图片描述

  1. 新建Key1 Key2对应的GPIO结构体

GPIO_InitTypeDef GPIO_InitStructure;

成员分别包括 引脚、时钟速率、模式
在这里插入图片描述

  1. 初始化GPIO结构体

GPIO_InitStructure.GPIO_Pin = macKEY1_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = macKEY1_GPIO_Mode;

因为在按下按键后会有一个电压上升沿,所以GPIO模式应该设置为 浮空输入(FLOATING)
在这里插入图片描述

  1. 使用GPIO引脚初始化函数

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

GPIOx: 指向要配置的 GPIO 端口(如 GPIOA, GPIOB 等)。
GPIO_InitStruct: 指向包含引脚配置的结构体的指针。

如:
GPIO_Init ( macKEY1_GPIO_PORT, & GPIO_InitStructure );

  1. 检测按键是否被按下

uint8_t Key_Scan ( GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin, uint8_t ucPushState, uint8_t * pKeyPress )

  • 读取按键的当前状态。
  • 如果按键处于按下状态,延时一段时间(消抖)。
  • 再次读取按键状态,确认按下后,标记按键被按下过。
  • 如果按键释放并且之前标记过按下,则认为按键被单击,返回1。
  • 否则返回0。
    在这里插入图片描述

2、中断模块

初始化EXTI用来产生中断

在这里插入图片描述

配置中断优先级

static void EXTI_NVIC_Config(void)

这个 EXTI_NVIC_Config 函数用于配置嵌套向量中断控制器(NVIC),以便为外部中断(EXTI)设置适当的中断优先级和使能。具体来说,它配置了 EXTI0 线路的中断。

  1. 配置优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  • 1

配置 NVIC 的优先级分组。NVIC_PriorityGroup_1 表示中断优先级分组 1,该分组将优先级划分为两部分:抢占优先级和子优先级。

  • NVIC_PriorityGroup_1 通常将 4 位优先级分为 1 位抢占优先级和 3 位子优先级。抢占优先级用于打断其他中断,子优先级用于决定同级别抢占优先级中断的处理顺序。
    在这里插入图片描述
  1. 配置 EXTI0 中断
    在这里插入图片描述
  • NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
    配置中断通道为 EXTI0_IRQn,即外部中断线 0 对应的中断通道。
    在这里插入图片描述

  • NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
    设置抢占优先级为 1。抢占优先级越低,优先级越高。

  • NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
    设置子优先级为 1。在抢占优先级相同的情况下,子优先级越低,优先级越高。

  • NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    使能 EXTI0 中断通道。

  1. 初始化 NVIC
NVIC_Init(&NVIC_InitStruct);
  • 1

调用 NVIC_Init 函数,使用配置好的 NVIC_InitStruct 结构体初始化 NVIC。

这样,当 EXTI0 中断发生时,NVIC 会根据配置的优先级正确处理中断。

初始化EXTI 使PA0触发外部中断

这段代码用于初始化外部中断/事件控制器(EXTI),使能 GPIOA 的第 0 引脚(PA0)触发的外部中断。下面是详细解释每一行代码的作用:

  1. 使能 AFIO 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  • 1
  • 使能替代功能(Alternate Function I/O, AFIO)时钟。AFIO 控制 GPIO 引脚的重映射和外部中断配置。
  • RCC_APB2PeriphClockCmd 函数用来配置外设时钟,RCC_APB2Periph_AFIO 表示 AFIO 模块。
  1. 配置 GPIO 引脚与 EXTI 线的连接
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
  • 1
  • 配置 GPIOA 的第 0 引脚(PA0)连接到 EXTI 线 0。
  • GPIO_EXTILineConfig 函数将指定的 GPIO 引脚连接到对应的 EXTI 线。
    • GPIO_PortSourceGPIOA: 指定 GPIOA 端口。
    • GPIO_PinSource0: 指定端口的第 0 引脚。
  1. 配置 EXTI 线
  • EXTI_InitStruct.EXTI_Line = EXTI_Line0;
    配置 EXTI 线 0(对应 PA0)。

  • EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    配置 EXTI 模式为中断模式。
    在这里插入图片描述

  • EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
    配置 EXTI 触发方式为上升沿触发(即信号从低电平变为高电平时触发中断)。
    在这里插入图片描述

  • EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    使能 EXTI 线。

  1. 初始化 EXTI
EXTI_Init(&EXTI_InitStruct);
  • 1
  • 调用 EXTI_Init 函数,使用配置好的 EXTI_InitStruct 结构体初始化 EXTI。
  • 该函数根据结构体配置,将 EXTI 线 0 设置为上升沿触发的中断模式,并使能该中断线。

这样,当 PA0 引脚的电平从低变高时,会触发 EXTI 线 0 的中断。

编写中断服务函数

  1. 在启动文件startup_stm32f10x_hd.s中找到中断函数名为EXTI0_IRQHandler
    在这里插入图片描述

  2. 在中断源文件stm32f10x_it.c 中添加中断函数
    在这里插入图片描述

  3. 当EXTI0被触发时,开关绿灯
    在这里插入图片描述

  • ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
    使用此函数检测到中断时,返回1或0。
    在这里插入图片描述

  • macLED1_TOGGLE();
    利用bsp_led.h里的函数翻转绿灯
    在这里插入图片描述

  • void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
    利用此函数来清除中断位,防止一直在中断内。

3、main()函数修改

在这里插入图片描述

添加按键、中断 和 LED 的初始化函数

4、初始化总结

按键初始化

  1. 按键时钟初始化
  2. 按键GPIO初始化

NVIC嵌套向量中断初始化

  1. 配置NVIC的优先级分组
  2. 配置GPIO引脚与EXTI事件线的连接
  3. NVIC初始化

EXTI外部中断初始化

  1. EXTI时钟初始化
  2. EXTI事件线初始化

LED初始化

  1. LED时钟初始化
  2. LED的GPIO初始化

interrupt(IT)中断初始化

  1. 在启动文件中找到对应的函数名
  2. 编写中断函数并添加到头文件中
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号