基于STM32hal库的外部中断检测按键+控制LED亮灭

目录

一、外部中断原理

二、NVIC简介

三、配置外部中断

四、编写外部中断程序


一、外部中断原理

        EXTI(External interrupt/event controller)—外部中断/事件控制器,和在STM32NVIC中断优先级管理(中断向量表)中讲述的CM3内核的外部中断不同。特指的是,在中断向量表中的EXTI的外部中断。STM32的每个IO都可以作为外部中断输入。EXTI管理了控制器的 20个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。

二、NVIC简介

NVIC 是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对Cortex-M3 内核里面的NVIC 进行裁剪,把不需要的部分去掉,所以说STM32的NVIC 是Cortex-M3 的NVIC 的一个子集。

NVIC 寄存器简介
在固件库中,NVIC 的结构体定义给每个寄存器都预留了很多位。不过STM32F103 可用不了这么多,只是用了部分而已,具体使用了多少可参考《Cortex-M3 内核编程手册》NVIC 寄存器映射。

typedef struct {
__IOM uint32_t ISER[8U]; // 中断使能寄存器
uint32_t RESERVED0[24U];
__IOM uint32_t ICER[8U]; // 中断清除寄存器
uint32_t RSERVED1[24U];
__IOM uint32_t ISPR[8U]; // 中断使能悬起寄存器
uint32_t RESERVED2[24U];
__IOM uint32_t ICPR[8U]; // 中断清除悬起寄存器
uint32_t RESERVED3[24U];
__IOM uint32_t IABR[8U]; // 中断有效位寄存器/
uint32_t RESERVED4[56U];
__IOM uint8_t IP[240U]; // 中断优先级寄存器(8Bit wide)
uint32_t RESERVED5[644U];
__OM uint32_t STIR; // 软件触发中断寄存器
} NVIC_Type;

NVIC 中断配置固件库

固件库文件core_cm3.h 的最后,还提供了NVIC 的一些函数,这些函数遵循CMSIS 规则,只要是Cortex-M3 的处理器都可以使用,具体如下:

void NVIC_EnableIRQ(IRQn_Type IRQn) //使能中断
void NVIC_DisableIRQ(IRQn_Type IRQn) //失能中断
void NVIC_SetPendingIRQ(IRQn_Type IRQn) //设置中断悬起位
void NVIC_ClearPendingIRQ(IRQn_Type IRQn) //清除中断悬起位
uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) //获取悬起中断编号
void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) //设置中断优先级
uint32_t NVIC_GetPriority(IRQn_Type IRQn) //获取中断优先级
void NVIC_SystemReset(void) //系统复位

三、配置外部中断

        从原理图我们可以得知,按键WK_UP按下的时候返回的是高电平,所以我们应该将WK_UP对应的PA0引脚配置为外部中断模式,将中断模式配置成 External lnterrupt Mode with Rising edge trigger detection (带上升边缘触发检测的外部中断模式),将LED0对应的PA8引脚配置成GPIO_Output模式。

四、编写外部中断程序

我们先在main.h里面宏定义一下HAL_GPIO_ReadPin()、HAL_GPIO_TogglePin()和HAL_GPIO_WritePin()函数,方便后面的代码编写。

#define KEY HAL_GPIO_ReadPin(KEY_GPIO_Port,KEY_Pin)
#define LED0_TOG HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin)
#define LED0_SET HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET)
#define LED0_RESET HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET)

编写外部中断回调函数:

/* 外部中断处理回调函数 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == GPIO_PIN_0)
	{
		HAL_Delay(15);	//按键消抖
		while(KEY);		//松手检测
        HAL_Delay(15);	//松手消抖
		LED0_TOG;		//翻转LED0引脚的电平来控制LED的亮灭
	}
}

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
首先,需要在STM32F407上连接一个按键和一个LED按键连接到一个GPIO输入引脚,LED连接到一个GPIO输出引脚。 然后,需要初始化这些引脚。使用HAL提供的函数可以很方便地完成初始化。下面是一个示例代码: ``` #include "stm32f4xx_hal.h" GPIO_InitTypeDef GPIO_InitStruct; void GPIO_Init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); // Initialize button pin (PA0) GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // Initialize LED pin (PC13) GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } ``` 在初始化完成后,需要设置外部中断。使用HAL提供的函数可以很方便地完成设置。下面是一个示例代码: ``` void EXTI0_IRQHandler(void) { if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); } HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); } void EXTI_Init(void) { // Enable EXTI0 interrupt HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); // Configure EXTI0 line EXTI_HandleTypeDef EXTI_InitStruct; EXTI_InitStruct.Line = EXTI_LINE_0; EXTI_InitStruct.Mode = EXTI_MODE_INTERRUPT; EXTI_InitStruct.Trigger = EXTI_TRIGGER_FALLING; EXTI_InitStruct.GPIOSel = EXTI_GPIOA; EXTI_InitStruct.GPIOPin = GPIO_PIN_0; HAL_EXTI_SetConfigLine(&EXTI_InitStruct); } ``` 在设置外部中断完成后,需要启动中断。下面是一个示例代码: ``` int main(void) { HAL_Init(); GPIO_Init(); EXTI_Init(); while (1) { // Do nothing } } ``` 这个示例代码中,当按键被按下时,LED会切换状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值