极海APM32E030 MCU中高速时钟的配置和相关注意事项
1
拍明芯城
极海APM32E030 MCU中高速时钟的配置和相关注意事项
极海APM32E030是一款基于Arm® Cortex®-M0+内核的32位工业级基础拓展型微控制器,其工作主频最高可达72MHz,在工业控制、智能家居、仪器仪表、可穿戴设备、医疗及手持设备、小家电、照明灯等领域有着广泛的应用。时钟系统作为MCU的核心组成部分,对MCU的性能和稳定性起着至关重要的作用。本文将详细介绍极海APM32E030 MCU中高速时钟的配置方法以及相关注意事项。

一、APM32E030时钟系统概述
APM32E030的时钟系统为MCU的各个模块提供稳定的时钟信号,确保MCU能够正常运行。其时钟源主要包括内部时钟源和外部时钟源两类。
内部时钟源
内部时钟源包含高速内部时钟信号(HSICLK)和低速内部时钟信号(LSICLK)。HSICLK由内部8MHz的RC振荡器产生,不同芯片的RC振荡器频率存在一定差异,且同一颗芯片的HSICLK时钟频率会随着温度、电压的变化而改变。不过,每个芯片的HSICLK时钟频率在出厂前都已经被厂家校准到1%(在25℃、VDD = VDDA = 3.3V的条件下)。LSICLK则支持40KHz的RC振荡器,主要用于一些对时钟精度要求不高的低速外设。
外部时钟源
外部时钟源包括高速外部时钟信号(HSECLK)和低速外部时钟信号(LSECLK)。HSECLK的输入时钟范围是4 - 32MHz,可通过外部晶体/陶瓷谐振器(常规的无源晶振)或用户外部时钟(有源晶振或者是其他芯片提供的时钟)来提供。LSECLK一般接入32.768KHz的晶体/陶瓷振荡器,常用于RTC(实时时钟)等需要精确计时的模块。
锁相环(PLL)
PLL是APM32E030时钟系统中的一个重要组成部分,它支持2 - 16倍频。通过PLL,可以将外部时钟源或内部时钟源的频率进行倍频,从而得到更高频率的时钟信号,以满足MCU对高速时钟的需求。系统时钟源可以从HSECLK、PLLCLK(PLL的时钟)、HSICLK这三个中选择。HSECLK经过PLL的分频器和倍频器配置后,最大可使PLL达到72M主频;而HSICLK的时钟频率是8M,需要固定2分频到PLL的倍频器,最大16倍频,所以最大主频只能配到64Mhz。
二、高速时钟配置方法
默认时钟配置
芯片上电后,会运行到启动文件,初始化完中断向量表后会进入到SystemInit()函数进行默认的时钟初始化。在SystemInit()函数中,会复位时钟相关的寄存器,然后进入SystemClockConfig()函数进行默认的时钟配置。APM32E030的SDK默认配置的是8M外部无源晶振,配置主频72M。如果需要配置更低的主频,可以直接通过选择不同的宏定义来直接切换。
使用外部高速晶振配置主频
当使用的外部高速晶振频率不是8M,而是4M、12M、16M等其他频率时,不能直接修改宏定义来配置主频,还需要进行以下修改:
修改HSE_VALUE:将HSE_VALUE改成实际的晶振频率。例如,使用12M晶振时,需修改为“#define HSE_VALUE ((uint32_t)12000000)”。
修改PLL倍频系数寄存器:以12M晶振为例,若要配置主频为72M,需要将PLLMULCFG设置为6,因为12M * 6 = 72M。具体代码示例如下:
cvoid SystemClock_HSE_PLL_Init(void){ uint32_t i; // 等待HSI稳定(可选,根据实际情况决定是否需要) while (RCM->CTRL1_B.HSIRDY == RESET); // 选择HSI作为系统时钟源(临时切换,为配置HSE做准备) RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_HSI); // 禁用PLL RCM_DisablePLL(); // 等待PLL停止 while (RCM->CTRL1_B.PLLRDY == SET); // 配置HSE RCM_ConfigHSE(RCM_HSE_OPEN); for (i = 0; i < HSE_STARTUP_TIMEOUT; i++) { if (RCM->CTRL1_B.HSERDY) { break; } } if (RCM->CTRL1_B.HSERDY) { // 启用Flash预取缓冲区和设置等待周期 FMC_EnablePrefetchBuffer(); FMC_SetWS2(); // 配置AHB分频 RCM_ConfigAHB(RCM_SYSCLK_DIV_1); // 配置APB分频 RCM_ConfigAPB(RCM_HCLK_DIV_1); // 配置PLL源和乘法因子 // 这里假设使用HSE作为PLL源,6倍频 RCM_ConfigPLL(RCM_PLL_SEL_HSE, RCM_PLLMF_6); // 配置时钟分频(如果需要) // RCM_ConfigCLKDIV(RCM_CLK_DIV_2); // 启用PLL RCM_EnablePLL(); // 等待PLL稳定 while (RCM->CTRL1_B.PLLRDY == BIT_RESET); // 选择PLL作为系统时钟源 RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_PLL); // 等待系统时钟源切换完成 while (RCM_CFG1_B.SCLKSWSTS != 0x02); } else { // 可增加HSE启动失败的处理程序 // 例如:可以使用HSI作为系统时钟源,或者进入错误处理流程 }}
使用内部晶振倍频配置主频
如果产品应用对时钟精度要求不高,想不接外部晶振,使用内部晶振倍频到64M,可以按照以下步骤进行操作:
屏蔽默认的使用外部晶振的宏定义:在代码中找到相关的宏定义,将其屏蔽或修改为使用内部晶振的配置。
编写使用内部晶振的时钟初始化函数:以下是一个示例代码,可在main函数中调用该函数进行时钟初始化。
void SystemClock_HSI_PLL_Init(void)
{
RCM_Reset();
// 启用HSI
RCM_EnableHSI();
// 等待HSI就绪
while (RCM->CTRL1_B.HSIRDY == RESET);
// 启用Flash预取缓冲区和设置等待周期
FMC_EnablePrefetchBuffer();
FMC_SetWS2();
// 配置AHB分频
RCM_ConfigAHB(RCM_SYSCLK_DIV_1);
// 配置APB分频
RCM_ConfigAPB(RCM_HCLK_DIV_1);
// 配置PLL,这里使用HSI经过2分频后作为PLL源,16倍频
RCM_ConfigPLL(RCM_PLL_SEL_HSI_DIV2, RCM_PLLMF_16);
// 启用PLL
RCM_EnablePLL();
// 等待PLL稳定
while (RCM->CTRL1_B.PLLRDY == BIT_RESET);
// 选择PLL作为系统时钟源
RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_PLL);
// 等待系统时钟源切换完成
while (RCM_CFG1_B.SCLKSWSTS != 0x02);
}
程序运行中切换主频频率
在某些应用场景中,可能需要在程序运行过程中动态切换主频频率。以下是一个将外部晶振72M的配置切换到36M的示例代码:
void SystemClock_Switch_To_36M(void)
{
uint32_t i;
// 选择HSI作为系统时钟源(临时切换,为重新配置PLL做准备)
RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_HSI);
// 禁用PLL
RCM_DisablePLL();
// 等待PLL停止
while (RCM->CTRL1_B.PLLRDY == SET);
// 配置HSE(如果之前已经配置过,这里可以省略或根据实际情况调整)
RCM_ConfigHSE(RCM_HSE_OPEN);
for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
{
if (RCM->CTRL1_B.HSERDY)
{
break;
}
}
if (RCM->CTRL1_B.HSERDY)
{
// 启用Flash预取缓冲区和设置等待周期
FMC_EnablePrefetchBuffer();
FMC_SetWS2();
// 配置AHB分频
RCM_ConfigAHB(RCM_SYSCLK_DIV_1);
// 配置APB分频
RCM_ConfigAPB(RCM_HCLK_DIV_1);
// 配置PLL源和乘法因子
// 这里假设使用HSE作为PLL源,4.5倍频(实际可能需要根据具体情况调整,例如使用9倍频后分频等)
// 为了得到36M主频,若HSE为8M,可使用4.5倍频(但PLL倍频系数可能需为整数,这里仅为示例说明思路)
// 更合理的可能是使用其他分频和倍频组合,如HSE为8M,先分频为4M,再9倍频得到36M
// 以下代码假设使用HSE直接4.5倍频(实际需根据芯片支持情况修改)
RCM_ConfigPLL(RCM_PLL_SEL_HSE, RCM_PLLMF_9); // 假设9倍频后通过其他方式得到36M,如分频等
// 配置时钟分频(如果需要,例如将PLL输出分频得到36M)
RCM_ConfigCLKDIV(RCM_CLK_DIV_2); // 假设通过2分频得到36M(需根据实际PLL输出调整)
// 启用PLL
RCM_EnablePLL();
// 等待PLL稳定
while (RCM->CTRL1_B.PLLRDY == BIT_RESET);
// 选择PLL作为系统时钟源
RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_PLL);
// 等待系统时钟源切换完成
while (RCM_CFG1_B.SCLKSWSTS != 0x02);
}
else
{
// 可增加HSE启动失败的处理程序
}
}
三、高速时钟配置相关注意事项
时钟源选择注意事项
内部时钟源精度:HSICLK的频率会受到温度、电压等因素的影响,虽然出厂时已经进行了校准,但在对时钟精度要求较高的应用场景中,可能需要进一步校准或选择外部时钟源。
外部时钟源稳定性:使用外部晶体/陶瓷谐振器时,要选择质量可靠的产品,并按照数据手册的要求正确连接和配置。同时,要注意外部时钟源的启动时间,确保在MCU需要时钟信号时已经稳定输出。
有源晶振与无源晶振的区别:有源晶振是一个完整的振荡器,不需要MCU的内部时钟电路,信号稳定,质量较好,输出波形一般为方波;无源晶振则需要结合外部时钟电路组成一个振荡器才能产生振荡信号,信号质量和精度较差,要匹配外部电容和滤波电阻,输出的波形一般都为正弦波。APM32E030可以选择BYPASS Clock Source模式(HSECLK旁路)以匹配外部有源晶振或其他直接时钟输入源,选择Crystal/Ceramic Resonator模式(HSECLK晶体)可以匹配外部无源晶振。
PLL配置注意事项
PLL输入频率范围:PLL的输入频率有一定的范围限制,在使用时要确保外部时钟源或内部时钟源的频率在该范围内。例如,APM32E030的PLL输入频率范围需根据具体配置和芯片要求确定,以保证PLL能够正常工作。
PLL倍频系数选择:在选择PLL倍频系数时,要综合考虑系统对时钟频率的需求、PLL的输出频率范围以及芯片的功耗等因素。过高的倍频系数可能会导致PLL输出信号不稳定,增加功耗;过低的倍频系数则可能无法满足系统对高速时钟的需求。
PLL锁定时间:PLL从启动到稳定输出需要一定的时间,在配置PLL后,要等待PLL稳定后再进行系统时钟源的切换。可以通过查询PLL的状态寄存器来判断PLL是否已经稳定。
系统时钟分频注意事项
AHB、APB分频:系统时钟经过AHB和APB分频后为各个外设提供时钟信号。在配置AHB和APB分频系数时,要根据外设的工作频率要求和系统的整体性能进行合理选择。如果分频系数设置不当,可能会导致外设无法正常工作或系统性能下降。
定时器时钟分配:所有TMRxCLK(定时器时钟)频率分配由硬件按以下2种情况自动设置:如果相应的APB预分频系数是1,定时器的时钟频率与所在APB总线频率一致;否则,定时器的时钟频率被设为与其相连的APB总线频率的2倍。在配置定时器时,要注意这一特性,以确保定时器能够按照预期的频率工作。
Flash等待周期与预取使能注意事项
Flash等待周期设置:随着系统时钟频率的提高,Flash的访问时间可能会变长,需要设置合适的Flash等待周期以确保MCU能够正确读取Flash中的指令和数据。APM32E030的Flash等待周期可以通过FMC(Flash控制器)进行设置,例如在上述时钟配置代码中使用的“FMC_SetWS2()”函数就是设置Flash等待周期为2个周期。
Flash预取使能:启用Flash预取缓冲区可以提高MCU对Flash的访问速度,减少等待时间。在时钟配置时,通常需要启用Flash预取缓冲区,如代码中的“FMC_EnablePrefetchBuffer()”函数。但要注意,在某些特殊情况下,如低功耗模式或对功耗要求极高的应用中,可能需要禁用预取缓冲区以降低功耗。
时钟配置顺序注意事项
在进行时钟配置时,要严格按照一定的顺序进行操作,以确保时钟系统能够正确切换和稳定工作。一般来说,时钟配置的顺序如下:
复位时钟相关寄存器,将时钟系统恢复到默认状态。
选择临时时钟源(如HSI),为配置其他时钟源做准备。
配置目标时钟源(如HSE或PLL),包括启用时钟源、等待时钟源稳定等操作。
配置时钟分频系数,包括AHB、APB分频以及PLL的分频和倍频系数等。
启用目标时钟源(如PLL),并等待其稳定。
选择目标时钟源作为系统时钟源,并等待切换完成。
查看当前时钟配置
如果想知道系统现在的时钟配置是多少,可以参考SDK中的RCB -> RCM_ClockSwitch例程。以下是一个简单的示例代码,用于通过串口打印当前时钟配置:
#include "apm_tiny_com.h" // 假设包含了串口初始化和打印相关的头文件
int main(void)
{
// 初始化串口
APM_TINY_COMInit(COM1);
// 打印系统时钟源
printf("sysSource = %s
", RCM_SYSCLK_SEL_TAB[RCM_ReadSYSCLKSource()]);
// 打印系统时钟频率
// 注意:这个打印是基于HSE_VALUE与实际相符的情况才是准确的,需要注意核对
printf("sysClock = %"PRId32"
", RCM_ReadSYSCLKFreq());
while (1)
{
// 主循环
}
}
四、总结
极海APM32E030 MCU的高速时钟配置是MCU开发中的重要环节,合理的时钟配置能够充分发挥MCU的性能,确保系统稳定运行。本文详细介绍了APM32E030的时钟系统概述、高速时钟配置方法以及相关注意事项,包括时钟源选择、PLL配置、系统时钟分频、Flash等待周期与预取使能、时钟配置顺序等方面的内容。在实际开发中,开发者需要根据具体的应用场景和需求,选择合适的时钟源和配置参数,并严格按照配置顺序进行操作,同时注意时钟配置过程中的各种注意事项,以确保时钟系统的稳定性和可靠性。
责任编辑:David
【免责声明】
1、本文内容、数据、图表等来源于网络引用或其他公开资料,版权归属原作者、原发表出处。若版权所有方对本文的引用持有异议,请联系拍明芯城(marketing@iczoom.com),本方将及时处理。
2、本文的引用仅供读者交流学习使用,不涉及商业目的。
3、本文内容仅代表作者观点,拍明芯城不对内容的准确性、可靠性或完整性提供明示或暗示的保证。读者阅读本文后做出的决定或行为,是基于自主意愿和独立判断做出的,请读者明确相关结果。
4、如需转载本方拥有版权的文章,请联系拍明芯城(marketing@iczoom.com)注明“转载原因”。未经允许私自转载拍明芯城将保留追究其法律责任的权利。
拍明芯城拥有对此声明的最终解释权。

产品分类

2012- 2022 拍明芯城ICZOOM.com 版权所有 客服热线:400-693-8369 (9:00-18:00)