【应用笔记】TAE32G5800 时钟树结构
1 应用介绍
TAE32G5800的时钟树是由多个时钟源和时钟分配器组成的,它可以为芯片提供各种时钟信号。时钟树的配置对于芯片的性能会有很大影响,在使用芯片是需要仔细的配置时钟树。
2 时钟树
为了高度的灵活性,用户可选择使用外部晶振方案或者使用内部RC振荡器的无晶振方案,通过PLL的合理配置,既可满足系统的最高时钟频率,也可为USB以及HRPWM、ADC等需要特定时钟的外设保证合适的频率。
图2.1 时钟电路简图
2.1 时钟分类
TAE32G5800有4个不同的时钟源来驱动系统时钟:
▶ LSI 振荡器时钟;
▶ HSE 振荡器时钟;
▶ PLL 时钟;
▶ HSI 振荡器时钟。
相应寄存器:RCU->CCR.SCS
系统时钟源选择寄存器 | |
---|---|
[1:0]
SCS
|
系统时钟源选择(System Clock Selection) 00:HSI 01:LSI 10:PLL0/N 11:XOSC |
2.1.1 LSI振荡器时钟
LSI RC振荡器可作为低功耗时钟源在停机和待机模式下保持运行,供独立看门狗(IWDG)和自动唤醒单元使用,时钟频率在 32 kHz左右,LSI RC低频振荡器不可关闭。
2.1.2 HSE振荡器时钟
高速外部时钟源,通常为晶振。HSE也是芯片的时钟源之一,通过HXI和HXO引脚输入,其频率范围可以在4MHz到26MHz之间。HSE可以作为系统时钟和PLL锁相环输入。晶振起振电路可通过晶振控制寄存器RCU_ XOSCCR中的XEN位打开或关闭。
相应寄存器:RCU->XOSCCR.XEN
HSE使能寄存器 | |
---|---|
[0]
XEN |
HSE使能(HSE Enable) 0:关闭 1:启动 |
图2.2 HSE时钟源
2.1.3 HSI振荡器时钟
高速内部时钟源,时钟频率为8MHz。HSI是芯片的时钟源之一。可作为系统时钟或PLL锁相环的输入。当HSI作为PLL参考时钟源时,可以通过从Flash中读取 HSI 实际频率来配置分频系数,以得到准确的PLL输出时钟频率。HSI RC振荡器可通过晶振控制寄存器RCU_ XOSCCR中的HEN位打开或关闭。
2.1.4 PLL时钟
PLL由HSE振荡器或HSI振荡器提供时钟信号,并具有两个不同的输出时钟:
▶ 第一个输出用于生成高速系统时钟(最高达180MHz);
▶ 第二个输出用于生成 FLASH工作时钟。
用于生成180M时钟用于HRPWM模块,60M时钟用于USB及ADC模块。
PLL的配置介绍:
▶ PLL的参考时钟源;
可通过软件配置 RCU 模块中的PLLx控制寄存器(RCU_PLLxCR)的RCS位来选择合适的PLL参考时钟。
-
00:HSE
-
01:HSI
▶ PLL的分频模块:包含小数和整数部分。
PLL内部VCO输出时钟经过硬件2分频后,送到FPLLx反馈分频模块,则输入到反馈分频模块FPLLx的频率为PLLxCLK输出频率除以2。①为PLL参考时钟源,可以选择内部/外部晶振,用户可以根据期望的系统时钟频率②,反推出PLL输出的频率。反馈分频模块FPLLx的频率为PLLxClk输出频率除2,即③为PLLxClk/2。
输入时钟经过反馈分频模块(FPLLx)后,输出时钟应该等于PLL的参考输入时钟的频率,即反馈分频模块(FPLLx)的输入时钟频率/输出时钟频率(等于PLL的输入参考频率),按照上述公式可得到PLL的分频值。根据计算出来的分频值,将整数部分存至RCU_PLLxFR.INT内,小数部分乘以216后再取整存入RCU_PLLxFR.FRAC内。
PLLxClk 时钟频率 = 晶振频率 * N * 2;
例如此时需要360M的PLLxClk,那么输入到FPLLx的频率为180M,根据上述公式,可得N为180M/晶振频率(以8M为例子)/2=11.25,那么向RCU->PLLxFR.INT写入整数11,向RCU->PLLxFR.FRAC写入0.25*216 =16384。
相应寄存器:RCU->PLLxFR
PLL倍频系数寄存器 | |
---|---|
[29:16]
INT |
PLL0 倍频系数整数部分 (PLL0 Integer part of multiplication factor) |
[15:0] FRAC |
PLL0 倍频系数小数部分 (PLL0 Fractional part of multiplication factor) Note: PLLx 输出频率经过硬件二分频得到 PLLxDiv2 时钟,PLLxDiv2 时钟经过 (Int+Frac) 分频后得到 PLLx 的 FeedBack 时钟,配置需确保计算出来的 FeedBack 时钟与参考时钟相等; 例如: 如果 PLLx 的参考时钟为 8M,需要 PLLx 的输出频率为 160M,按照上述流程,PLLxDiv2 时钟频率为 80M,然后用 80M 除以 (Int+Frac) 需要等于参考时钟 8M,即可得到除频系数为 Int=10,Frac=0; |
图2.3 PLL的配置流程
2.2 时钟树解析
本章节分析一下时钟树的每一部分的时钟作用以及配置方法。
2.2.1 MCO
芯片时钟输出(MCO)引脚,时钟源可通过RCU_DBGCR寄存器中MCO位来选择,通过置位RCU_DBGCR寄存器中MCOEN位来使能时钟FanOut的功能。此功能可以将内部时钟输出到外部,通过示波器可以查看当前配置时钟频率。
相应寄存器:RCU->DBGCR
时钟 fanout 寄存器 | |
---|---|
[4] MCOEN |
芯片内部时钟输出使能 (Internal Clock Fanout Enable) 0:关闭 1:使能 |
[2:0] MCO |
芯片内部时钟输出源选择 (Internal Clock Fanout Source) 000:LSI 001:HSI 010:HSE 011:SYSCLK 100:PLL0/16 101:Reserved 110:FCLK 111:ATECLK |
图2.4 MCO时钟框架图
具体操作代码如下:
代码清单2.1 时钟fanout代码
RCU->KEY = 0x3fac87e4; //解锁RCU寄存器
RCU->DBGCR.MCOEN = 1; //使能芯片内部输出使能
RCU->DBGCR.MCO = 1; //选择内部输出时钟源(具体时钟源参考芯片手册)
RCU->KEY = 0x01; //加锁RCU寄存器
2.2.2 系统时钟和外设时钟
系统时钟是绝大部分部件工作的时钟源。它的时钟来源可以由HSI、HSE、PLLCLK提供,TAE32F5800希望有一个比较大的时钟频率,因此选择PLLCLK作为系统时钟。PLLCLK是从HSE或HSI经过PLL倍频得到。
图2.5 系统时钟框架图
可通过多个预分频器配置AHB0/1频率、APB0/1频率(RCU->CCR寄存器),AHB域最高时钟频率为 180MHz,APB域的最高时钟频率为90MHz。AHB外设时钟根据上一级预分频器(RCU->CCR.HPSC)获得,APB外设时钟由两级预分频器(RCU->CCR.HPSC和RCU->CCR.P0PSC)获得。
相应寄存器:RCU->CCR
总线时钟分频寄存器 | |
---|---|
[15:12] P1PSC |
APB1时钟分频配置 (APB1 Clock Prescale) 0:1 分频 (不分频) 1:2 分频 … N:N+1 分频 |
[11:8] P0PSC |
APB0时钟分频配置 (APB0 Clock Prescale) 1:2分频 … N:N+1 分频 Note:最低 2 分频; |
[7:2] HPSC |
AHB时钟分频配置 (AHB Clock Prescale) 0:1 分频 (不分频) 1:2 分频 |
代码清单2.2 系统时钟和总线时钟分频配置代码
static void SystemClock_Config(void)
{
LL_StatusETypeDef ret;
RCU_PLLUserCfgTypeDef pll1_cfg;
RCU_SysclkUserCfgTypeDef sysclk_cfg;
//SYSCLK Clock Config
sysclk_cfg.sysclk_src = SYSCLK_SRC_PLL0DivClk; //选择系统时钟的时钟源
sysclk_cfg.sysclk_freq = 180000000UL; //配置的系统时钟频率
sysclk_cfg.pll0clk_src = PLLCLK_SRC_HSE; //选择PLL0的时钟源
sysclk_cfg.pll0clk_src_freq = HSE_VALUE; //选择内外部晶振
sysclk_cfg.apb0_clk_div = RCU_CLK_DIV_2; //选择APB0的预分频值
sysclk_cfg.apb1_clk_div = RCU_CLK_DIV_2; //选择APB1的预分频值
sysclk_cfg.ahb_clk_div = RCU_CLK_DIV_1; //选择AHB的预分频值
ret = LL_RCU_SysclkInit(RCU, &sysclk_cfg);
if (ret == LL_OK) {
SystemCoreClockUpdate(sysclk_cfg.sysclk_freq);
}
}
在时钟树图中我们还可以得到一个重要信息,大多数有关时钟输出部分都有一个使能控制,比如AHB总线、APB1外设、APB2外设等。当需要使用某个时钟的时候一定要开启它的使能,否则将不工作。
上述内配置的APB0时钟、APB1时钟、AHB时钟分别提供不同外设的时钟,设备所属的时钟树通过查看RCU->APB0ENR、RCU->APB1ENR、RCU->AHB0ENR、RCU->AHB1ENR寄存器确定,寄存器定义如下所示:
RCU APB0 时钟控制寄存器 (RCU_APB0ENR)
• 名称:APB0 Peripheral Clock Enable Register
• 偏移地址:0x50
• 默认值:0x00000000
RCU APB1 时钟控制寄存器 (RCU_APB1ENR)
• 名称:APB1 Peripheral Clock Enable Register
• 偏移地址:0x54
• 默认值:0x00000000
RCU AHB0 时钟控制寄存器 (RCU_AHB0ENR)
• 名称:AHB0 Peripheral Clock Enable Register
• 偏移地址:0x58
• 默认值:0x000000FE
RCU AHB1 时钟控制寄存器 (RCU_AHB1ENR)
• 名称:AHB1 Peripheral Clock Enable Register
• 偏移地址:0x5C
• 默认值:0x00000000
2.2.3 特定外设时钟
除以下时钟外,所有外设时钟均由系统时钟(SYSCLK)提供:
▶ 来自于特定PLL0输出的USB时钟(60MHz);
▶ 来自于特定PLL0输出的CAN时钟(120MHz);
▶ 来自于特定PLL0输出的ADC时钟(60MHz);
▶ 来自于特定PLL0输出的HRPWM时钟(180MHz)。
图2.6 特殊外设时钟框图
代码清单2.3 PLL0时钟配置代码
LL_StatusETypeDef ret;
RCU_PLLUserCfgTypeDef pll0_cfg;
RCU_SysclkUserCfgTypeDef sysclk_cfg;
//PLL0 Config
pll0_cfg.pll_clk_src = PLLCLK_SRC_HSE; //PLL0的时钟源
pll0_cfg.pll_in_freq = HSE_VALUE; //PLL0对应的晶振
pll0_cfg.pll_user_freq = 360000000UL; //PLL0时钟频率
ret = LL_RCU_Pll0Cfg(RCU, &pll0_cfg);
代码清单2.4 特殊外设时钟配置代码
if (ret == LL_OK) {
LL_RCU_HRPWM_ClkCfg(RCU_CLK_SRC_PLL0, RCU_CLK_DIV_6); //HRPWM时钟
LL_RCU_ADC_ClkCfg(RCU_CLK_SRC_PLL0, RCU_CLK_DIV_6); //ADC时钟
LL_RCU_USB_ClkCfg(RCU_CLK_SRC_PLL0, RCU_CLK_DIV_6); //USB时钟
LL_RCU_CAN_ClkCfg(RCU_CLK_SRC_PLL0, RCU_CLK_DIV_6); //CAN时钟
}