TMS320F2807x时钟系统深度解析:从PLL配置到多时钟域实战
1. 项目概述
在嵌入式开发领域,尤其是涉及实时控制、电机驱动或数字电源的场合,德州仪器(TI)的C2000系列微控制器是许多工程师的首选。而TMS320F2807x作为该系列中的高性能成员,其复杂且灵活的时钟系统,既是其强大性能的基石,也是新手工程师最容易“踩坑”的地方。时钟配置不当,轻则导致外设通信失败、ADC采样时序错乱,重则引发系统运行不稳定甚至无法启动。我见过太多项目,硬件电路设计精良,软件算法逻辑清晰,最终却卡在了一个不起眼的时钟配置寄存器上,调试过程苦不堪言。
本文将以TMS320F2807x为例,深入拆解其时钟系统的“五脏六腑”。我们不会止步于数据手册的简单翻译,而是结合我多年在电机控制和数字电源项目中的实战经验,从最底层的振荡源开始,一步步剖析PLL的配置玄机、各个时钟域的划分逻辑,直到如何实现可靠的缺失时钟检测(MCD)。我的目标是,让你读完这篇文章后,不仅能看懂手册里的框图,更能胸有成竹地根据自己项目的需求(比如需要跑多高的主频、是否要用USB或CAN),独立完成一套稳定、高效的时钟配置方案,避开那些我当年踩过的“坑”。
2. 时钟系统整体架构与设计思路
TMS320F2807x的时钟系统,其设计核心思想是“分而治之,按需供给”。它不是一个简单的单一时钟树,而是一个由多个独立又相互关联的时钟路径构成的网络。理解这个架构,是进行任何配置的前提。
2.1 核心设计哲学:为何如此复杂?
你可能会问,一个单片机,给一个主时钟不就行了吗?为什么搞得这么复杂?这背后是应对不同应用场景的权衡:
- 性能与功耗的平衡:CPU和高速外设(如PWM、ADC)需要高频时钟以实现高精度控制;而低速通信外设(如SCI、SPI)在低频下工作即可,使用独立的低频时钟域可以降低动态功耗。
- 精度与成本的权衡:片内振荡器(INTOSC)成本低、启动快,但精度和稳定性较差(典型误差在±1%到±5%)。对于CAN、USB这类对时序抖动(Jitter)和频率精度要求极高的通信协议,必须使用高精度的外部晶振。
- 安全与可靠性的需求:在工业、汽车等关键应用中,时钟源的失效可能导致灾难性后果。因此,需要备份时钟源(INTOSC1)和缺失时钟检测(MCD)机制,在主时钟失效时无缝切换,维持系统基本功能或安全关机。
- 模块独立性与灵活性:USB模块需要固定的60MHz时钟,而CPU主频可能根据运算负载动态调整。独立的辅助PLL(AUXPLL)使得USB时钟不受系统主频变化的影响,两者可以独立配置。
基于这些考量,F2807x的时钟架构被清晰地划分为几个层次:时钟源 -> 衍生时钟 -> 时钟域。接下来,我们就从源头开始,逐一解析。
2.2 时钟信号流全景图
在深入每个模块之前,我们先在心里构建一张简化的信号流图(注意,这不是官方框图,而是便于理解的逻辑视图):
[时钟源层] INTOSC2 (10MHz) ---+ | XTAL (外部晶振) ----+---> MUX --> OSCCLK (主振荡器时钟) | INTOSC1 (10MHz) ---+ | AUXCLKIN (GPIO133) -+---> MUX --> AUXOSCCLK (辅助振荡器时钟) [衍生时钟层] OSCCLK ----> [系统PLL] ----> PLLRAWCLK ----> [分频器] ----> PLLSYSCLK (系统时钟) AUXOSCCLK -> [辅助PLL] ----> AUXPLLRAWCLK -> [分频器] ----> AUXPLLCLK (USB时钟,固定60MHz) [时钟域层] PLLSYSCLK --------------------------------------> CPUCLK (CPU核心时钟) | +-> [分频器] -> SYSCLK ----------------> PERx.SYSCLK (高速外设时钟,如PWM, ADC) | | | +-> [分频器] -> LSPCLK ------> PERx.LSPCLK (低速外设时钟,如SCI, SPI) | +---------------------------------------> PLLSYSCLK (系统控制、RAM时钟域)这张图揭示了几个关键点:
- OSCCLK是绝大多数模块的“总水源”。
- PLL是“水泵”,负责将低频水源提升到高压(高频)。
- 分频器是“水龙头”,按需分配不同流速(频率)的水给各个房间(模块)。
- AUXOSCCLK和AUXPLL是独立的“小厨房专用供水系统”,专门满足USB模块的苛刻用水(60MHz精准时钟)需求。
理解了这张全景图,我们再深入每个部分,就会清晰很多。
3. 四大时钟源深度解析与选型实战
时钟源是整个系统的“心脏”。F2807x提供了四颗“心脏”,你需要根据系统的“体能要求”(性能、成本、可靠性)来选择用哪一颗,或者哪几颗协同工作。
3.1 主内部振荡器(INTOSC2):快速启动的备选方案
INTOSC2是一个片内集成的10MHz RC振荡器。它的最大优点是“开机即有”。在芯片上电复位(POR)后,系统默认就使用INTOSC2作为OSCCLK。这意味着你的BootROM代码和最初的初始化程序,在外部晶振还未稳定起振时,就已经可以运行了。
但是,它的缺点非常明显且关键:精度太差。数据手册通常只会给出一个很宽泛的频率范围(例如±5%)。这个精度对于普通的GPIO翻转、简单的延时循环或许够用,但对于以下两类应用是绝对不行的:
- 通信协议:CAN总线对位定时要求极其严格,通常需要优于0.1%的时钟精度以确保在恶劣电磁环境下也能可靠通信。USB协议更是要求高速模式(12 Mbps)下时钟精度优于±0.25%。INTOSC2的误差远超此限。
- 需要精确时序的外设:例如,当你希望ePWM模块产生一个精确的100kHz开关信号时,如果系统时钟本身就有±5%的误差,那么输出频率的误差也会在这个量级,这对于电源环路控制等应用是不可接受的。
实操心得:在我的项目中,INTOSC2通常只扮演两个角色:1) 上电初始化阶段的“临时心脏”,让我可以配置GPIO、初始化Flash等待状态等;2) 作为外部晶振失效后,MCD机制切换到的“安全心脏”,保证系统不会彻底死机,至少能执行一些故障安全操作。永远不要将它用于最终产品中需要精确时序的场合。
3.2 备份内部振荡器(INTOSC1):沉默的守护者
INTOSC1是另一个独立的10MHz片内振荡器,它与INTOSC2在物理上是分离的。在正常情况下,它非常“低调”,只做两件事:
- 为看门狗定时器(Watchdog Timer)提供时钟(WDCLK)。
- 作为缺失时钟检测(MCD)电路的参考时钟。
它的核心价值体现在“主时钟失效”的危急时刻。当MCD电路检测到OSCCLK(可能来自INTOSC2或XTAL)丢失时,硬件会自动、无缝地将系统时钟切换到INTOSC1。此时,虽然频率可能不准,但系统得以继续运行,可以触发NMI中断,安全地关闭功率管、保存关键数据或进入安全状态。
手动切换功能:除了作为备份,你也可以通过配置CLKSRCCTL1寄存器,手动将OSCCLK或AUXOSCCLK切换到INTOSC1。这在调试阶段非常有用,例如,你可以强制系统使用一个已知频率(尽管不准)的内部时钟,来排除外部晶体电路的问题。
3.3 外部振荡器(XTAL):高精度应用的基石
这是产品化应用中的“主力心脏”。XTAL时钟源通过专用的X1和X2引脚接入,支持三种模式:
| 模式 | 连接方式 | 特点与适用场景 |
|---|---|---|
| 单端有源时钟 | 外部有源晶振(OSC)的输出脚接X1,X2悬空。 | 最省心。外部有源晶振通常集成负载电容和起振电路,输出稳定、驱动能力强,受PCB布局影响小。适合对可靠性要求高、不想在时钟电路上花费调试时间的项目。成本稍高。 |
| 外部晶体 | 无源晶体跨接在X1和X2之间,并搭配两个负载电容(CL1, CL2)接地(VSSOSC)。 | 最常见、最经济的选择。需要仔细计算并匹配负载电容(CL),其值由晶体参数和芯片内部等效电容共同决定。CL不匹配会导致频率偏移甚至不起振。 |
| 外部谐振器 | 陶瓷谐振器跨接在X1和X2,一端接地(VSSOSC)。 | 类似于晶体,但精度和稳定性通常低于石英晶体,成本也更低。适用于对时钟精度要求不苛刻的消费类产品。 |
关键配置位:XTALOFF无论使用以上哪种外部时钟模式,必须将CLKSRCCTL1寄存器中的XTALOFF位清零(设置为0)。这个位的作用是启用芯片内部连接X1/X2引脚的振荡器电路放大器。如果此位为1,外部时钟路径将被禁用,信号无法进入芯片。
踩坑记录:我曾遇到一个诡异的故障,系统偶尔启动失败。排查良久,最后发现是初始化代码中在配置PLL前,忘记将
XTALOFF位清零。这导致芯片试图使用一个不存在的时钟源去锁相环,自然失败。教训是:初始化时钟的第一步,就是确认你的目标时钟源路径是打开的。
3.4 辅助时钟输入(AUXCLKIN):为通信模块专设的“VIP通道”
这是一个非常特殊的时钟输入,位于GPIO133引脚,复用为AUXCLKIN功能。它只接受单端3.3V有源时钟信号。
它的设计目的非常明确:为CAN和USB模块提供高精度的位时钟(Bit Clock)。
- 对于USB,AUXCLKIN可以作为
AUXOSCCLK的源,经过辅助PLL倍频/分频后,产生精确的60MHz时钟(AUXPLLCLK)给USB模块。 - 对于CAN,每个CAN模块都可以独立配置其位时钟源,可以选择
SYSCLK、XTAL或AUXCLKIN。当系统主频因性能调节而变化时,如果CAN位时钟源自SYSCLK,其波特率也会跟着变,这可能破坏通信。因此,对于稳定性要求高的CAN网络,推荐使用独立的XTAL或AUXCLKIN作为时钟源。
一个重要区别:XTAL和AUXCLKIN虽然都是外部时钟,但XTAL是系统主时钟的源头,影响整个系统;而AUXCLKIN是专门为个别高精度外设服务的“专线”,更加灵活。
4. 衍生时钟:PLL的魔法与配置陷阱
时钟源提供了原始的“频率素材”,而衍生时钟则是通过PLL(锁相环)和分频器“加工”后,真正供给各个模块使用的“成品时钟”。
4.1 系统PLL:CPU性能的引擎
系统PLL以OSCCLK为输入,通过一个可配置的乘法器(支持整数和小数)进行倍频,产生PLLRAWCLK,再经过一个分频器,最终得到PLLSYSCLK(也就是我们常说的系统时钟)。
配置公式是核心:f(PLLSYSCLK) = f(OSCCLK) * (IMULT + FMULT) / PLLSYSCLKDIV
IMULT: 整数乘数(SYSPLLMULT.IMULT),范围请查数据手册。FMULT: 小数乘数(SYSPLLMULT.FMULT),以分数形式表示(如0.5, 0.25)。PLLSYSCLKDIV: 分频系数(SYSCLKDIVSEL.PLLSYSCLKDIV),通常为1, 2, 4等。
配置流程与避坑指南: 官方手册给出了配置步骤,但其中有些“坑”需要特别注意。下面是我总结的稳健配置流程:
- 选择并启用OSCCLK源:首先,通过
CLKSRCCTL1.OSCCLKSRCSEL选择你的时钟源(例如,选择外部晶体)。 - 旁路PLL:在配置PLL参数前,先清除
SYSPLLCTL1.PLLCLKEN,让OSCCLK直接通过,系统暂时运行在低频下。 - 设置分频器为1:将
SYSCLKDIVSEL.PLLSYSCLKDIV设为最小值(通常为1)。这是为了后续切换时,频率变化平滑,避免电流冲击。 - 计算并设置倍频器:根据你想要的CPU频率和输入的
OSCCLK频率,计算IMULT和FMULT。关键一步:同时写入SYSPLLMULT寄存器的IMULT和FMULT字段。这个写操作会自动使能PLL电路。 - 等待PLL锁定:这是一个必须的步骤,但手册里有时语焉不详。PLL从启动到输出稳定频率需要时间。你需要等待
SYSPLLSTS.LOCKS位被硬件置1。通常需要延时数十微秒。绝对不能在锁定前就切换到PLL输出! - 切换时钟源:设置
SYSPLLCTL1.PLLCLKEN = 1,将系统时钟从OSCCLK切换到PLLRAWCLK。 - 调整到最终分频:最后,再将
SYSCLKDIVSEL.PLLSYSCLKDIV设置为你最终需要的分频值。
致命陷阱——VCO频率超限:PLL内部有一个压控振荡器(VCO),
OSCCLK * (IMULT+FMULT)得到的VCO频率必须在数据手册规定的范围内(例如,200MHz 到 500MHz)。即使最终PLLSYSCLK没超CPU最高频率,如果VCO频率超限,PLL可能无法锁定或工作不稳定。计算时务必双重检查。
4.2 辅助PLL:USB的专属时钟工坊
辅助PLL的配置逻辑与系统PLL类似,但它的目标是产生一个**精确的60MHz时钟(AUXPLLCLK)**给USB模块。其源可以是INTOSC2、XTAL或AUXCLKIN。
为什么必须是60MHz?这是USB 2.0全速(12 Mbps)和低速(1.5 Mbps)协议物理层的要求。时钟需要被分频来产生精确的位采样时钟。±0.25%的精度要求,几乎注定必须使用外部高精度晶振作为AUXOSCCLK的源。
配置流程中的特殊步骤: 辅助PLL的配置流程包含一个利用CPU Timer 2进行验证的步骤,这是系统PLL配置所没有的,目的是确保USB时钟的可靠性。
- 配置
AUXOSCCLK源。 - 等待至少2个
AUXOSCCLK周期(软件延时)。 - 配置
AUXPLLMULT和AUXCLKDIVSEL,方法与系统PLL类似。 - 关键验证步骤:将CPU Timer 2的时钟源设置为
AUXPLLCLK,并设置一个已知的超时值。启动Timer 2并轮询其溢出标志。如果在预期时间内标志置位,说明AUXPLLCLK运行正常;否则,需要重新配置PLL。
经验之谈:在同时使用系统PLL和辅助PLL的项目中,务必注意配置顺序。手册中特别提到,如果系统PLL的时钟(CPUCLK)远快于辅助振荡器时钟(AUXOSCCLK),在切换
AUXOSCCLK源和写AUXPLLMULT寄存器之间,即使代码里是两条紧挨着的语句,由于CPU速度太快,也可能在同一个AUXOSCCLK周期内完成,这会导致PLL被意外禁用。安全的做法是,在切换时钟源后,插入一个基于AUXOSCCLK的短暂延时(如循环判断某个计数器),再配置倍频器。
5. 七大时钟域详解与配置要点
衍生时钟最终被分配到不同的“功能区”,这就是时钟域。每个域内的模块共享同一时钟,但可以独立门控(开启/关闭)。
5.1 系统时钟域(PLLSYSCLK):控制核心与内存
这个域的时钟驱动系统控制寄存器、全局共享RAM(GSRAM)、GPIO输入同步和滤波电路,以及NMI看门狗定时器。它虽然叫PLLSYSCLK,但实际上可以选择来自系统PLL的输出,也可以直接来自OSCCLK(旁路PLL)。通过SYSCLKDIVSEL寄存器可以对其进行分频。
注意:PLLSYSCLK在HALT低功耗模式下会被门控(关闭)。
5.2 CPU时钟域(CPUCLK):大脑与私密空间
CPUCLK与PLLSYSCLK同源同频,但它专门供给CPU核心、浮点单元(FPU)、三角函数单元(TMU)、CPU私有RAM(M0, M1, D0, D1)以及Flash封装模块。当CPU进入IDLE、STANDBY或HALT模式时,CPUCLK会被门控以节省功耗,而PLLSYSCLK可能还在运行(HALT模式除外)。
5.3 CPU子系统时钟域(SYSCLK/PERx.SYSCLK):外设大本营
这是最繁忙的时钟域。SYSCLK同样等同于PLLSYSCLK,它被分配给CLA(控制律加速器)、DMA以及绝大多数外设,如ADC、ePWM、eCAP、eQEP、SPI、I2C等。每个外设的时钟(PERx.SYSCLK)都可以通过PCLKCRx(外设时钟控制寄存器)独立开启或关闭,这是精细化管理功耗的关键。
重要细节——ePWM/EMIF时钟分频: 当CPU频率超过100MHz时,ePWM、EMIF1和EMIF2模块的时钟默认会有一个额外的/2分频器生效。这是为了满足这些模块在高频下的时序要求。如果你的CPU频率低于100MHz,可以通过PERCLKDIVSEL寄存器禁用这个额外分频,让这些外设运行在全速,以获得更好的性能(例如,ePWM能有更高的分辨率)。
5.4 低速外设时钟域(LSPCLK/PERx.LSPCLK):节能专区
SCI、SPI、McBSP等串行通信模块的比特率远低于CPU主频。为了让它们工作在合适的频率下并降低功耗,SYSCLK经过一个低速外设定标器(LOSPCP)产生LSPCLK。默认分频系数是/4,可以通过LOSPCP寄存器调整。
同样,每个低速外设的时钟(PERx.LSPCLK)也可以通过PCLKCRx独立门控。
5.5 USB辅助时钟域(AUXPLLCLK):独立精准的VIP通道
如前所述,USB模块需要固定的60MHz时钟。AUXPLLCLK由辅助PLL专门生成,与系统主时钟完全独立。这确保了即使你在动态调整CPU主频以省电,USB通信也不会受到任何影响。
5.6 CAN位时钟:灵活应对网络需求
CAN模块的位时钟可以灵活选择:PERx.SYSCLK、XTAL或AUXCLKIN。选择策略取决于应用:
- 对成本敏感,CAN波特率固定:如果系统主频稳定且CAN波特率不需改变,使用
SYSCLK最方便。 - 高可靠性CAN网络:强烈建议使用独立的
XTAL或AUXCLKIN。这样,即使系统主频因软件bug或低功耗模式发生变化,CAN通信的波特率依然保持精准,避免了整个网络通信瘫痪的风险。配置在CLKSRCCTL2寄存器中完成。
5.7 CPU Timer2时钟(TIMER2CLK):特殊的测量工具
CPU Timer 0和1固定使用SYSCLK。但Timer 2是个“多面手”,它的时钟源可以通过TMR2CLKCTL寄存器选择为SYSCLK、INTOSC1、INTOSC2、XTAL或AUXPLLCLK。
它的主要用途是频率测量或提供独立于系统主频的定时基准。例如,你可以用Timer 2来测量一个外部信号的频率,或者在一个需要恒定时间基准而系统主频可能变化的场景中使用它。
重要限制:如果Timer 2使用的不是SYSCLK,那么SYSCLK的频率必须至少是Timer 2时钟源频率的两倍,以确保芯片内部同步逻辑能正确采样,否则会导致计时错误。
6. 时钟输出(XCLKOUT)与缺失时钟检测(MCD)
6.1 XCLKOUT:把内部时钟“拉出来”看看
调试时,我们常常需要知道芯片内部的时钟到底跑没跑、跑得多快。XCLKOUT功能就是将内部某个时钟信号引到GPIO73引脚上,方便用示波器或逻辑分析仪测量。
配置三步曲:
- 选源:通过
CLKSRCCTL3寄存器,选择你想观察的时钟源(如SYSCLK、PLLRAWCLK等)。 - 分频:通过
XCLKOUTDIVSEL寄存器设置输出分频。因为芯片引脚速度有限,高频时钟直接输出可能失真,需要分频到可测量的范围(如几MHz到几十MHz)。 - 配置GPIO:将GPIO73的复用功能选择为XCLKOUT(通常是Mux通道3)。
调试技巧:在系统启动初期,将XCLKOUT配置为输出
OSCCLK并分频,是验证外部晶体是否成功起振的最直接方法。如果示波器上看不到信号,那么问题很可能出在晶体电路或XTALOFF配置上。
6.2 缺失时钟检测(MCD):系统的“心跳监护仪”
在安全攸关的应用中,时钟失效是必须防范的单一故障点。MCD电路就是为此而生。它持续以高精度的备份时钟INTOSC1为参考,监测主时钟OSCCLK是否“停跳”。
工作原理简述: MCD使用两个计数器:一个由OSCCLK驱动(MCDPCNT),另一个由INTOSC1驱动(MCDSCNT)。OSCCLK每计数溢出一次,就复位一次INTOSC1的计数器。只要OSCCLK正常,INTOSC1的计数器就永远没机会溢出。
一旦OSCCLK丢失或慢到一定程度(低于INTOSC1的1/64),INTOSC1的计数器就会溢出,触发MCD事件:
- 置位
MCLKSTS状态标志。 - 产生
CLOCKFAIL信号,此信号会触发PWM模块的Trip事件(紧急关闭PWM输出)和CPU的NMI(不可屏蔽中断)。 - 硬件自动将系统时钟切换到
INTOSC1,并旁路PLL。 - 系统得以在备份时钟下继续运行,执行NMI中断服务程序,进行故障安全处理。
恢复流程: 检测到故障并处理后,如果需要恢复,软件流程是:
- 先将
OSCCLK的源选择为INTOSC1(此时已是事实,但需配置一致)。 - 写
MCLKCLR位清除故障状态。 - 重新配置并锁定PLL(如果需要)。
- 将
OSCCLK源切换回原来的时钟(如XTAL)。
安全设计考量:MCD的检测时间最长为8192个
INTOSC1周期(约0.82ms)。这意味着从主时钟失效到系统切换至备份时钟,有近1ms的“盲区”。在这段时间里,系统行为是不可预测的。因此,对于极高安全等级的应用,仅靠MCD可能不够,可能需要在外围电路增加额外的硬件看门狗。
7. 实战:从需求到配置的完整案例
理论最终要服务于实践。我们以一个常见的电机控制+USB通信应用为例,梳理完整的时钟配置思路。
项目需求:
- CPU主频:120MHz,以满足复杂的磁场定向控制(FOC)算法。
- 外设:ePWM用于驱动电机(需要高分辨率),ADC用于电流采样,USB用于与上位机通信。
- CAN总线用于与车载网络通信,要求高可靠性。
- 使用20MHz外部晶体作为主时钟源。
配置方案推导:
时钟源选择:
- 系统主时钟(OSCCLK):必须使用20MHz外部晶体(XTAL),以满足CPU高频和CAN精度的要求。
CLKSRCCTL1.OSCCLKSRCSEL = 1(选择XTAL),并确保XTALOFF=0。 - USB辅助时钟(AUXOSCCLK):同样需要高精度,但为了节省一个晶振,我们可以复用同一个20MHz晶体。
CLKSRCCTL2.AUXOSCCLKSRCSEL = 1(选择XTAL)。注意:需要确认芯片数据手册是否支持XTAL同时驱动两个PLL,通常是可以的。 - CAN位时钟:为追求最高可靠性,选择独立的时钟源。由于XTAL已被占用,我们可以使用
AUXCLKIN引脚,外接一个4MHz或8MHz的有源晶振专门给CAN。CLKSRCCTL2中配置CAN模块的时钟源为AUXCLKIN。
- 系统主时钟(OSCCLK):必须使用20MHz外部晶体(XTAL),以满足CPU高频和CAN精度的要求。
系统PLL计算:
- 目标
PLLSYSCLK= 120MHz。 - 源
OSCCLK= 20MHz。 - 尝试方案:先倍频再分频。为了获得干净的120MHz,我们寻找整数倍关系。120 / 20 = 6。因此,设置
IMULT=6,FMULT=0,PLLSYSCLKDIV=1。 - 验证VCO频率:20MHz * 6 = 120MHz。检查数据手册,VCO频率范围假设为100-200MHz,120MHz在范围内,可行。
- 目标
辅助PLL计算:
- 目标
AUXPLLCLK= 60MHz (USB要求)。 - 源
AUXOSCCLK= 20MHz (来自XTAL)。 - 计算:60 / 20 = 3。设置
IMULT=3,FMULT=0,AUXPLLDIV=1。 - 验证VCO频率:20MHz * 3 = 60MHz。同样需要检查是否在辅助PLL的VCO允许范围内。
- 目标
外设时钟分频配置:
- CPU频率为120MHz > 100MHz,因此ePWM和EMIF的默认/2分频器生效。这通常是可以接受的,因为ePWM在60MHz下仍然能提供很高的分辨率。如果需要ePWM全速运行(120MHz),需查阅芯片勘误表,确认在���频率下ePWM模块是否工作正常。
- 低速外设时钟
LSPCLK默认是SYSCLK的1/4,即30MHz。对于SCI、SPI等,这个频率通常足够高,可以通过波特率寄存器进一步分频得到所需的通信速率。
初始化代码流程(关键步骤):
// 1. 启用外部晶体振荡器电路 ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF = 0; // 2. 选择OSCCLK源为XTAL ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 1; // 选择XTAL DELAY_US(100); // 等待晶体起振稳定,时间参考晶体手册 // 3. 配置系统PLL (旁路 -> 设置 -> 锁定 -> 切换) ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0; // 旁路PLL ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = 0; // 分频设为1 // 设置倍频器,同时写IMULT和FMULT会自动使能PLL ClkCfgRegs.SYSPLLMULT.all = (6 << 8) | 0; // IMULT=6, FMULT=0 while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1) { } // 等待PLL锁定 ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1; // 切换到PLL输出 // 此时系统时钟已为120MHz // 4. 配置辅助PLL (用于USB) ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 1; // AUXOSCCLK也选择XTAL DELAY_US(10); // 重要!等待AUXOSCCLK稳定 ClkCfgRegs.AUXPLLMULT.all = (3 << 8) | 0; // IMULT=3, FMULT=0 while(ClkCfgRegs.AUXPLLSTS.bit.LOCKS != 1) { } // 等待辅助PLL锁定 ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 1; // 启用辅助PLL输出 // 5. 配置CAN时钟源为AUXCLKIN (假设已连接4MHz有源晶振到GPIO133) // 首先配置GPIO133为AUXCLKIN功能 GpioCtrlRegs.GPBMUX2.bit.GPIO133 = 3; // 具体Mux值查手册 ClkCfgRegs.CLKSRCCTL2.bit.CANA_BITCLKSRCSEL = 2; // 选择AUXCLKIN // 注意:还需要在CAN模块初始化中,根据此外部时钟频率计算并设置正确的波特率预分频器。 // 6. (可选) 启用XCLKOUT用于调试 ClkCfgRegs.CLKSRCCTL3.bit.XCLKOUTSEL = 0; // 选择SYSCLK输出 ClkCfgRegs.CLKSRCCTL3.bit.XCLKOUTDIV = 4; // 120MHz / 16 = 7.5MHz,方便测量 GpioCtrlRegs.GPAMUX1.bit.GPIO73 = 3; // 配置GPIO73为XCLKOUT功能
通过以上步骤,我们便为这个复杂的应用搭建起了一个稳定、可靠且满足所有功能需求的时钟系统。记住,时钟是嵌入式系统的脉搏,在项目初期多花时间理解并正确配置它,将为后续所有功能的稳定运行打下最坚实的基础。
