0%

【MCU】嵌入式软件之时钟系统配置与开发

前言

本文从嵌入式软件开发的角度,简要讲述时钟系统的原理、组成、寄存器配置与开发、进阶应用等,引述示例包括但不限于ST、JL等厂商片子的时钟系统。

时钟简述

数字电路-时钟的本质

时钟的本质是周期性变化的信号,为数字系统提供统一的时序参考。通过稳定的频率和相位关系,确保系统中所有操作(如指令执行、数据传输等),在严格的时间窗口内完成,避免逻辑混乱。

数字电路依赖于同步设计,而时钟通过周期性脉冲信号,强制系统在离散的时间点上更新状态,实现同步,使得逻辑电路在一个周期完成相应的逻辑运算,规避过渡状态(数字电路运算延时导致的状态),避免信号混乱。

时钟系统组成

通常,一个简单、常见的时钟系统可以由以下几个部分组成:

  • 时钟源(Clock Source)
  • 时钟分频器(Clock Divider)
  • 锁相环(Phase-Locked Loop,PLL)
  • 时钟选择器(Clock Selector)
  • 时钟分布网络
  • 时钟管理单元(Clock Management Unit,CMU)

相应地,从嵌入式软件的角度,配置时钟也从上述几个方面展开。

时钟源

有源晶振

内置振荡电路和放大元件,直接输出时钟信号,稳定性更高

无源晶振(石英晶体)

需要外部电路驱动才能振荡。

石英晶体具有压电效应,即当对它施加机械应力时会产生电荷,反之,施加电场也会导致其机械变形。
每块石英晶体都有一个固有的谐振频率,这个频率由晶体的尺寸、形状和切割方式决定。

原理-振荡电路

锁相环(PLL)

时钟分布网络

时钟树,了解各总线、外设模块的时钟分配,才能去配置 目的模块的时钟

系统时钟之软件配置

时钟系统初始化

系统上电启动后,默认使用内部时钟源(内部RC振荡器)作为初始时钟。

时钟系统初始化:配置外部晶振、切换时钟源、PLL、分频器、总线/外设时钟配置等等

如何从零配置一个时钟的启动?以寄存器说明

时钟系统进阶应用

时钟门控

关闭未使用模块的时钟信号,减少动态功耗。
通过硬件或软件控制时钟使能信号。

外设管理:关闭未使用外设的时钟。

软件:通过寄存器配置控制时钟使能。

时钟映射到引脚

动态时钟频率调度

配置时钟主频变频时,需要注意不要影响其它模块,比如SPI、UART、USB、ADC、PWM

  • 暂停关键操作,暂停DMA传输、外设通信等
  • 设置PLL、分频器等参数,生成目标频率
  • 切换系统时钟源,等待时钟稳定
  • 重新配置外设时钟,比如SPI

示例,如下uart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static void clock_critical_enter(void)
{

}

static void clock_critical_exit(void)
{
uart_update_set_baud(update_baudrate);
}
// 将入口函数,和退出函数 指针注册到时钟critical处理的相关section中
CLOCK_CRITICAL_HANDLE_REG(uart_update, clock_critical_enter, clock_critical_exit)


// 当时钟变化时,会轮询执行所有注册在相应段的函数。确保外设的时钟不会受到系统时钟变化的影响

时钟校准与补偿

思考与拓展

有源晶振和无源晶振分别是?为什么外部不直接使用高频晶振?为什么通常都是先倍频再分频的配置方式?

软件如何检测外部晶振是否配置成功?如何排查晶振问题?

晶振就绪硬件位检测

为什么SoC一般都采用动态频率调整的调度方式?

功耗优化
性能优化
温度管理
支持多种工作模式

什么场景下可以省掉外部晶振器件?

没有高精度、高频率的模块工作时,可以省掉外部晶振器件。比如不使用USB、蓝牙、WIFI等模块时。

时钟与指令周期的关系?

时钟周期、指令周期、机器周期、总线周期

参考站点