STM32F407按键控制呼吸灯

STM32F407按键控制呼吸灯

本次实现用到正点原子的STM32F407ZGT6(根据自己板子调整),通过STM32CubeMx+Keil5进行实现,实现效果是通过按键KEY0(PE4)控制LED0(PF9)灯进行呼吸,呼吸方式通过定时器实现,过程代码如果有错误地方恳请各位大佬指正。
@

STM32CubeMx配置界面

首先是初始界面
在这里插入图片描述

双击进入配置界面
在这里插入图片描述

配置引脚
按键初始化

在这里插入图片描述
LED0初始化
在这里插入图片描述

配置RCC时钟
我们使用的是外部高速晶振
在这里插入图片描述

配置定时器14通道一可以根据情况自己修改
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

配置MCU时钟树
根据以下图片修改
在这里插入图片描述

选择代码保存路径
以下分别对应路径名称,存储位置,需要注意的是最好为英文,否则会出现一些奇奇怪怪的问题,可以根据自己路径进行修改
在这里插入图片描述

代码生成,这里就完成了,点击生成文件
在这里插入图片描述

接下来就是Keil5实现
主要文件
在这里插入图片描述

上代码,代码有注释

代码如下:

**main.c main函数需要添加代码**
#include "key.h"

/* USER CODE BEGIN PV */
volatile uint8_t breath_enable = 1; // 呼吸灯使能标志
uint16_t pwm_value = 0; // 当前的PWM占空比(0~自动重装载值)
int8_t breath_dir = 1; // 呼吸方向:1表示递增(渐亮),-1表示递减(渐暗)
uint32_t max_compare; // 用于保存自动重装载值
/* USER CODE END PV */

int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM14_Init();
  /* USER CODE BEGIN 2 */
	// 启动PWM前设置初始状态
	 HAL_TIM_PWM_Start(&htim14, TIM_CHANNEL_1);  // 启动TIM14 PWM输出
   __HAL_TIM_SET_COMPARE(&htim14, TIM_CHANNEL_1, 0); // 初始灯灭
	 max_compare = __HAL_TIM_GET_AUTORELOAD(&htim14);  // 获取自动重装载值
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		/* 呼吸灯控制逻辑 */
        if (breath_enable) {
            pwm_value += breath_dir * 5;
            if (pwm_value >= max_compare) {
                breath_dir = -1;
            } else if (pwm_value <= 0) {
                breath_dir = 1;
            }
            __HAL_TIM_SET_COMPARE(&htim14, TIM_CHANNEL_1, pwm_value);
            HAL_Delay(10);
        }

        /* 按键扫描 */
        Key0_flag = KEY_Scan(0);
        if (Key0_flag == 1) {
            Key0_flag = 0;
            breath_enable = !breath_enable;
            if (breath_enable) {
                // 开启呼吸灯,重置方向
                breath_dir = 1;
                pwm_value = 0;   // 从0开始
                __HAL_TIM_SET_COMPARE(&htim14, TIM_CHANNEL_1, pwm_value);
            } else {
                // 关闭呼吸灯,熄灭LED
                pwm_value = 0;
                __HAL_TIM_SET_COMPARE(&htim14, TIM_CHANNEL_1, pwm_value);
            }
        }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}



KEY.c


#include "key.h"

//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,KEY2按下
//2,KEY3按下

uint8_t Key0_flag=0;

uint8_t KEY_Scan(uint8_t mode)
{	 
	static uint8_t key_up=1;//按键按松开标志
	
	if(mode) key_up=1;  //支持连按(按键连发有效)		
	if(key_up && KEY0==0)
	{
		HAL_Delay(10);
		key_up = 0;   //有键按下
		if(KEY0==0) return 1;	
	}
	else if(KEY0==1) key_up=1; 	    
	return 0;// 无按键按下	
}



	

key.h


#ifndef __KEY_H
#define __KEY_H	 
#include "main.h"

#define KEY0 HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4) //PA0

#define KEY0_PRES 	1

extern uint8_t Key0_flag;

uint8_t KEY_Scan(uint8_t);  		//按键扫描函数	

#endif




如果感兴趣的话可以进stm32f4xx_it,stm32f4xx_hal_usart库看看。

效果展示

在这里插入图片描述

介绍

呼吸灯效果通过PWM(脉宽调制)技术实现,核心是周期性调整LED的亮度。其本质是改变PWM信号的占空比:

占空比与亮度:占空比越高,LED亮度越强;占空比为0时灯灭,100%时最亮

渐变效果:通过线性或非线性(如指数曲线)改变占空比,模拟“呼吸”节奏

源码地址

通过网盘分享的文件:STM32F407ZGT6实现呼吸灯
链接: https://pan.baidu.com/s/1ZuNULWnhUmv5cTqnc49scg?pwd=1111 提取码: 1111

posted @ 2025-07-04 16:43  少年执笔  阅读(107)  评论(0)    收藏  举报