本帖最后由 小恩GG 于 2025-12-15 19:37 编辑
MCXNX4X: OSC32k 配置与Cap Bank使用详解
在低功耗嵌入式系统中,时钟源的稳定性和功耗控制至关重要。MCXNx4x 系列芯片的 VBAT模块不仅支持电池供电下的关键功能,还集成了 32.768 kHz 晶体振荡器(OSC32k) 和 可配置电容器组(Cap Bank),用于优化晶体负载匹配和功耗表现。本文将深入解析 MCXN 系列芯片的 OSC32k 配置流程及 Cap Bank 的应用场景。
一、OSC32k 概述 VBAT 模块提供两种时钟源: - OSC32k:外部32.768 kHz 晶体振荡器,适用于高精度RTC。
- FRO16K:内部16 kHz 自由运行振荡器,默认上电启用。
OSC32k 默认在VBAT 上电复位(POR)后关闭,需软件显式启用。启用后,需等待启动时间,直到STATUSA[OSC_RDY] 置位,表示时钟稳定。
二、OSC 工作模式 OSC32k 支持两种模式: - 正常模式(Normal Mode):适用于对频率精度要求高的场景。
- 低功耗模式(Low Power Mode):用于延长电池寿命,降低功耗。
模式选择通过OSCCTLA[MODE_EN] 配置,其中 00b 表示正常模式,01b表示startup模式,11b 表示低功耗模式。 在任意模式下支持软件可配置电容组,并且在首次启用振荡器时必须进行配置。
三、Cap Bank配置 晶体振荡器的负载电容对频率稳定性影响显著。MCXNx4x 提供软件可配置的电容器组,通过OSCCTLA[XTAL_CAP_SEL] 和OSCCTLA[EXTAL_CAP_SEL] 设置: - 每个引脚(XTAL、EXTAL)可选择 0 pF ~ 30 pF,步进 2 pF。
- 启用电容选择需设置 OSCCTLA[CAP_SEL_EN] = 1。
负载电容计算公式:
其中: - Cextal:EXTAL 引脚选择的电容
- Cxtal:XTAL 引脚选择的电容
- Cshunt:芯片内部寄生电容(参考数据手册)
注意事项: - 低功耗模式下,必须配置CAP_SEL_EN = 1且XTAL_CAP_SEL/ EXTAL_CAP_SEL = 0000。此配置专门设计用于将功耗降至最低,并且适用于负载电容(CL)为 7 pF或更低的晶体。当内部电容组均为0pF时,您必须从外部提供所需的全部负载电容。
- 正常模式下,必须配置CAP_SEL_EN = 1,注意此时不能同时将XTAL/EXTAL都设置为 0 pF。EXTAL 引脚的内部电容具有硬件强制的最小值 2 pF。XTAL_CAP_SEL仍可设置为 0 pF。如果在此模式下使用外部电容,在计算外部电容值时必须考虑 EXTAL32 引脚上残留的 2 pF。
- 电容选择需结合晶体 ESR、CL 参数及 PCB 寄生效应。
- 关于使用Cap Bank设置或者外部电容选择,可以参考AN13057.pdf,里面有更详细的解释及计算公式。
- 低功耗模式下可根据 VBAT 电压选择 SUPPLY_DET(<3V 或 >3V)。
四、OSC 初始化步骤 正常模式配置流程: - 根据晶体参数配置 EXTAL_CAP_SEL、XTAL_CAP_SEL 和 COARSE_AMP_GAIN。
- 设置 OSCCTLA[MODE_EN] = 0b,CAP_SEL_EN = 1b,OSC_EN = 1b。
- 将 OSCCTLB 写入 OSCCTLA 的反码。
- 等待 STATUSA[OSC_RDY] = 1b。
- 锁定配置:OSCLCKA[LOCK] = 1b,OSCLCKB[LOCK] = 0b。
低功耗模式配置流程(需要从startup mode切换到low power mode): - 初始化启动时间,写入 3h 到 OSCCFGA[INIT_TRIM]。
- 将 OSCCFGA 的反码写入 OSCCFGB[INVERSE]。
- 根据晶体 ESR、CL 参数及 PCB 寄生效应,配置:OSCCTLA[EXTAL_CAP_SEL],OSCCTLA[XTAL_CAP_SEL],OSCCTLA[COARSE_AMP_GAIN],同时设置:OSCCTLA[MODE_EN] = 1h(startup mode),OSCCTLA[CAP_SEL_EN] = 1h,OSCCTLA[OSC_EN] = 1h
- 将 OSCCTLA 的反码写入 OSCCTLB[INVERSE]。
- 等待 STATUSA[OSC_RDY] 置位。
- 清除启动时间配置,写入 0h 到 OSCCFGA[INIT_TRIM]。
- 将 OSCCFGA 的反码写入 OSCCFGB[INVERSE]。
- 设置OSCCTLA[MODE_EN] = 3h(low-power mode),OSCCTLA[EXTAL_CAP_SEL] = 0h,OSCCTLA[XTAL_CAP_SEL] = 0h。根据应用需求配置 OSCCTLA[SUPPLY_DET]。
- 将 OSCCTLA 的反码写入 OSCCTLB[INVERSE]。
- 等待 OSC_RDY 置位。
五、应用实战 硬件环境: 开发板:MCXN547EVK
软件环境: IDE:MCUXpresso IDEv25.06 SDK:MCXN547EVK 25.09 基础工程:mcxn5xxevk_irtc_cm33_core0
配置思路 在实际应用中,OSC32k的配置主要包括以下三个步骤: - 启用OSC32k 并选择输出到VBAT 域。
- 配置内部电容组(Cap Bank),确保晶体负载匹配。
- 锁定配置并等待振荡器稳定。
关键代码解析: 1. 时钟初始化Clock_config.c: void BOARD_BootClockPLL150M(void) { ... CLOCK_SetPll0MonitorMode(_kSCG_Pll0MonitorDisable_); /* 禁用 Pll0 监控 */ CLOCK_SetupOsc32KClocking(_kCLOCK_Osc32kToVbat_); /* 启用 OSC32k 输出到VBAT */
vbat_osc_config_tg_vbatOscConfig_BOARD_BootClockPLL150M = { .coarseAdjustment = kVBAT_OscCoarseAdjustment10, .enableInternalCapBank = true, .enableCrystalOscillatorBypass = false, .xtalCap =kVBAT_OscXtal22pFCap, .extalCap =kVBAT_OscExtal22pFCap, }; /* 结构体里设置OSC相关的参数*/
VBAT_SetOscConfig(VBAT0, &g_vbatOscConfig_BOARD_BootClockPLL150M); CLOCK_AttachClk(_kPLL0_to_MAIN_CLK_); ... } 要点说明: - enableInternalCapBank = true 表示启用内部电容组。
- xtalCap 和 extalCap 根据晶体负载电容参数选择,示例中均为 22 pF。
2. OSC32k 时钟设置函数CLOCK_SetupOsc32KClocking: status_t CLOCK_SetupOsc32KClocking(uint32_t id) { /* 启用 LDO */ SCG0->LDOCSR |=SCG_LDOCSR_LDOEN_MASK | SCG_LDOCSR_VOUT_OK_MASK; /* 配置 OSCCTLA 并启用OSC */ VBAT0->OSCCTLA= (VBAT0->OSCCTLA & ~(VBAT_OSCCTLA_MODE_EN_MASK |VBAT_OSCCTLA_CAP_SEL_EN_MASK | VBAT_OSCCTLA_OSC_EN_MASK)) | VBAT_OSCCTLA_MODE_EN(0x0) | VBAT_OSCCTLA_CAP_SEL_EN_MASK |VBAT_OSCCTLA_OSC_EN_MASK; VBAT0->OSCCTLB =VBAT_OSCCTLB_INVERSE(0xFFF7E);
/* 等待振荡器稳定 */ while ((VBAT0->STATUSA &VBAT_STATUSA_OSC_RDY_MASK) == 0U) {}
VBAT0->OSCCLKE|= VBAT_OSCCLKE_CLKE(id);
/* De-initializesthe SCG ROSC */ SCG0->ROSCCSR =SCG_ROSCCSR_ROSCERR_MASK;
/* Unlock ROSCCSR*/ SCG0->ROSCCSR&= ~SCG_ROSCCSR_LK_MASK;
/* Enable SOSCclock monitor and Enable ROSC */ SCG0->ROSCCSR|= SCG_ROSCCSR_ROSCCM_MASK;
/* Wait for ROSCclock to be valid. */ while((SCG0->ROSCCSR & SCG_ROSCCSR_ROSCVLD_MASK) == 0U) { }
s_Xtal32_Freq =32768U;
returnkStatus_Success; } 要点说明:
3. VBAT_SetOscConfig函数 void VBAT_SetOscConfig(VBAT_Type *base, constvbat_osc_config_t *config) { uint32_t tmp32;
if (config->enableCrystalOscillatorBypass== true) { base->OSCCTLA |= VBAT_OSCCTLA_OSC_BYP_EN_MASK; while((VBAT0->STATUSA & VBAT_STATUSA_OSC_RDY_MASK) == 0U) { } } else { tmp32 =base->OSCCTLA;
if (config !=NULL) { if(config->enableInternalCapBank) { tmp32&= ~(VBAT_OSCCTLA_EXTAL_CAP_SEL_MASK | VBAT_OSCCTLA_XTAL_CAP_SEL_MASK); tmp32|= VBAT_OSCCTLA_EXTAL_CAP_SEL(config->extalCap) |VBAT_OSCCTLA_XTAL_CAP_SEL(config->xtalCap); tmp32|= VBAT_OSCCTLA_CAP_SEL_EN_MASK; } else { /*Disable the internal capacitance bank. */ tmp32&= ~VBAT_OSCCTLA_CAP_SEL_EN_MASK; }
tmp32&= ~(VBAT_OSCCTLA_COARSE_AMP_GAIN_MASK); tmp32 |=VBAT_OSCCTLA_COARSE_AMP_GAIN(config->coarseAdjustment); } base->OSCCTLA = tmp32; base->OSCCTLB = ~tmp32; while((VBAT0->STATUSA & VBAT_STATUSA_OSC_RDY_MASK) == 0U) { } } } 要点说明: - VBAT 寄存器采用 A/B 双寄存器机制,必须写入反码,否则会触发 STATUSA[CONFIG_DET]。
- 配置完成后,等待 OSC_RDY 置位。
Note: 1. 从Reference manual里面我们可以知道OSC32K配置寄存器只能通过VBAT 域的冷启动上电复位来重置,一旦这些寄存器被软件锁定,就没有其它可用的解锁方法。 2. 且VBAT寄存器比较特殊,其实现为独立的A 和 B 寄存器。在配置 A 寄存器时,必须向对应的 B 寄存器写入 A 寄存器的取反值。否则就会触发STATUSA[CONFIG_DET]置位。
测试结果 重新上电(冷启动)后,调用 VBAT_SetOscConfig() 可成功更改晶体负载电容,验证配置生效。
六、总结 MCX Nx4x 系列在低功耗设计中提供了灵活的OSC32k 配置能力,结合可调节的Cap Bank,使开发者能够在时钟精度与功耗优化之间找到最佳平衡。 1.正常模式适用于RTC 等高精度场景,确保系统时间稳定。 2.低功耗模式则在电池供电应用中显著降低能耗,延长设备续航。 3.配置过程中,务必关注VBAT 寄存器的 A/B 双寄存器机制,正确写入反码并等待 OSC_RDY 置位,避免配置失效。 4.合理选择负载电容(内部或外部),并结合晶体参数与PCB 寄生效应,才能实现最佳性能。 通过掌握这些关键点,开发者不仅能提升系统稳定性,还能在功耗控制上获得显著优势,为低功耗应用提供可靠的时钟解决方案。
|