STM32 HAL库 外部中断 实现按键控制LED亮灭

目录

1、为什么使用GPIO外部中断控制LED亮灭?

2、NVIC嵌套向量中断控制器

3、EXTI外部中断

4、项目的硬件排线

5、STM32CUBE_MX配置

6、HAL库代码

7、实际效果


1、为什么使用GPIO外部中断控制LED亮灭?

        实现LED亮灭控制有很多方式,其中一种就是在main函数的while循环里面不断地检测GPIO引脚的电平变化实现输出的电平变化从而实现LED的亮灭控制。但是这种轮询的方式让CPU在不断地运行,不仅消耗电量而且消耗算力。

        另一种方式就是使用GPIO外部中断,这是一种可以由硬件自动触发任务执行的方式,只有需要进行控制的时候,CPU才会介入控制。

2、NVIC嵌套向量中断控制器

        NVIC属于STM32的内核外设,用于响应外设请求并让CPU跳转到指定的指令地址进行执行任务。STM32F103C8T6单片机只有10个系统异常和60个可屏蔽中断。

        STM32可以精确的控制60种中断的具体抢占优先级和响应优先级。原因是IPR寄存器组有15个寄存器。每个寄存器32位,8位控制一种中断,那么有15*4一共60个控制方式,用于解决多个相同中断的优先级处理问题。

        另外,除了上面的60个具体中断类型的控制,AIRCR寄存器还提供了对这60种中断的总的控制方式,AIRCR寄存器是一个32位寄存器,其中的10-8位用于设置总的优先级。具体位比特值对应的控制形式如下图。

        AIRCR寄存器的值会直接影响IPR寄存器8位控制位中的高四位,IPR高4位的不同组合的控制也如上图所示。

        中断向量表:就是每种中断对应跳转的函数地址,比如ADC1中断在A地址,IIC中断在C地址等。这些地址都已经被编译器提取确定无法修改,但是虽然有60种中断,但是电平变化的引脚却不止60个,所以需要在中断服务函数里面手动判定是哪个引脚触发了中断。

3、EXTI外部中断

        外部中断主要来自GPIO引脚以及STM32芯片内部的外设。具体如下:

  1. 0-15:对应GPIO_PIN 0-15中断;
  2. 16:PVD输出;
  3. 17:RTC闹钟事件;
  4. 18:USB唤醒事件;
  5. 19:连接到以太网唤醒事件(只适用于互联型产品)

4、项目的硬件排线

        具体的布线如下。系统板来自江科大最小系统板,PC13是该系统板自己集成的LED灯。

5、STM32CUBE_MX配置

        第一步:配置烧录方式

        第二步:配置PA8引脚功能

        第三步:配置PC13引脚功能

6、HAL库代码

        复杂下面的代码到main.c里面即可。HAL_GPIO_EXTI_Callback表示GPIO外部中断的回调函数,

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    if (GPIO_Pin == GPIO_PIN_8) {
        // 切换PC13引脚的电平
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
    }
}

7、实际效果

        请大家多多点赞。

LED_EXTI

  • 12
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,需要在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会切换状态。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值