使用信号频率分析仪(SFA)测量FRO 6M频率
概述
信号频率分析仪(Signal Frequency Analyzer,SFA)是恩智浦(NXP)KW45、MCXW71、KW47 和 MCXW72 微控制器中提供的一种专用硬件外设。它旨在为数字信号特性(包括频率、周期和定时间隔)提供精确的实时测量和分析。这使得它成为需要精确定时诊断、信号验证和系统调试的应用程序的宝贵工具。
通过利用内部 32 位计数器和可配置的触发机制,SFA 能够高分辨率地捕获信号跳变,支持强大的系统监控和故障检测。
SFA 的功能特性
此SFA模块支持下列测量:
它使用两个 32 位计数器运行:
测量是通过比较两个时钟的计数进行的,直到达到预定的目标值。
FRO 6M 频率故障场景
在某些情况下,6 MHz 自由运行振荡器 (FRO6M)可能会偶尔输出不正确的频率:
为减轻因不正确的 FRO6M 输出而导致的潜在问题,应用程序开发人员有责任验证振荡器的频率,并在需要时采取纠正措施。
使用 SFA 监控 FRO 6M
要监控 FRO6M 信号,建议采用以下配置:
SFA 配置参数
代码实现
所展示的函数旨在在用户应用程序中实现,内部函数是恩智浦 SDK 中 SFA 驱动程序实现的一部分。
它可在 MCXW71、MCXW72、KW45、KW47 上使用,只需确保
void init_SFA_peripheral(void)
{
/* Enable SFA interrupt. */
EnableIRQ(SFA_IRQn);
/* Set SFA interrupt priority. */
NVIC_SetPriority(SFA_IRQn, 1);
SFA_Init(DEMO_SFA_BASEADDR);
SFA_InstallCallback(DEMO_SFA_BASEADDR, EXAMPLE_SFA_CALLBACK);
}
void EXAMPLE_SFA_CALLBACK(status_t status)
{
if (status == kStatus_SFA_MeasurementCompleted)
{
SfaMeasureFinished = true;
}
sfa_callback_status = status;
}
此函数使用 CPU 时钟作为参考来设置 FRO6M 信号的测量。
uint8_t SFA_freq_measurement_6M_FRO(void)
{
uint8_t ratio = 0;
uint32_t freq = 0UL;
sfa_config_t config;
CLOCK_SetClkOutSel(kClockClkoutSelSirc); //set clokout to SIRC
SFA_GetDefaultConfig(&config); //Get SFA default config
config.mode = kSFA_FrequencyMeasurement0;
config.refSelect = kSFA_REFSelect1; //Set CPU clk as ref clk
config.cutSelect = kSFA_CUTSelect1; //Set clkout as CUT
config.refTarget = 0xFFFFFFUL;
config.cutTarget = 0xFFFFUL;
config.enableCUTPin = true;
freq = get_ref_freq_value(CPU_CLK);
SFA_SetMeasureConfig(DEMO_SFA_BASEADDR, &config);
SFA_MeasureNonBlocking(DEMO_SFA_BASEADDR);
while (1)
{
if (SfaMeasureFinished)
{
SfaMeasureFinished = false;
if(kStatus_SFA_MeasurementCompleted == sfa_callback_status)
{
freq = SFA_CalculateFrequencyOrPeriod(DEMO_SFA_BASEADDR, freq);//Calculate the FRO freq
if(FREQ_6MHZ + TOLERANCE <= freq )
{
ratio = 1;
}
else
{
if(FREQ_3MHZ + TOLERANCE <= freq)
{
ratio = 2;
}
else
{
if(FREQ_2MHZ + TOLERANCE <= freq)
{
ratio = 3;
}
else
{
ratio = 4;
}
}
}
break;
}
}
else
{
__WFI();
}
}
return ratio;
}
结果解释与使用
在添加上述函数后测试 FRO 6M,可在执行以下操作后测试 FRO:
函数 SFA_freq_measurement_6M_FRO() 返回测量的 FRO6M 频率比,通过该比率可以了解 6M FRO 的当前频率输出,比率 1 表示 FRO 正在输出 6M,比率 2 表示 FRO 的频率输出减半,即 FRO 正在输出 3 MHz,比率 3 表示 FRO 的输出频率被削减了三分之一,结果为 2 MHz 频率输出。
有了这些信息,您可以:
FRO6M 输出频率较低时重新配置外设时钟的步骤
按照前面所述使用 SFA 测量来确定 FRO6M 是否在其预期频率(6 MHz)以下运行。如果结果明显较低,则继续重新配置。
大多数恩智浦微控制器提供多个内部和外部时钟源。常见的替代选项包括:
选择一个符合以下条件的时钟源:
使用 SDK 的 CLOCK_Set... API 来更改时钟源。
您可能还需要:
示例场景:测量 FRO 并根据频率比调整 UART
假设您的应用程序依赖于 6 MHz 自由运行振荡器(Free Running Oscillator,FRO),且其精度直接影响 UART 通信。为确保可靠运行,您可以使用系统频率调整(System Frequency Adjustment,SFA)功能来监控 FRO 输出,并动态调整 UART 配置。
使用推荐方法测量 6 MHz FRO 后,系统会返回一个频率比值。该值的范围为 1 到 4,其中:
使用该比率,您可以初始化和配置 UART 外设及其驱动程序,以补偿任何频率变化,确保稳定且准确的通信。
*/
int main(void)
{
BOARD_InitHardware();
uint8_t ch = 0;
uint8_t FRO_ratio = 0;
init_SFA_peripheral();
/*Measure FRO6M output frequency*/
FRO_ratio = SFA_freq_measurment_6M_FRO();
/*Init debug console and compensate in case a different frequency is output */
if(0 == FRO_ratio)
{
assert(0);//this user defined return value means something went wrong while measuring 6Mz FRO
}
uint32_t uartClkSrcFreq = BOARD_DEBUG_UART_CLK_FREQ/FRO_ratio;//Compensate the src frequency set for uart module
CLOCK_EnableClock(kCLOCK_Lpuart1);
CLOCK_SetIpSrc(kCLOCK_Lpuart1, kCLOCK_IpSrcFro6M);
DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq);
......
}
SDK 25.0.00FRO6M 校准功能增强
为了解决6 MHz自由运行振荡器(FRO6M)已知的可靠性问题,尤其是在从低功耗电源模式过渡时,SDK 25.06.00 版本引入了一系列软件增强,旨在提升振荡器的验证和校准能力。
引入的关键特性
为方便对 FRO6M 频率进行运行验证,新增了两个功能:
这些函数提供了一种轻量级且高效的机制,用于检测和响应振荡器异常行为,确保系统稳定性和时序精度。
使用案例及优势
这些增强功能在以下应用中特别有价值:
通过集成这些校准例程,开发人员可以主动检测和纠正 FRO6M 频率异常,提高整体系统鲁棒性,并降低因时钟不稳定导致的运行时错误风险。