【STM32 HAL库】01 - LED闪烁实验(GPIO输出)
一、实验目的
熟悉 STM32CubeMX 图形化配置工具的基本使用流程
掌握 GPIO 引脚配置为输出模式的方法
理解 HAL 库中 GPIO 相关函数的使用
实现 LED 周期性闪烁,验证开发板下载、运行链路正常
二、硬件平台
项目 | 说明 |
|---|---|
开发板 | 野火霸天虎 STM32F407ZG |
主控芯片 | STM32F407ZGT6(LQFP144) |
LED 引脚 | PF6(红色 LED,开漏输出,低电平点亮) |
外部晶振 | HSE = 25 MHz |
系统时钟 | SYSCLK = 168 MHz |
野火 LED 电路说明:霸天虎板上的 LED 采用共阳极接法,GPIO 配置为开漏输出(Open Drain),当引脚输出低电平时 LED 点亮,输出高电平时 LED 熄灭。
三、软件环境
软件 | 版本/说明 |
|---|---|
STM32CubeMX | v6.x(生成初始化代码) |
Keil MDK-ARM | v5(编译+下载) |
固件包 | STM32Cube FW_F4 |
下载器 | ST-LINK / CMSIS-DAP |
四、CubeMX 配置步骤
4.1 选择芯片
打开 STM32CubeMX →ACCESS TO MCU SELECTOR→ 搜索STM32F407ZG→ 选择STM32F407ZGTx→Start Project。
4.2 配置 RCC(外部晶振)
左侧System Core → RCC:
High Speed Clock (HSE) 选择
Crystal/Ceramic Resonator(外部晶振)
4.3 配置时钟树
切换到Clock Configuration标签页:
配置项 | 值 |
|---|---|
HSE 输入频率 | 25 MHz |
PLL 来源 | HSE |
/M (PLLM) | 25 |
*N (PLLN) | 336 |
/P (PLLP) | 2 |
系统时钟来源 | PLLCLK |
AHB 预分频 | /1 |
APB1 预分频 | /4 |
APB2 预分频 | /2 |
最终 SYSCLK = 168 MHz,APB1 = 42 MHz,APB2 = 84 MHz。
4.4 配置 LED 引脚 PF6
在芯片引脚图上找到PF6,左键选择GPIO_Output。
点击左侧System Core → GPIO,找到 PF6 进行配置:
配置项 | 值 |
|---|---|
GPIO output level | Low(初始低电平,LED 亮) |
GPIO mode | Output Open Drain(开漏输出) |
GPIO Pull-up/Pull-down | No pull-up and no pull-down |
Maximum output speed | Low |
User Label | LED_R |
⚠️关键:GPIO mode 必须选择开漏输出(Open Drain),不能选推挽(Push Pull),否则与野火板的硬件电路不匹配。
4.5 配置调试接口
左侧System Core → SYS:
Debug 选择
Serial Wire(SWD 调试接口)
⚠️必须配置:如果不选 Serial Wire,下载一次后 PA13/PA14 会被复用,仿真器将无法再次连接芯片,只能用串口 ISP 救砖。
4.6 工程设置并生成代码
切换到Project Manager标签页:
配置项 | 值 |
|---|---|
Project Name |
|
Project Location | 自定义工程目录 |
Toolchain / IDE | MDK-ARM V5 |
Code Generator标签页勾选:
✅ Generate peripheral initialization as a pair of '.c/.h' files per peripheral
✅ Copy all used libraries into the project folder
点击右上角GENERATE CODE生成代码。
五、代码实现
生成代码后,打开Core/Src/main.c,在while(1)循环的USER CODE BEGIN 3区域添加 LED 翻转代码:
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_GPIO_TogglePin(LED_R_GPIO_Port, LED_R_Pin); /* 翻转 LED 电平 */ HAL_Delay(1000); /* 延时 1 秒 */ } /* USER CODE END 3 */核心函数说明
函数 | 作用 |
|---|---|
| 翻转指定 GPIO 引脚的输出电平 |
| 毫秒级延时(基于 SysTick) |
LED_R_GPIO_Port和LED_R_Pin宏定义在Core/Inc/main.h中,由 CubeMX 根据 User Label 自动生成:#define LED_R_Pin GPIO_PIN_6 #define LED_R_GPIO_Port GPIOF
GPIO 初始化代码(gpio.c,CubeMX 自动生成)
void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOF_CLK_ENABLE(); /* 使能 GPIOF 时钟 */ __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_RESET); /* 初始低电平 */ GPIO_InitStruct.Pin = GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; /* 开漏输出 */ GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); }六、编译与下载
编译:Keil 中按
F7或点击 Build 按钮,确认 0 Error(s)。配置下载器:魔术棒 →
Debug选择ST-Link Debugger或CMSIS-DAP Debugger→ Settings 确认识别到芯片。下载:按
F8或点击 Load 按钮。验证:下载成功后,LED_R 以 1 秒为周期闪烁。
七、实验现象
板载红色 LED(LED_R)每秒亮灭一次,循环闪烁。
八、常见问题
问题 | 原因 | 解决方法 |
|---|---|---|
LED 不亮 | 下载后未自动运行 | 勾选 |
LED 微亮但不闪烁 | GPIO 配成推挽输出 | 改为开漏输出(Open Drain) |
编译报错找不到头文件 | Include 路径未配置 | 检查 Keil 工程 Include Paths |
仿真器无法连接 | SYS Debug 未配置 Serial Wire | 用串口 ISP 重新下载,或检查接线 |
延时不准 | HSE 频率配错 | 确认 HSE = 25 MHz(野火板不是 8 MHz) |
九、工程目录结构
01_LED_Blink/ ├── Core/ │ ├── Inc/ │ │ ├── main.h ← LED_R_Pin 等宏定义 │ │ ├── gpio.h │ │ ├── stm32f4xx_hal_conf.h │ │ └── stm32f4xx_it.h │ └── Src/ │ ├── main.c ← 主循环(LED 翻转逻辑) │ ├── gpio.c ← GPIO 初始化(CubeMX 生成) │ ├── stm32f4xx_hal_msp.c │ ├── stm32f4xx_it.c ← 中断服务函数 │ └── system_stm32f4xx.c ← 系统时钟 ├── Drivers/ ← STM32 HAL 库源码 ├── MDK-ARM/ ← Keil 工程文件 └── 01_LED_Blink.ioc ← CubeMX 配置文件提示:修改代码时务必写在
/* USER CODE BEGIN */和/* USER CODE END */之间,否则重新用 CubeMX 生成代码时会被覆盖。