本文最后更新于57 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
前言
如果你是嵌入式开发的新手,或刚从标准库转型,那么 HAL 库(Hardware Abstraction Layer,硬件抽象层) 将是你开启 STM32 大门的金钥匙。
过去标准库需要我们对着几百页的寄存器手册一个位一个位地配置,而现在,借助于 ST 官方提供的 STM32CubeMX 图形化工具,我们可以通过“点点鼠标”快速生成初始化代码,把精力集中在核心业务逻辑上。
有同学咨询过我,看stm32cubemx的图形化配置界面,就想当然地认为cubemx界面可以完成所有配置,就不需要我们去编写代码了(doge)我哭笑不得,所以希望大家去接触一下hal库的开发流程,哪怕只是点灯,相信会对大家有一些帮助
今天,我们就用最简单的方式,带你完成第一个 STM32 HAL 库项目:点亮 LED 灯。
一、 为什么选择 HAL 库?
- 跨平台移植性强:F1 系列的代码可以轻松移植到 F4 或 H7 上。
- 开发效率高:图形化配置时钟树和外设,告别繁琐的底层初始化。
- 官方主推:ST 已停止维护标准库,HAL 库是未来的标准。
- 易读性好:API 命名直观,如 HAL_GPIO_WritePin(),见名知义。
二、 准备工作
在开始之前,请确保你的电脑上已安装:
- STM32CubeMX:用于配置芯片和生成代码。
- Keil uVision 5 (或 STM32CubeIDE):用于编写代码和编译。
- STM32 开发板:用于测试代码运行
- ST-Link/DAP-Link等烧录器:用于下载程序。
三、 实战步骤:点亮 LED
我们将配置 STM32 的 PC13 引脚(大多数最小系统板的板载 LED 引脚)为输出模式,并实现闪烁效果。
1. CubeMX 配置 (图形化阶段)
- 新建工程:打开 CubeMX,点击 “Access to MCU selector”,输入你的芯片型号(如 STM32F103C8)并双击。


- 设置引脚 (Pinout):在右侧芯片引脚图找到 PC13,左键点击并选择 GPIO_Output。

- 时钟配置 (Clock Configuration):
- 在System Core中的RCC中,将RCC中的HSE和HSI的源设置为外部晶振
- 点击上方 Clock Configuration 选项卡。
- 在 HCLK 框输入最大频率(如 72MHz),按回车,让工具自动配置时钟树。


- 项目设置 (Project Manager):
- Project Name: 填写项目名称(如 LED_Blink)。
- Toolchain / IDE: 选择 MDK-ARM (如果你用 Keil) 或 STM32CubeIDE。
- Code Generator: 勾选 “Generate peripheral initialization as a pair of ‘.c/.h’ files per peripheral”(这样代码结构更清晰)。
- 生成代码:点击右上角的 GENERATE CODE。
- 注意项目名称和项目路径尽量使用西文字符


2. 编写逻辑代码 (开发阶段)
打开生成的 Keil 工程,找到 main.c 文件。
⚠️ 铁律:所有的用户代码必须写在 USER CODE BEGIN 和 USER CODE END 之间!
否则,下次你用 CubeMX 修改配置重新生成代码时,你的代码会被全部覆盖删除。
在 main.c 的 while(1) 循环中添加以下代码:codeC
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// 1. 翻转 PC13 引脚电平
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
// 2. 延时 500 毫秒
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
3. 编译与下载
- 点击 Keil 的 Build (F7) 按钮,确保 0 Error(s)。
- 点击 Download (F8) 将程序烧录进开发板。
- 观察现象:板子上的 LED 灯开始以 0.5 秒为间隔闪烁了!
四、 常用 HAL 库 GPIO 函数解析
掌握了 LED 闪烁,你就已经学会了 HAL 库的基本逻辑。以下是几个最常用的 GPIO 函数:
- 电平输出:
HAL_GPIO_WritePin(GPIOX, GPIO_PIN_X, GPIO_PIN_SET/RESET); - 电平翻转:
HAL_GPIO_TogglePin(GPIOX, GPIO_PIN_X); - 读取电平:
HAL_GPIO_ReadPin(GPIOX, GPIO_PIN_X); - 毫秒延时:
HAL_Delay(ms);
五、 给初学者的进阶建议
- 善用跳转:在 Keil 中选中一个函数(如 HAL_GPIO_Init),按 F12 可以直接跳转到定义。你会发现 HAL 库的源码里有非常详尽的英文注释,教你如何使用这个外设。
- 理解句柄 (Handle):HAL 库大量使用了结构体(句柄),比如 UART_HandleTypeDef。这就像是一个“身份证”,里面记录了该外设的所有配置信息。
- 不要怕报错:遇到问题优先检查:
- CubeMX 里引脚有没有配置对?
- 代码是不是写在了 USER CODE 区域外?
- 电源和下载线是否接触良好?
结语
从寄存器到标准库,再到如今的 HAL 库,嵌入式开发变得越来越高效。HAL 库并不是让你变懒,而是让你把有限的精力投入到更有价值的算法和逻辑开发中。
再多的理论都不如实践,还希望大家动手操作
下一篇预告:如何使用 HAL 库实现串口通信(UART)。


