LPC5114时钟树分析
LPC5114时钟树分析
---东方青
对于LPC5114这款MCU而言,我首先关注的是其运行的时钟频率和MCU的时钟系统,这决定着在开发时对外设时钟的管理,做低功耗时对时钟频率的调节等等。
从用户手册《LPC5411x User manual》中可以知道,所有系统相关的配置有SYSCON管理;包括系统时钟总线、外设时钟、电源等等。在进行一切的分析工作之前,我们有必要先来了解LPC5114的系统时钟总线架构,这样有助于全面的了解它的系统时钟。实际上就是所谓的时钟树,如图:
如上图,对于主时钟main_clk而言,它有三种方式获取时钟源:
(1)由内部FRO(提供12MHz、48MHz、96MHz)提供。
主要由MAINCLKSELA寄存器管理。MAINCLKSELA寄存器可以再选择输入的时钟源。
(2)由锁相环PLL提供时钟源。
(3)由外部晶振提供32.768KHz的频率
因为板卡没有提供外部12MHz的晶振,所以实际上在使用的时候直接是由FRO产生12MHz、48MHz或者96MHz的时钟频率来为主时钟main_clk提供时钟源。然后main_clk又为各个时钟总线(AHB、Sync APB、APB0、APB1)提供外设工作所需要的时钟频率。如下图:
1.如何将MCU的时钟配置为想要的工作频率呢?
(1)如上图所示,程序进入main函数之后,第一件事就是讲将MCU的主时钟频率配置为12MHz,这涉及到三个寄存器:MAINCLKSELA、MAINCLKSELB和FXCOMCLKSEL。
如上图所示,当MAINCLKSELA寄存器取值为0x00时,使得FRO输出12MHz的时钟频率,对于MAINCLKSELB寄存器而言,因为在时钟树种可以选择其由MAINCLKSELA寄存器选择的通道为main_clk提供时钟源,所以MAINCLKSELB的值也为0x00,而实际上他们的默认值为0x00,可以不用设置。而对于FXCOMCLKSEL的配置,如下图:
FXCOMCLKSEL寄存器的默认值为0x7,意味着如果不进行配置,那么MCU的主时钟的值为0,那也意味这CPU可能不工作,所以我们需要将FXCOMCLKSEL寄存器的值设置为0x00。在程序可以直接调用库函数CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0);实现以上操作,或者也可以直接操作寄存器SYSCON->FXCOMCLKSEL[0] = 0x00;(MAINCLKSELA和MAINCLKSELB的默认值为0x00,可以不需要配置),实现将系统时钟配置为12MHz的工作频率,以保证CPU能正常的工作。
(2)CPU正常工作以后,就可以再进行配置,切换时钟频率。可以使得MCU工作在48MHz或者96MHz的主时钟频率下。
首先操作PDRUNCFGCLR0寄存器,将FRO电源关闭。
当对PDRUNCFGCLR0寄存器的位[4]写1时,即为将PDRUNCFG0寄存器的位[4]清0,将FRO的电源关闭,这样才能重新配置FRO。然后再一次将FRO配置输出位12MHz,调用CLOCK_AttachClk(kFRO12M_to_MAIN_CLK);(这里的做法是为了在系统运行过程中进行频率切换而考虑的)。
以上步骤做完之后,直接调用库接口POWER_SetVoltageForFreq(96000000);(这里以96MHz说明)设置内核在对应时钟频率运行时的电压,然后再调用POWER_SetVoltageForFreq(96000000);设置Flash的等待周期;与Flash配置寄存器FLASHCFG有关。
到这里就可以直接时钟频率了,首相配置FRO控制寄存器FROCTRL,如下图:
主要针对配置位[14],置1时,FRO可输出96MHz,可以直接操作寄存器或者调用接口(CLOCK_SetupFROClocking(96000000);)配置。
最后在通过调用CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK);,使得MAINCLKSELA寄存器选择96MHz的频率作为时钟源,供给MAINCLKSELB寄存器。如下图:
到这里主时钟main_clk的输出就为96MHz的频率了。
2.外设的时钟如何配置?
主时钟配置好之后,对于外设的时钟的配置就很简单了,可以分为两种情况:
(1)挂载在时钟总线AHB、ASYNC APB、APB0、APB1下的外设
对于这种外设,我们只需要自其对于时钟总线的寄存器将时钟打开或者配置倍频/分频即可。例如GPIO口的时钟配置,其挂载在AHB总线上,如下图:
直接对想要使用的外设对于的位写1,就打开了对于的时钟。
(2)由主时钟main_clk直接提供时钟的外设
对于这种外设,有单独的寄存器来进行配置时钟,这一点从时钟树就可以知道。这里以USB来举例:
使用USBCLKSEL寄存器来选择供给USB时钟的时钟源,可以选择maic_clk,然后再使用USBCLKdiv寄存器来设置时钟的分频系数,这样就可以配置外设的时钟了。