
🎬 渡水无言 :个人主页渡水无言
❄专栏传送门 : 《linux专栏》《嵌入式linux驱动开发》《linux系统移植专栏》
❄专栏传送门 : 《freertos专栏》 《STM32 HAL库专栏》《linux裸机开发专栏》
⭐️流水不争先,争的是滔滔不绝
📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生
| 省级优秀毕业生获得者 | csdn新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生
在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连
目录
[二、时钟系统核心原理(从 "树" 的视角理解)](#二、时钟系统核心原理(从 “树” 的视角理解))
[3.1、CubeMX 完整配置步骤](#3.1、CubeMX 完整配置步骤)
[3.1.2、选择SYS 外设的核心配置及设置引脚模式](#3.1.2、选择SYS 外设的核心配置及设置引脚模式)
[3.1.3打开Clock Configuration](#3.1.3打开Clock Configuration)
前言
STM32 的时钟系统是整个单片机的 "心脏",决定了代码执行速度、外设工作频率。本次博客从时钟树原理入手,结合 CubeMX 配置 + Keil 实战,手把手教你从默认 8MHz 配置到 72MHz 最大频率,并通过板载 LED 闪烁直观感受时钟频率差异。
一、单片机系统结构
单片机的系统可以与电脑类比,甚至可以说是一一对应。
核心由 3 条总线串联所有外设,而所有外设都需要时钟信号驱动:
AHB 总线:高速总线,驱动内核、DMA、SRAM 等核心模块;
APB1 总线:低速总线,驱动串口、I2C、定时器(低速)等;
APB2 总线:高速总线,驱动 GPIO、ADC、定时器(高速)等。
数字电路可以分为两类:

下图可以看到,单片机内部有许许多多模块(红框),每个模块都包含记忆性的元件,它们都属于时序组合电路,所以单片机需要给每一个模块提供时钟信号:

二、时钟系统核心原理(从 "树" 的视角理解)
2.1、整体情况(两棵树)
STM32 的时钟系统可以类比成一棵 "大树",所有外设和内核的时钟都从这棵树分配而来。

左边的时钟树为绝大部分模块提供时钟,右边的只为RTC和IWDG模块提供时钟
树根:时钟源(HSI/HSE/PLL)树干:系统时钟 SYSCLK → AHB 总线时钟 HCLK
树枝:APB1/APB2 外设总线时钟
树叶:挂载在总线上的各个外设(GPIO、定时器、串口等)
2.2树根(时钟源)

在我们的stm32最小系统板上,LSE和HSE就是指芯片外接的两颗晶振,如下图所示:

2.3、树干

| 目标 SYSCLK | 方案 | 公式 | 优势 | 适用场景 |
|---|---|---|---|---|
| 8MHz | 低成本 | SYSCLK = HSI |
无外部晶振、电路简单 | 低成本、低精度要求项目 |
| 8MHz | 高精度 | SYSCLK = HSE |
时钟稳定、精度高 | 通信、同步类外设 |
| 8MHz | 锁相环学习 | SYSCLK = HSE/2 * 2 |
熟悉 PLL 配置流程 | 学习、调试 PLL 驱动 |
| 12MHz | 低成本 + PLL | SYSCLK = HSI/2 * 3 |
成本低 + 灵活频率 | 中等性能需求的低成本项目 |
| 12MHz | 高精度 + PLL | SYSCLK = HSE/2 * 3 |
高精度 + 灵活频率 | 工业控制、高精度采集 |
| 72MHz | 最高性能 | SYSCLK = HSE * 9 |
最大化 MCU 性能 | 高速运算、复杂业务场景 |
2.4、树枝和树叶
树枝就是指AHB、APB1、APB2三根总线,而树叶就是总线上的各个模块。

三、时钟配置实验
8MHZ时的时钟频率,让led闪烁
3.1、CubeMX 完整配置步骤
CubeMX新建项目------选型号------选调试接口------再点开clock configuration
1.打开STM32CubeMX,新建工程,选择芯片
2.设置芯片的调试接口(如果忘记这个步骤,芯片的调试接口将被锁死,程序烧录不进去)
3.1.1、创建新工程及选择芯片型号
首先点击File --->点击New project

选中STM32F103C8T6,再点击start project
3.1.2、选择SYS 外设的核心配置及设置引脚模式
在SYS Mode and Configuration栏中,按如下配置:
调试模式(Debug):选定了Serial Wire(SW 模式)。
这是 STM32 最常用的调试接口模式,仅需占用SWDIO和SWCLK两个引脚。
时基源(Timebase Source):选定了SysTick。
这表示将系统滴答定时器作为 HAL 库的时基来源,用于实现HAL_Delay()等延时函数,是 STM32 工程的标准配置。
并在右侧芯片图中点击PC13设置为GPIO_Output"
PA9引脚设置为GPIO_input"

3.1.3打开Clock Configuration
可以看到这就是上一小节说的两棵时钟树

还有一些目前没有用到的模块,以后再学,如下图所示:

其中,有一个极其特殊的树叶,那就是Cortex-M3内核,因为我们所写的所有代码都是由其执行的

这里HCLK的频率就决定着代码的执行速度。
注意stm32cubemax默认的Cortex-M3时钟频率为8MHZ

原理如下:

默认情况下SYSCLK为8MHZ,AHB的分频器默认情况是/1。所以此时HCLK频率(Cortex-M3频率)就为8MHZ。
这里我们就试一试8MHZ时的时钟频率,让led闪烁。
3.1.4、pc13引脚参数设置
点击GPIO选中对应的引脚,即可设置参数,设置为开漏模式,初值为高电平,这样led默认为熄灭。

3.1.5项目管理与生成
给项目取名、设置位置、选择开发的工具链,再点击GENERATE CODE生成

3.2、代码编写
本次实验原理如下:

在keil中补齐代码:
在while写如下代码:
uint32_t i;
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
for(i = 0; i < 1000000; i++){}
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
for(i = 0; i < 1000000; i++){}

为了更准确,可以把修改级别优化选项,改成level 0
| 优化等级 | 编译速度 | 代码体积 | 执行速度 | 调试友好度 | 适用场景 |
|---|---|---|---|---|---|
-O0(无优化) |
最快 | 最大 | 最慢 | 最好(调试时变量 / 行号完整) | 开发调试阶段 |
-O1(轻度优化) |
较快 | 较小 | 较快 | 较好 | 初步优化、验证功能 |
-O2(中度优化) |
中等 | 更小 | 更快 | 一般 | 正式发布前测试 |
-O3(高度优化) |
最慢 | 最小 | 最快 | 差(变量可能被优化掉,断点可能失效) | 最终量产版本 |

烧录完发现板载LED每秒钟1次,比想象中稍快一点,因为单片机内核指令流水线的存在让代码执行的速度稍快。
总结
本次博客从时钟树原理出发,完成了 STM32F103 8MHz 时钟配置与 LED 闪烁实战。


