1. 项目概述与PLL核心价值
在嵌入式系统,尤其是像TMS320C6472这样的高性能多核DSP设计中,时钟系统是整个芯片的“心跳”。它决定了处理器内核、高速外设以及内存接口能否协调、稳定且高效地运行。而锁相环(PLL)正是这颗“心脏”的起搏器与变频器。我接触过不少项目,初期调试的“玄学”问题,比如程序跑飞、数据采集时序错乱、以太网丢包,追根溯源,十有八九都和时钟配置不当有关。因此,吃透DSP的PLL控制器,绝非纸上谈兵,而是确保系统稳定性的第一道,也是最重要的一道防线。
TMS320C6472-HiRel作为一款面向高可靠性应用的多核DSP,其时钟架构设计得相当精细。它内部集成了三个独立的软件可编程PLL控制器:PLL1、PLL2和PLL3。这三个PLL各司其职,PLL1通常用于产生CPU内核及主要外设的系统时钟(SYSCLK),PLL2专为千兆以太网控制器(EMAC)提供多种速率的参考时钟,PLL3则专门驱动DDR2内存接口时钟。这种分离式设计的好处显而易见:不同时钟域可以独立配置、启停和进行功耗管理,互不干扰,极大地提升了系统的灵活性和能效。
然而,灵活性也带来了复杂性。官方数据手册(Datasheet)和用户指南(User‘s Guide)虽然给出了寄存器的位域定义,但如何将这些冰冷的寄存器位映射成一套安全、高效的时钟配置流程,中间隔着大量的实践细节和“坑”。比如,修改倍频分频系数后,为什么要执行一个“GO”操作?PLL的锁定时间(Lock Time)到底需要等待多久?直接操作保留位(Reserved Bits)会导致什么后果?这些问题,手册往往不会展开细说,却直接关系到系统能否正常启动。
本文将基于TI官方文档SPRS696B,结合我多年在DSP底层驱动开发中的实际经验,深入拆解TMS320C6472的PLL控制器,特别是其寄存器配置的精髓与时钟管理的实操要点。我会带你超越手册的简单描述,不仅看懂每个寄存器位是干什么的,更要理解为什么要这么设计,以及在实际编程中如何安全、正确地去操作它们。无论你是正在评估C6472的硬件工程师,还是负责底层BSP开发的软件工程师,这篇文章都将为你提供一份可直接参考的“避坑指南”和配置蓝图。
2. PLL控制器架构与核心寄存器全景
在深入每个寄存器之前,我们必须先建立起对C6472 PLL控制器整体架构的认知。这有助于理解各个寄存器在时钟产生链路中所处的位置和扮演的角色。你可以把每个PLL控制器想象成一个高度可配置的时钟合成“黑盒”,它接收一个外部的参考时钟输入(CLKIN),经过内部一系列处理,最终输出一个或多个系统时钟(SYSCLK)。
这个“黑盒”内部的核心处理链条通常是:输入参考时钟 → [可选PLL旁路] → PLL倍频模块 → 后分频器(Post-Divider) → 输出时钟。而软件可编程的寄存器,就是用来控制这个链条上每一个开关和齿轮的“控制面板”。
C6472的三个PLL控制器(PLL1, PLL2, PLL3)在寄存器视图上高度相似,但功能和配置细节有显著区别。PLL1功能最全,支持动态调整倍频和分频;PLL2固定20倍频,主要为以太网产生特定频率的时钟;PLL3也固定20倍频,专供DDR2内存。因此,虽然寄存器名字一样,但操作它们时的约束条件截然不同。
下表概括了三个PLL控制器的核心功能与关键差异,这是后续所有配置操作的基础:
| PLL控制器 | 主要用途 | 输入时钟 (CLKIN) | 固定倍频 | 可配置分频器 | 输出时钟 (SYSCLK) | 关键特性 |
|---|---|---|---|---|---|---|
| PLL1 | CPU内核及主要外设主时钟 | CLKIN1 | 软件可配 (x10 ~ x32) | 是 (PLLDIV10) | SYSCLK1~SYSCLK10 | 支持动态频率缩放, 功能最完整 |
| PLL2 | 千兆以太网 (EMAC) 时钟 | CLKIN2 | 固定 x20 | 是 (PLLDIV1~6) | SYSCLK13~SYSCLK18 | 为RGMII/GMII提供125MHz/25MHz/2.5MHz等时钟 |
| PLL3 | DDR2内存接口时钟 | CLKIN3 | 固定 x20 | 无 (直接输出) | DDR2 Clock | 输出频率直接为PLLOUT, 需严格满足DDR2时序要求 |
注意:手册中反复强调了一个重要原则:C6472只支持文档中明确列出的寄存器和位域。对于标记为“Reserved”的地址或位,绝对不要进行写操作,甚至不要依赖其读出的值。这些保留位可能用于芯片测试或未来型号,随意写入可能导致不可预测的行为,包括时钟紊乱、外设失效甚至芯片锁死。这是底层编程的第一铁律。
2.1 寄存器内存映射与访问原则
三个PLL控制器在DSP的内存空间中拥有各自独立的地址窗口。以PLL1控制器为例,其寄存器基地址通常位于类似0x029C 0000的地址(具体需参考芯片的内存映射表)。PLL2和PLL3的基地址则依次偏移。每个控制器内部的寄存器,如PID、PLLCTL、PLLM等,都相对于这个基地址有一个固定的偏移量。
访问这些寄存器时,必须使用32位的读写操作。在C代码中,我们通常通过定义好的宏或结构体指针来访问。例如:
// 假设 PLL1 控制器基地址已定义 #define PLL1_BASE (0x029C0000) typedef volatile struct { uint32_t PID; // 0x00: 外设ID寄存器 uint32_t RESERVED[63]; // 0x04-0xFC: 保留区 uint32_t PLLCTL; // 0x100: PLL控制寄存器 // ... 其他寄存器 } PLL1_Regs; PLL1_Regs *pll1 = (PLL1_Regs *)PLL1_BASE;在操作寄存器时,务必遵循“读-修改-写”的原则,特别是对于那些只包含少数有效位的寄存器。不要直接赋值,以免意外修改了保留位。例如,设置PLLCTL的某个位,应该这样操作:
uint32_t reg_val = pll1->PLLCTL; // 先读取当前值 reg_val &= ~(1 << 1); // 清除PLLPWRDN位(假设位1) reg_val |= (0 << 1); // 设置PLLPWRDN为0(退出省电模式) pll1->PLLCTL = reg_val; // 写回3. PLL1控制器寄存器详解与配置流程
PLL1是整个系统的时钟核心,其配置最为灵活,也最容易出错。我们将按照一个典型的时钟初始化流程,来逐一剖析关键寄存器。
3.1 身份识别:PID寄存器
PID寄存器是一个只读的常量寄存器,用于标识此外设模块的类型、类别和修订版本。对于PLL1控制器,其值通常是固定的(例如TYPE=0x01, CLASS=0x08, REV=0x0D)。这个寄存器在驱动程序中主要用途是进行模块存在性校验。在系统启动初期,特别是进行板级支持包(BSP)的通用性设计时,读取此寄存器并与预期值比较,可以确认芯片型号或硅片版本是否与驱动兼容。虽然在实际产品中我们可能不会每次都检查,但在调试阶段,这是一个快速排除硬件连接或地址映射错误的好方法。
3.2 总控制台:PLLCTL寄存器
PLLCTL是PLL的“总开关”,控制着PLL最基本的工作状态。理解它的每一个有效位至关重要。
PLLEN (位0) - PLL使能位:这是决定时钟路径的关键。
0-旁路模式。输入参考时钟CLKIN1直接绕过PLL倍频电路,经后续分频器后输出。此模式通常用于系统初始化和低功耗状态,或者当外部可以提供足够高的时钟时。此时PLL本身不工作,无锁定过程。1-PLL模式。时钟路径经过PLL,输出频率为CLKIN1 * (PLLM+1) / (分频比)。这是正常工作模式。- 操作心得:在切换PLLEN之前,必须确保PLL已经稳定锁定。常见的启动顺序是:先让PLL工作在旁路模式,配置好倍频系数PLLM,然后释放PLL复位(PLLRST=0),等待足够的锁定时间,最后才将PLLEN从0切到1。直接从不稳定状态切入PLL模式,会导致输出时钟紊乱。
PLLPWRDN (位1) - PLL省电模式选择位:
0- PLL处于工作状态。1- PLL进入省电状态,内部模拟电路(如压控振荡器VCO)被关闭。- 注意事项:在进入省电模式前,必须先将PLLEN设为0(进入旁路模式)。否则,正在使用中的PLL被突然断电,会导致系统时钟瞬间丢失,引发灾难性后果。从省电模式唤醒时,也需要先配置好PLL,等待锁定,再切换PLLEN。
PLLRST (位3) - PLL复位位:
0- 释放PLL复位。1- 断言PLL复位,将PLL内部状态机复位到初始状态。- 关键时序:在修改了倍频系数(PLLM)或需要重新锁定PLL时,需要先对其进行复位。手册给出了复位时间要求:
PLL Reset Time = 128 * CLKIN1周期。例如,CLKIN1为50MHz(周期20ns),则需至少等待128 * 20ns = 2.56μs。在软件中,通常用一个简单的延时循环来满足这个时间。
保留位处理:PLLCTL中有大量保留位(如位31:8, 7, 6, 5:4, 2)。必须严格遵守手册要求。例如,位5:4在PLL1中必须写为
00,而在PLL3中则必须写为10。位7必须保持为0。这些保留位很可能与芯片内部的模拟电路校准或测试模式相关,错误配置可能导致PLL无法锁定或输出频率不准。
3.3 频率倍增器:PLLM寄存器
PLLM寄存器(位4:0)定义了PLL的倍频系数N,计算公式为:输出频率 = CLKIN1频率 × (PLLM + 1)。其中,PLLM的可编程范围为0x09到0x1F,即十进制9到31。这意味着倍频系数N的范围是10到32。
为什么是N+1?这种设计在数字逻辑中很常见,将“0”作为一个有效的偏移量,使得寄存器值0x00(此处不支持)对应倍频比1,而我们的可编程范围从10开始。在计算时务必注意这个“+1”。
配置实例:假设外部晶振CLKIN1为50MHz,我们希望CPU内核运行在700MHz。
- 计算所需倍频系数:N = 700MHz / 50MHz = 14。
- 计算PLLM值:PLLM = N - 1 = 13。
- 将十进制13转换为十六进制:0x0D。
- 因此,需要向PLLM寄存器的低5位写入0x0D。
警告:绝对不能在PLL运行过程中(PLLEN=1)直接修改PLLM寄存器!这会导致PLL失锁,输出频率跳变,系统几乎必然崩溃。正确的修改流程是:1) 切换至旁路模式(PLLEN=0);2) 复位PLL(PLLRST=1);3) 写入新的PLLM值;4) 释放复位(PLLRST=0);5) 等待锁定时间;6) 重新使能PLL模式(PLLEN=1)。
3.4 时钟分频与使能:PLLDIV10寄存器
PLL倍频后产生的高频时钟,需要通过分频器产生不同频率的SYSCLK供各个子系统使用。PLLDIV10寄存器控制着SYSCLK10的分频比和使能。
RATIO (位4:0) - 分频比:此字段定义分频系数D,范围为2(0x2)到31(0x1F),对应的分频比为D+1。即写入0x2,实际分频比为3;写入0x1F,实际分频比为32。特别注意,值0x0和0x1是保留的,不能使用。SYSCLK10的频率 = PLL输出频率 / (RATIO + 1)。
DnEN (位15) - 分频器使能:
0- 关闭分频器,SYSCLK10无输出。1- 开启分频器。- 应用场景:对于不使用的时钟域,可以关闭其分频器以降低动态功耗。在动态改变分频比(DVFS)时,也需要配合后续的GO操作。
3.5 安全切换命令:PLLCMD与PLLSTAT寄存器
这是PLL1控制器实现时钟频率动态切换(DFS)的核心机制,也是最容易出错的地方。其设计目的是保证在改变分频比时,系统时钟能够平滑、无毛刺地过渡。
- PLLCMD (位0 - GOSET):GO操作命令位。当我们需要应用对PLLDIV10分频比的新配置时,不是写完后立即生效,而是需要向此位写1,发起一个“GO”命令。
- PLLSTAT (位0 - GOSTAT):GO操作状态位。这是一个只读位,用于指示GO操作是否正在进行中。
0:GO操作未进行,SYSCLK分频比稳定。1:GO操作正在进行中,SYSCLK分频比正在切换。
完整的动态分频比修改流程如下:
- 检查状态:读取PLLSTAT寄存器,确保GOSTAT位为0。如果为1,需要等待其完成,否则新的GO命令可能被忽略或导致错误。
- 修改配置:向PLLDIV10寄存器写入新的分频比(RATIO字段)。同时,硬件会自动将DCHANGE寄存器中对应的标志位(例如SYSCLK10位)置1,表示该时钟的分频比已发生更改,等待应用。
- 发起切换:向PLLCMD寄存器的GOSET位写1,发起GO操作。
- 等待完成:轮询PLLSTAT寄存器的GOSTAT位,直到其从1变回0。在此期间,硬件会安全地将SYSCLK10切换到新的频率,并可能进行相位对齐(如果使能了相关功能)。
- 清除标志:GO操作完成后,DCHANGE寄存器中的相应标志位会被硬件自动清除。
核心要点:GO操作是针对分频比(PLLDIVn)的更改,而不是倍频比(PLLM)的更改。修改PLLM必须遵循前述的“旁路-复位-配置-锁定-使能”流程。GO机制的存在,使得在不影响PLL本身锁定的情况下,动态调整各个时钟域的频率成为可能,这对于实现基于负载的DVFS(动态电压频率调整)至关重要。
3.6 变更记录与状态查询:DCHANGE与SYSTAT寄存器
- DCHANGE寄存器:这是一个状态寄存器,用于记录哪个SYSCLK的分频比被修改了。当我们写PLLDIV10时,硬件会自动将DCHANGE[9](SYSCLK10位)置1。GO操作只会对那些标志位为1的时钟进行分频比切换。这允许多个时钟分频器被依次修改,然后通过一次GO操作统一生效。在GO操作完成后,硬件会清除相应的位。
- SYSTAT寄存器:这是一个只读寄存器,实时反映各个SYSCLK(SYSCLK1~SYSCLK10)的开关状态(1为开启,0为关闭)。在调试时,读取此寄存器可以验证时钟门控逻辑是否正确,或者确认某些外设的时钟是否已按预期使能。
4. PLL2与PLL3控制器的特殊性与配置要点
PLL2和PLL3的寄存器视图与PLL1类似,但因其固定用途,配置上更简单,约束也更强。
4.1 PLL2:为千兆以太网量身定做
PLL2的倍频系数固定为20倍。其输入时钟CLKIN2必须为25MHz。这是由以太网协议(尤其是RGMII接口)的时钟要求决定的。PLL2输出固定为500MHz(25MHz * 20),然后通过6个独立的分频器(PLLDIV1~PLLDIV6)产生6组特定的时钟:
- SYSCLK13: 250MHz (用于RGMII0 1000Mbps模式)
- SYSCLK14: 50MHz 或 125MHz (用于RGMII0 100Mbps和GMII 1000Mbps模式)
- SYSCLK15: 5MHz (用于RGMII0 10Mbps模式)
- SYSCLK16: 250MHz (用于RGMII1 1000Mbps模式)
- SYSCLK17: 50MHz (用于RGMII1 100Mbps模式)
- SYSCLK18: 5MHz (用于RGMII1 10Mbps模式)
关键约束:手册Table 7-37给出了PLLDIVn寄存器的默认值。例如,在大多数配置下(MACSEL0[2:0] ≠ 1),PLLDIV1的RATIO默认值为9,这意味着分频比为10,从而得到500MHz / 10 = 50MHz?不对,这里需要仔细计算。SYSCLK13要求是250MHz,而PLL2输出是500MHz,所以所需分频比是2。但默认RATIO是9(分频比10),这看起来矛盾。
这里隐藏了一个重要信息:PLL2的分频器可能有一个前置或后置的固定分频。从手册框图(Figure 7-25)看,SYSCLK13路径上有一个“/2”的分频器。因此,实际计算是:PLLOUT (500MHz) -> /2 -> 250MHz -> PLLDIV1分频器。而PLLDIV1的默认分频比是10,那么最终频率是250MHz / 10 = 25MHz?这仍然不对。
实操解读:对于PLL2,强烈建议不要修改PLLDIVn寄存器的默认RATIO值。以太网控制器的时钟需求非常精确,TI已经通过硬件逻辑和默认配置,使得在正确的CLKIN2(25MHz)输入下,这些分频器能自动产生符合协议的时钟。工程师的任务是:
- 确保提供稳定的25MHz时钟给CLKIN2。
- 正确配置PLLCTL,释放PLL2复位(PLLRST=0),并使能PLL(PLLEN=1)。
- 等待PLL2锁定(Lock Time = 2000 * CLKIN2周期 = 80μs)。
- 保持PLLDIVn为默认值,并确保其使能位(DnEN)为1。
任何对PLLDIVn比率的修改,都必须基于对以太网控制器时钟树的彻底理解,否则极易导致网络通信失败。
4.2 PLL3:DDR2内存的专用时钟源
PLL3最为简单,它没有可配置的分频器,输出时钟直接用于DDR2内存接口。其倍频系数也固定为20倍。关键点在于其输入频率范围:CLKIN3必须在20MHz到26.66MHz之间。根据所需的DDR2时钟频率(PLLOUT),可以反推CLKIN3:
- 若需要DDR2时钟为400MHz,则CLKIN3 = 400MHz / 20 = 20MHz。
- 若需要DDR2时钟为533.33MHz,则CLKIN3 = 533.33MHz / 20 = 26.666MHz。
配置流程极其简洁:
- 根据DDR2速率要求,提供对应频率的CLKIN3。
- 配置PLLCTL寄存器。特别注意:PLL3的PLLCTL[5:4]两位必须写为
10(二进制),这与PLL1不同。 - 释放复位,使能PLL,等待锁定(Lock Time = 2000 * CLKIN3周期)。
- PLL3没有PLLDIVn和GO操作,使能后输出时钟即生效。
DDR时钟稳定性的重要性:DDR2接口对时钟的抖动(Jitter)和稳定性要求极高。PLL3的锁定时间必须得到充分保证。在初始化DDR2控制器之前,必须确认PLL3已完全锁定且稳定。通常会在软件中插入远大于理论锁定时间的延时,或者通过查询PLL状态位(如果支持)来确认。
5. 电气特性与时钟质量保障
寄存器配置是软件行为,而时钟信号的质量则是硬件设计的结果。两者必须协同,系统才能稳定。手册第7.8.4和7.9.4节给出了CLKIN1/2/3的时序要求,这是硬件工程师设计时钟电路,以及软件工程师评估时钟源的依据。
以CLKIN1为例(Table 7-29):
- 周期时间 (tc(CLKIN1)):20ns 到 80ns,对应频率12.5MHz 到 50MHz。这是输入时钟的频率范围。
- 高/低脉冲宽度 (tw):必须大于周期的40%。这意味着时钟占空比应在40%~60%之间,最好是50%。
- 过渡时间 (tt):最大1.2ns。指时钟信号上升沿和下降沿的时间,要求边沿陡峭。过慢的边沿会导致PLL无法准确识别时钟沿,引起抖动甚至失锁。
- 周期抖动 (tJ):峰峰值最大100ps。抖动是时钟周期的不确定性。过大的抖动会被PLL倍频后放大,导致系统时钟抖动超标,影响高速接口的时序裕量。
给硬件工程师的建议:
- 优先选择低抖动、高稳定性的有源晶振或时钟发生器作为CLKIN源。
- 时钟走线应作为高速信号处理,保持阻抗连续,远离噪声源,并做好端接。
- 电源去耦至关重要。PLL的模拟电源(AVDD)必须干净、稳定,通常需要单独的LDO供电和大量的滤波电容。
给软件工程师的检查清单:
- 在初始化PLL前,确认硬件提供的时钟频率在手册规定范围内。
- 配置PLL时,严格遵守各项时序要求:复位等待时间、锁定等待时间。
- 在关键任务(如启动高速数据传输)前,可以考虑重新校准或验证时钟频率(如果芯片有相关功能)。
6. 实战配置流程与常见问题排查
结合以上所有知识,我们可以总结出一套完整的、稳健的PLL1初始化流程(以从50MHz晶振产生700MHz CPU时钟和100MHz SYSCLK10为例):
步骤1:硬件与基础检查
- 确认硬件上CLKIN1引脚连接了稳定的50MHz时钟源。
- 软件上,映射并访问PLL1控制器基地址。
- (可选)读取PID寄存器,验证外设识别正确。
步骤2:配置PLL倍频系数(进入旁路模式操作)
- 读取PLLCTL,确保PLLEN=0(旁路模式)。如果不是,先写入0。
- 设置PLLRST=1,复位PLL。
- 等待至少128个CLKIN1周期(约2.56μs)。
- 计算并写入PLLM寄存器。目标700MHz, N=14, PLLM=13 (0x0D)。
- 设置PLLRST=0,释放复位。
- 等待PLL锁定时间。这是最容易忽略的一步!锁定时间至少为2000个CLKIN1周期(约40μs)。在实际代码中,我通常会等待100μs以上,甚至1ms,以确保绝对稳定。
// 示例代码片段:配置PLLM pll1->PLLCTL &= ~(1 << 0); // 确保PLLEN=0, 旁路模式 pll1->PLLCTL |= (1 << 3); // 设置PLLRST=1, 复位PLL delay_cycles(128 * CLKIN1_CYCLES_PER_US); // 简单延时函数,等待复位完成 pll1->PLLM = 0x0D; // 写入倍频系数 pll1->PLLCTL &= ~(1 << 3); // 设置PLLRST=0, 释放复位 delay_us(100); // 等待PLL锁定, 远大于理论值40us步骤3:配置系统时钟分频
- 配置PLLDIV10寄存器。目标SYSCLK10=100MHz, PLL输出为700MHz,分频比D=7。RATIO = D - 1 = 6 (0x06)。同时确保DnEN=1。
- 此时,由于PLLEN仍为0,系统时钟仍来自CLKIN1的直接分频(如果分频器使能),频率较低。
步骤4:切换到PLL模式并应用分频
- 将PLLCTL的PLLEN位设置为1,切换到PLL模式。
- 注意:此时SYSCLK10的分频比还是旧的(如果之前有配置)。我们需要发起GO操作来应用新的分频比。
- 检查PLLSTAT的GOSTAT位,等待其为0。
- 向PLLCMD的GOSET位写1,发起GO操作。
- 轮询PLLSTAT的GOSTAT位,直到其变为0,表示频率切换完成。
// 示例代码片段:切换至PLL模式并应用新分频 pll1->PLLDIV10 = (1 << 15) | (0x06 << 0); // DnEN=1, RATIO=6 pll1->PLLCTL |= (1 << 0); // 设置PLLEN=1, 进入PLL模式 while (pll1->PLLSTAT & 0x1); // 等待任何正在进行的GO操作完成 pll1->PLLCMD = 0x1; // 发起GO操作 while (pll1->PLLSTAT & 0x1); // 等待GO操作完成常见问题与排查技巧:
系统无法启动,或启动后随机死机
- 排查:首先检查PLL锁定时间是否足够。尝试显著增加锁定延时(如到10ms)。其次,用示波器测量CLKIN1和SYSCLKOUT(如果引脚可用)的波形,看频率是否正确,抖动是否过大。
- 检查寄存器:确认PLLCTL、PLLM、PLLDIV10的值是否与预期一致。特别注意保留位是否被误写。
动态频率切换(DFS)时系统挂起
- 排查:99%的原因是未遵循GO操作流程。严格检查:a) 修改PLLDIVn后,是否等待了GOSTAT=0? b) 发起GOSET=1后,是否等待了GOSTAT从1变回0? c) 是否在PLL模式(PLLEN=1)下进行GO操作?
- 技巧:在GO操作前后读取DCHANGE寄存器,看对应位是否被置1并在完成后清0,这有助于确认硬件是否正确识别了配置变更。
以太网(PLL2)或DDR(PLL3)工作不稳定
- 排查:确认输入时钟CLKIN2是否为精确的25MHz,CLKIN3是否在20-26.66MHz范围内。检查电源噪声,尤其是PLL的模拟电源AVDD。
- 对于PLL2:确认没有修改PLLDIVn的默认分频比。确认PLL2的锁定时间已满足。
- 对于PLL3:确认PLLCTL[5:4]被正确写为
10。
功耗高于预期
- 排查:检查未使用的外设时钟是否通过SYSTAT寄存器确认已关闭(SYSnON=0)。对于暂时不用的PLL(如系统中未使用以太网),可以考虑将PLL2的PLLPWRDN置1,并关闭其输入时钟,以节省功耗。
调试心得:在早期板卡调试阶段,不要急于让所有PLL全速运行。可以先将所有PLL配置在较低的、保守的频率下,让系统先“跑起来”。然后,逐步提高频率,同时用示波器监测电源纹波和时钟质量。使用DSP的仿真器,可以实时查看和修改寄存器,是排查PLL配置问题的利器。最后,所有稳定的配置参数,都应该固化到你的系统初始化代码中,并做好详尽的注释。时钟是系统的基石,在这部分的代码上多花一分心思,就能为后续的稳定性省去十分的麻烦。