华大HC32F460时钟简介
本帖最后由 binoo7 于 2021-1-29 13:55 编辑#申请原创# @21小跑堂 @21小跑堂 @21小跑堂
最近在学习华大的HC32F460单片机,学习单片机就不得不说说单片机的运行时钟,华大这款单片机的时钟有很多的时钟总线,外设都是挂载在时钟线上运行的,
HC32F460的时钟其实就是片内时钟和片外时钟两种
片内时钟有三种:
1.HRC 片内高速时钟
2.MRC 片内中速时钟
3.LRC 片内低速时钟
片外时钟有两种:
1.XTAL 片外高速时钟
2.XTAL32 片外低速时钟
在HC32F460的简介里说了他的时钟工作频率
如下图所示
但是这个怎么配置呢?在用户手册里的开始就有介绍,但是不清晰,我重新整理了一下
这张表内就把他说的AHB总线和APB总线时钟在内部是怎么分配的介绍清除了,不明白的同学可以查看用户手册
外设挂在哪个总线上清晰了,那怎么配置时钟是多少合适呢?
有两个方法可以参考,第一参考用户手册,第二参考厂家给的例程
先说用户手册看哪里,给大家一个表
大家在配置的时候可以根据这个表来配置时钟频率
刚才也说了有第二种方法来配置,怎么配置呢?
大家看下面这个代码,是我自己根据官方给的例程来进行注释说明的,具体如下
static void SysClkConfig(void)
{
stc_clk_sysclk_cfg_t stcSysClkCfg;
stc_clk_xtal_cfg_t stcXtalCfg;
stc_clk_mpll_cfg_t stcMpllCfg;
MEM_ZERO_STRUCT(stcSysClkCfg);
MEM_ZERO_STRUCT(stcXtalCfg);
MEM_ZERO_STRUCT(stcMpllCfg);
/* Set bus clk div. */
stcSysClkCfg.enHclkDiv= ClkSysclkDiv1;// 100MHz
stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;// 50MHz
stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;// 100MHz
stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;// 50MHz
stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;// 25MHz
stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;// 25MHz
stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;// 50MHz
CLK_SysClkConfig(&stcSysClkCfg);//时钟分频
/* Switch system clock source to MPLL. */
/* Use Xtal as MPLL source. */
stcXtalCfg.enMode = ClkXtalModeOsc;//XTAL模式选择位0:振荡器模式 1:外部时钟输入模式
stcXtalCfg.enDrv = ClkXtalLowDrv;/*XTAL驱动能力选择 00:高驱动能力(建议20~24MHz晶振)
01:中驱动能力(建议16~20MHz晶振)
10:小驱动能力(建议8~16MHz晶振)
11:超小驱动能力(建议4~8MHz晶振)*/
stcXtalCfg.enFastStartup = Enable;//XTAL超高速驱动允许0:禁止超高速驱动 1:允许超高速驱动 超高速驱动允许时,XTAL稳定后,无视此位设定,禁止超高速驱动,降低功耗。
CLK_XtalConfig(&stcXtalCfg);//CMU XTAL配置寄存器
CLK_XtalCmd(Enable);//开启CMU XTAL控制寄存器的XTALSTP位 0:XTAL振荡器振荡 1:停止振荡
/* MPLL config. */
stcMpllCfg.pllmDiv = 1ul;//MPLL输入时钟分频系数
stcMpllCfg.plln =50ul;//MPLL倍频系数
stcMpllCfg.PllpDiv = 4ul;
stcMpllCfg.PllqDiv = 4ul;
stcMpllCfg.PllrDiv = 4ul;
CLK_SetPllSource(ClkPllSrcXTAL);//CMU MPLL配置 寄存器的时钟源选择
/*MPLL/UPLL输入时钟源选择
0:选择外部高速振荡器作为MPLL/UPLL的输入时钟
1:选择内部高速振荡器作为MPLL/UPLL的输入时钟*/
CLK_MpllConfig(&stcMpllCfg);//CMU MPLL配置 寄存器 时钟分频配置
/* flash read wait cycle setting */
EFM_Unlock();
EFM_SetLatency(5ul);
EFM_Lock();
/* Enable MPLL. */
CLK_MpllCmd(Enable);//用于开始停止MPLL。0:MPLL动作开始 1:MPLL停止
/* Wait MPLL ready. */
while(Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
{
;
}
/* Switch system clock source to MPLL. */
CLK_SetSysClkSource(CLKSysSrcMPLL);//CMU系统时钟源切换寄存器
/* 0 0 0:选择HRC时钟作为系统时钟 内部高速
0 0 1:选择MRC时钟作为系统时钟 内部中速
0 1 0:选择LRC时钟作为系统时钟 内部低速
0 1 1:选择XTAL时钟作为系统时钟 外部高速
1 0 0:选择XTAL32时钟作为系统时钟外部低速
1 0 1:选择MPLL作为系统时钟 倍频
1 1 0:禁止设定
1 1 1:禁止设定*/
}
系统给的例程中配置的是外部高速时钟,外部时钟频率是8M的,选择MPLL作为系统时钟源,进入MPLL之前先通过分频器分频,然后再进行倍频,倍频后再根据不同的需要进行分频,分频后根据不同的外设时钟再进行分频,这样的话就可以配置成不同的外设时钟,在配置的时候安装官方给的例程配置不会出错,因为在配置的时候有很多的注意事项如果各位对他的内部寄存器和时钟比较清晰可以单独配置寄存器,如果不太清楚的话就先学习,学习会了再根据自己的需要来配置时钟,大家有什么疑问可以在帖子下面留言,我看到后会尽快回复大家 是不是还没有看懂?
那我再给大家剖析一下,这次加点图片展示,应该就理解了
首先大家看下面这张图片
这张图片我把内部时钟用紫色的框起来了,外部时钟用红色框起来了,
这就解释了时钟:内部3种,外部两种
这次以外部高速时钟为例
大家看下面这张图
首先外部高速时钟进来,通过选择器进行选择,这里选择有两个第一是外部高速时钟,第二是内部高速时钟作为PLL的时钟源,这里我们选择的是外部高速时钟,
外部高速时钟进入PLL之前需要进行分频,为什么要分频呢?应该是消除外部干扰,比如8M的外部高速时钟进入后,进行8分频,这样的话就得到了1M的时钟,
然后这1M的时钟再进行倍频,倍频后就得到了一个特别高速的时钟,
这个时钟是无法进行使用的,因为频率太快了,
所以还有进行再次的分频,分频后的时钟呢就可以作为系统时钟来使用了,
系统时钟有了,我们再根据AHP和APB上外设的不同,对系统时钟进行分频处理,
这样就得到了我们所需要的外设时钟了,然后根据不同的时钟进行通信。
总结一下:
外部高速时钟
↓
分频
↓
倍频
↓
选择为系统时钟
↓
系统时钟分频
↓
不同的外设时钟总线再次分频
↓
结束
系统给的例程中配置的是外部高速时钟,外部时钟频率是8M的 楼主优秀,棒棒哒 这个原创是不是有点简单啦?不过还是支持原创的。 Set bus clk div.
这部分,是分那个频
如果是8M晶振,系统时钟是400M吗? 学习了 我就是这样设置的,外部晶振作为时钟输入。但是很奇怪,我短接晶振引脚,单片机居然没有死,仍然在继续运行。不知道是我哪里设置的不对吗?
void SystemClk_Init(void)
{
stc_clk_sysclk_cfg_t stcSysClkCfg;
stc_clk_xtal_cfg_t stcXtalCfg;
stc_clk_mpll_cfg_t stcMpllCfg;
MEM_ZERO_STRUCT(stcSysClkCfg);
MEM_ZERO_STRUCT(stcXtalCfg);
MEM_ZERO_STRUCT(stcMpllCfg);
/* Set bus clk div. */
stcSysClkCfg.enHclkDiv = ClkSysclkDiv1; // 168MHz
stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;// 84MHz
stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;// 168MHz
stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;// 84MHz
stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;// 42MHz
stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;// 42MHz
stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;// 84MHz
CLK_SysClkConfig(&stcSysClkCfg);
/* Switch system clock source to MPLL. */
/* Use Xtal as MPLL source. */
stcXtalCfg.enMode = ClkXtalModeOsc;
stcXtalCfg.enDrv = ClkXtalLowDrv;
stcXtalCfg.enFastStartup = Disable;
CLK_XtalConfig(&stcXtalCfg);
CLK_XtalCmd(Enable);
/* MPLL config. */
stcMpllCfg.pllmDiv = 1u;
stcMpllCfg.plln = 42u;
stcMpllCfg.PllpDiv = 2u;
stcMpllCfg.PllqDiv = 2u;
stcMpllCfg.PllrDiv = 2u;
CLK_SetPllSource(ClkPllSrcXTAL);
CLK_MpllConfig(&stcMpllCfg);
/* flash read wait cycle setting */
EFM_Unlock();
EFM_SetLatency(EFM_LATENCY_4);
EFM_Lock();
/* Enable MPLL. */
CLK_MpllCmd(Enable);
/* Wait MPLL ready. */
while (Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
{
}
/* Switch system clock source to MPLL. */
CLK_SetSysClkSource(ClkSysSrcXTAL);
} 谢谢,总结的好,刚学习正好用上 CAN使用时钟是哪里来的? 后来补充的这个时钟图很好,
要做的就是把每一个节点配置好,
是倍频,分频?
每一个MCU的时钟,其实都是通过这个图来计算的 ming_hu 发表于 2021-6-22 13:08
CAN使用时钟是哪里来的?
研究了好几天,看到这个贴算是总结了 精品贴
页:
[1]