AT32F423时钟配置 前言
本应用入门指南主要介绍两部分内容:
1、基于雅特力提供的V2.x.x 的板级支持包来进行时钟源码的配置及修改
2、如何使用配套的时钟配置工具来进行时钟路径及参数的设定,生成相应的时钟流程代码并使用。
支持型号列表:
支持型号 AT32F423xx
1 简介
时钟是芯片正确高效运行的基础,正确的时钟配置是芯片能正确运行的必要条件,其重要性不言而
喻。AT32 各系列产品的时钟配置部分可能存在细微的差异和需要注意的事项,本文档就着重针对各
系列的情况来详细介绍如何结合雅特力提供的V2.x.x 的板级支持包(BSP)来配置时钟。
以下介绍时钟配置的方法主要分两种:
1、 以手动编写代码调用BSP 中提供的驱动函数接口来进行时钟配置。
2、 采用时钟工具来配置并生成相应的源码文件。
2 时钟树
在进行时钟配置之前,应充分了解对应芯片的时钟树结构,这样在进行时钟配置时才会游刃有余。对
于系统时钟频率及路径的配置我们需要关注时钟源、倍频及系统时钟部分。类似如下图:
图1. 时钟框图
可由图中得到以下几个关键信息:
1) SCLKSEL:系统时钟可以由HEXT、PLLCLK、HICK 三大时钟源提供。
2) HEXT:HEXT 是外部高速时钟,其可以外接范围是4~25 MHz 的晶振或时钟源。
3) HICK:HICK RC 是内部高速振荡器,频率为48 MHz。HICK 时钟由内部振荡器给出,但在初
始情况下由HICKDIV 控制并默认6 分频后为8 MHz,亦可配置为不分频,保持48 MHz 的频
率。
4) PLLCLK:PLL 时钟 = PLL 输入时钟 / PLL_MS * PLL_NS / PLL_FR。
5) PLL 输入时钟:PLL 的输入时钟由PLLRCS 决定,有两个来源:HICK 8 MHz 和HEXT。
3 代码配置解析
以下将以库函数接口为核心来对时钟配置流程和方法进行说明。
3.1 函数接口
各系列产品对应提供的BSP 中对硬件的时钟设置部分已封装好接口函数以供调用,以下罗列出时钟
配置常用的函数接口,各函数的具体参数及返回值类型等请参考at32f425_crm.c/.h 文件。
/* 时钟和复位管理模块的复位函数,将时钟配置部分恢复到默认值 */
void crm_reset(void);
/* 外部高速时钟的旁路使能函数 */
void crm_hext_bypass(confirm_state new_state);
/* 各状态标志的获取函数,如PLL/HEXT/HICK 等时钟源的稳定标志等 */
flag_status crm_flag_get(uint32_t flag);
/* 等待外部高速时钟稳定 */
error_status crm_hext_stable_wait(void);
/* 时钟源使能函数,如PLL/HEXT/HICK 等时钟源的使能 */
void crm_clock_source_enable(crm_clock_source_type source, confirm_state new_state);
/* PLL 配置函数,配置内容包括:PLL 时钟源、各PLL 倍频系数等 */
void crm_pll_config(crm_pll_clock_source_type clock_source, uint16_t pll_ns, uint16_t pll_ms, crm_pll_fr_type
pll_fr);
/* 系统时钟切换函数 */
void crm_sysclk_switch(crm_sclk_type value);
/* 当前系统时钟切换状态获取函数 */
crm_sclk_type crm_sysclk_switch_status_get(void);
/* 自动顺滑使能函数,当PLL 倍频频率大于108 MHz 时,切换系统时钟到PLL 前需开启 */
void crm_auto_step_mode_enable(confirm_state new_state);
/* 内部高速时钟6 分频配置函数,主要用于hick 48 MHz 接入系统时钟 */
void crm_hick_divider_select(crm_hick_div_6_type value);
/* 内部高速时钟用做系统时钟时的频率路径选择函数,可设置固定路径(8 MHz),6 分频路径路径(8 MHz 或
48 MHz 由6 分频配置函数决定) */
void crm_hick_sclk_frequency_select(crm_hick_sclk_frequency_type value);
/* 系统时钟到AHB 时钟的分频设置函数 */
void crm_ahb_div_set(crm_ahb_div_type value);
/* AHB 时钟到APB1 时钟的分频设置函数 */
void crm_apb1_div_set(crm_apb1_div_type value);
/* AHB 时钟到APB2 时钟的分频设置函数 */
void crm_apb2_div_set(crm_apb2_div_type value);
/* HEXT 时钟到系统时钟的分频设置函数 */
void crm_hext_sclk_div_set(crm_hext_sclk_div_type value);
3.2 时钟配置流程
按常规应用来讲解时钟配置流程,其内容可大致分为如下步骤:
图2. 时钟配置流程图
3.2.1 复位(CRM Reset)
首先按规范流程应复位CRM 配置参数,其主要是将系统时钟切换到HICK,其余的系统时钟配置寄
存器写入默认值,待后续进行新配置参数的写入。函数调用的代码实现如下:
crm_reset(); /* CRM 复位 */
3.2.2 Flash 等待周期(Set Flash Wait Cycle)
AT32F423 片上采用的是嵌入式Flash,当运行在不同的主频下时需对应设定Flash 等待周期。flash
等待周期与运行主频关系如下:
System Clock Frequency Flash Wait Cycle
0< sysclk <=32 MHz FLASH_WAIT_CYCLE_0
32< sysclk <=64 MHz FLASH_WAIT_CYCLE_1
64< sysclk <=96 MHz FLASH_WAIT_CYCLE_2
96< sysclk <=128 MHz FLASH_WAIT_CYCLE_3
128< sysclk <=150 MHz FLASH_WAIT_CYCLE_4
函数调用的代码实现如下:
flash_psr_set(FLASH_WAIT_CYCLE_0); /* 设置flash 等待周期0 cycle */
3.2.3 时钟源配置(Clock Source Configuration)
与系统时钟相关的高速时钟源主要包括HEXT 和HICK,PLL 也是使用以上时钟源来进行倍频。需要
在配置使能PLL 前将所使用的PLL 参考时钟源开启并等待其稳定。
HEXT
外部高速时钟如采用外接有源时钟的方式时,可开启旁路模式来进行使用,采用晶振时,不能开启旁
路模式,旁路模式应在外部高速时钟源使能前进行设定,其默认情况为关闭。旁路模式使能代码实现
如下:
crm_hext_bypass(TRUE); /* HEXT 时钟旁路模式开启 */
使能HEXT 时钟源并等待HEXT 时钟稳定,代码实现如下:
crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE); /* 开启HEXT 时钟源 */
while(crm_hext_stable_wait() == ERROR) /* 等待HEXT 时钟稳定 */
{
}
HICK
内部高速时钟是由芯片内部振荡器提供,使能HICK 时钟源并等待HICK 时钟稳定,代码实现如下:
crm_clock_source_enable(CRM_CLOCK_SOURCE_HICK, TRUE); /* 开启HICK 时钟源 */
while(crm_flag_get(CRM_HICK_STABLE_FLAG) != SET) /* 等待HICK 稳定标志置起 */
{
}
3.2.4 PLL 配置(PLL Configuration)
PLL 配置主要包括:PLL 时钟源、PLL 倍频系数、PLL 倍频频率范围等的设置。倍频时钟公式为:
PLLCLK = (PLL 输入时钟 * PLL_NS) / (PLL_MS * PLL_FR)。
PLL 时钟源
PLL 时钟源细分有如下来源:1、HICK(8 MHz),2、HEXT。PLL 时钟源应在PLL 配置使能前开
启并等待稳定。以上PLL 时钟源在crm_pll_config 函数中对应的参数定义如下:
CRM_PLL_SOURCE_HICK
CRM_PLL_SOURCE_HEXT
PLL 倍频系数
PLL_MS:PLL 预分频系数,范围值1~15。其功能是对PLL 输入时钟进行预分频。
PLL_NS:PLL 倍频参数,范围值31~500。其功能是对PLL_MS 进行预分频处理后的时钟进行倍
频。
PLL_FR:PLL 后分频系数,范围(1、2、4、8、16、32)。其功能是对PLL_NS 倍频后的时钟进
行后除频,除频后的时钟才是PLL 时钟。
以上参数在搭配使用时有如下限制条件,详情可参考RM 的时钟源章节:
2 MHz <= PLL 输入时钟 / PLL_MS <= 16 MHz
500 MHz <= PLL 输入时钟 * PLL_NS / PLL_MS <= 1000 MHz
当PLL 参数设置完成后,即可开启PLL 并等待PLL 稳定。示例:外部时钟晶振8 MHz,采用HEXT
时钟作为PLL 时钟源,PLLCLK 倍频到288 MHz 的代码实现如下:
crm_pll_config(CRM_PLL_SOURCE_HEXT, 72, 1, CRM_PLL_FR_2); /* 配置PLL 参数 */
crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE); /* 开启PLL 时钟源 */
while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET) /* 等待PLL 稳定标志置起 */
{
}
3.2.5 总线分频(Set Bus Frequency Division)
总线分频包含SCLK 到AHBCLK 分频、AHBCLK 到APB1CLK 分频、AHBCLK 到APB2CLK 分
频。AHB 总线1 分频、APB1/APB2 总线1 分频的代码实现如下:
crm_ahb_div_set(CRM_AHB_DIV_1); /* SCLK 1 分频作为AHB 总线时钟 */
crm_apb2_div_set(CRM_APB2_DIV_1); /* AHBCLK 1 分频作为APB2 总线时钟,最大频率150MHz*/
crm_apb1_div_set(CRM_APB1_DIV_1); /* AHBCLK 1 分频作为APB1 总线时钟,最大频率120MHz*/
注:APB2CLK 的最大频率为150MHz,APB1CLK 的最大频率为120MHz。
3.2.6 切换系统时钟(Switch System Clock)
系统时钟来源主要有三个:HICK、HEXT、PLLCLK。在切换系统时钟到如上时钟源时应提前确保对
应时钟源已稳定。
HICK 系统时钟
内部高速时钟在系统复位重新运行时默认作为系统时钟,后期代码进行设定时,可有两种频率值来进
行设定(8 MHz 和48 MHz)。如图1 所述HICK 默认情况下用的是8 MHz,可配置为48 MHz。
HICK 8 MHz 用作系统时钟的代码实现如下:
crm_hick_sclk_div_set(CRM_HICK_SCLK_DIV_1); /* 设置HICK 到系统时钟分频 */
crm_sysclk_switch(CRM_SCLK_HICK); /* 切换系统时钟到HICK */
while(crm_sysclk_switch_status_get() != CRM_SCLK_HICK) /* 等待系统时钟状态为HICK */
{
}
HICK 48 MHz 用作系统时钟的代码实现如下:
crm_hick_sclk_frequency_select (CRM_HICK_SCLK_48MHZ); /* HICK 选择hick48MHz */
crm_hick_sclk_div_set(CRM_HICK_SCLK_DIV_1); /* 设置HICK 到系统时钟分频 */
crm_sysclk_switch(CRM_SCLK_HICK); /* 切换系统时钟到HICK */
while(crm_sysclk_switch_status_get() != CRM_SCLK_HICK) /* 等待系统时钟状态为HICK */
{
}
HEXT 系统时钟
外部高速时钟用作系统时钟时,其系统时钟频率以实际使用的外部时钟频率为准,范围为4~25
MHz。HEXT 用作系统时钟的代码实现如下:
crm_sysclk_switch(CRM_SCLK_HEXT); /* 切换系统时钟到HEXT */
crm_hext_sclk_div_set(CRM_HEXT_SCLK_DIV_1); /* 设置HEXT 到系统时钟分频 */
while(crm_sysclk_switch_status_get() != CRM_SCLK_HEXT) /* 等待系统时钟状态为HEXT */
{
}
PLLCLK 系统时钟
PLLCLK 用作系统时钟时,系统时钟频率 = PLLCLK / 2,频率值以实际的PLL 倍频结果为准。其最
高频率应满足芯片规格为基础。PLLCLK 用作系统时钟的代码实现如下:
crm_sysclk_switch(CRM_SCLK_PLL); /* 切换系统时钟到PLL */
while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL) /* 等待系统时钟状态为PLL */
{
}
3.2.7 更新核心频率(Update Core Frequency)
提供的BSP 中,其代码框架内保留了一个表示系统核心频率的参数值system_core_clock,其保存
的是CPU 核心的运行频率值,应该在每次系统时钟配置完成后来进行更新。为的是在整个代码框架
下,各外设驱动的频率配置能很快获取到当前核心运行频率值并使用。代码实现如下:
system_core_clock_update(); /* 更新系统核心频率值system_core_clock */
3.3 时钟配置示例
以下将以完整的时钟配置流程来进行说明,示例:由8 MHz 外部时钟晶振作为时钟源,经PLL 倍频
后,144 MHz 用做系统时钟,AHB 不分频,APB2 采用1 分频,APB1 采用2 分频。函数
system_clock_config 代码实现如下:
void system_clock_config(void)
{
crm_reset(); /* CRM 复位 */
flash_psr_set(FLASH_WAIT_CYCLE_4); /* 设置flash 等待周期4 cycle */
pwc_ldo_output_voltage_set(PWC_LDO_OUTPUT_1V3); /* 设置ldo 输出电压为1.3V */
crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE); /* 使能HEXT 时钟源 */
while(crm_hext_stable_wait() == ERROR) /* 等待HEXT 时钟稳定 */
{
}
crm_pll_config(CRM_PLL_SOURCE_HEXT, 72, 1, CRM_PLL_FR_2); /* 配置PLL,PLL 时钟源选择HEXT,
倍频参数PLL_MS = 1,PLL_NS = 72,PLL_FR = 2 分频,公式:PLLCLK = 8 / 1 * 72 / 2 = 288 MHz,选择
PLLCLK 作为系统时钟时,系统时钟 = PLLCLK / 2 = 144MHz */
crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE); /* 使能PLL */
while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET) /* 等待PLL 稳定 */
{
}
crm_ahb_div_set(CRM_AHB_DIV_1); /* SCLK 1 分频作为AHB 总线时钟 */
crm_apb2_div_set(CRM_APB2_DIV_1); /* AHBCLK 1 分频作为APB2 总线时钟 */
crm_apb1_div_set(CRM_APB1_DIV_2); /* AHBCLK 2 分频作为APB1 总线时钟 */
crm_auto_step_mode_enable(TRUE); /* 因PLLCLK 144 MHz 大于108 MHz,
开启时钟切换顺滑模式 */
crm_sysclk_switch(CRM_SCLK_PLL); /* 切换系统时钟到PLL */
while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL) /* 等待系统时钟切换状态为PLL */
{
}
crm_auto_step_mode_enable(FALSE); /* 切换完成,关闭时钟切换顺滑模式 */
system_core_clock_update(); /* 更新系统核心频率值 */
}
更多时钟工具、注意事项、案例等详细内容请参考附件:
AN0158_AT32F423_CRM_Start_Guide_ZH_V2.0.0.pdf
(888.99 KB)
|