stm32f407外部中断控制流水灯状态
时间: 2025-05-30 09:03:35 浏览: 25
### 使用STM32F407通过外部中断控制流水灯状态的实现
以下是基于STM32F407芯片,利用外部中断控制LED流水灯工作的代码示例。该代码使用HAL库进行开发,并假设GPIOA的一个输入引脚作为外部中断源,而其他GPIO用于驱动LED。
#### 初始化部分
初始化GPIO和EXTI(外部中断),并将GPIO配置为输入模式以便检测按键信号。
```c
#include "stm32f4xx_hal.h"
// 定义全局变量
uint8_t led_state = 0;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void)
{
HAL_Init(); // 初始化HAL库
SystemClock_Config(); // 配置系统时钟
MX_GPIO_Init(); // 初始化GPIO
while (1)
{
// 主循环可以为空,因为所有的逻辑都在中断服务程序中完成
}
}
/**
* @brief EXTI线回调函数,在发生外部中断时调用
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_0) // 假设PA0被配置为外部中断源
{
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)) // 判断是否为高电平
{
led_state = 1; // 启动流水灯
}
else
{
led_state = 0; // 停止流水灯
}
}
}
```
#### 中断处理函数
在中断服务程序中更新LED的状态:
```c
/**
* @brief 处理流水灯逻辑
*/
void Update_LEDs()
{
static uint8_t current_led = 0;
if (led_state == 1) // 如果处于启动状态
{
for (int i = 0; i < 8; i++) // 假设有8个LED连接到PB0-PB7
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0 << i, RESET); // 关闭当前LED
HAL_Delay(100); // 延迟一段时间
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0 << ((i + 1) % 8), SET); // 打开下一个LED
}
}
else // 如果处于停止状态
{
for (int i = 0; i < 8; i++)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0 << i, RESET); // 关闭所有LED
}
}
}
```
#### GPIO初始化函数
以下是对GPIO的初始化过程,包括设置输入引脚和输出引脚。
```c
static void MX_GPIO_Init(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA时钟
__HAL_RCC_GPIOB_CLK_ENABLE(); // 使能GPIOB时钟
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 配置GPIOA的第0号引脚为输入模式(外部中断)
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; // 上升沿/下降沿触发
GPIO_InitStruct.Pull = GPIO_PULLUP; // 上拉电阻
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置GPIOB的前8个引脚为输出模式(驱动LED)
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |
GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 |
GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 设置速度为低速
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// 配置NVIC优先级组
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
// 配置外部中断优先级并启用中断
HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); // 设置抢占优先级和子优先级
HAL_NVIC_EnableIRQ(EXTI0_IRQn); // 启用外部中断
}
```
以上代码实现了通过外部中断控制LED流水灯的功能[^1]。当GPIOA上的某个引脚接收到高电平时,流水灯开始运行;当接收低电平时,流水灯停止工作。
---
###
阅读全文
相关推荐


















