返回列表 发新帖我要提问本帖赏金: 10.00元(功能说明)

[综合信息] 华大HC32F460时钟简介

[复制链接]
7679|15
 楼主| binoo7 发表于 2021-1-29 13:46 | 显示全部楼层 |阅读模式
本帖最后由 binoo7 于 2021-1-29 13:55 编辑

#申请原创# @21小跑堂   @21小跑堂    @21小跑堂  


  最近在学习华大的HC32F460单片机,学习单片机就不得不说说单片机的运行时钟,华大这款单片机的时钟有很多的时钟总线,外设都是挂载在时钟线上运行的,
HC32F460的时钟其实就是片内时钟和片外时钟两种
           片内时钟有三种:
                          1.HRC 片内高速时钟
                          2.MRC 片内中速时钟
                          3.LRC 片内低速时钟
                  片外时钟有两种:
                          1.XTAL   片外高速时钟
                          2.XTAL32 片外低速时钟
HC32F460的简介里说了他的时钟工作频率
如下图所示
3567360139f2de8052.png
但是这个怎么配置呢?在用户手册里的开始就有介绍,但是不清晰,我重新整理了一下
6047060139fc84c7b8.png
这张表内就把他说的AHB总线和APB总线时钟在内部是怎么分配的介绍清除了,不明白的同学可以查看用户手册
外设挂在哪个总线上清晰了,那怎么配置时钟是多少合适呢?
有两个方法可以参考,第一参考用户手册,第二参考厂家给的例程
先说用户手册看哪里,给大家一个表
854276013a09754a5d.png
236926013a0a91a68a.png
大家在配置的时候可以根据这个表来配置时钟频率
刚才也说了有第二种方法来配置,怎么配置呢?
大家看下面这个代码,是我自己根据官方给的例程来进行注释说明的,具体如下
  1. static void SysClkConfig(void)
  2. {
  3.     stc_clk_sysclk_cfg_t    stcSysClkCfg;
  4.     stc_clk_xtal_cfg_t      stcXtalCfg;
  5.     stc_clk_mpll_cfg_t      stcMpllCfg;

  6.     MEM_ZERO_STRUCT(stcSysClkCfg);
  7.     MEM_ZERO_STRUCT(stcXtalCfg);
  8.     MEM_ZERO_STRUCT(stcMpllCfg);

  9.     /* Set bus clk div. */
  10.     stcSysClkCfg.enHclkDiv  = ClkSysclkDiv1;  // 100MHz
  11.     stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;  // 50MHz
  12.     stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;  // 100MHz
  13.     stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;  // 50MHz
  14.     stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;  // 25MHz
  15.     stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;  // 25MHz
  16.     stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;  // 50MHz
  17.     CLK_SysClkConfig(&stcSysClkCfg);//时钟分频

  18.     /* Switch system clock source to MPLL. */
  19.     /* Use Xtal as MPLL source. */
  20.     stcXtalCfg.enMode        = ClkXtalModeOsc;//XTAL模式选择位  0:振荡器模式 1:外部时钟输入模式
  21.     stcXtalCfg.enDrv         = ClkXtalLowDrv;/*XTAL驱动能力选择   00:高驱动能力(建议20~24MHz晶振)
  22.                                                                                                                                                                                                                                                                         01:中驱动能力(建议16~20MHz晶振)
  23.                                                                                                                                                                                                                                                                         10:小驱动能力(建议8~16MHz晶振)
  24.                                                                                                                                                                                                                                                                         11:超小驱动能力(建议4~8MHz晶振)*/
  25.     stcXtalCfg.enFastStartup = Enable;//XTAL超高速驱动允许  0:禁止超高速驱动 1:允许超高速驱动 超高速驱动允许时,XTAL稳定后,无视此位设定,禁止超高速驱动,降低功耗。
  26.     CLK_XtalConfig(&stcXtalCfg);//CMU XTAL  配置寄存器
  27.     CLK_XtalCmd(Enable);//开启CMU XTAL  控制寄存器的XTALSTP位 0:XTAL振荡器振荡 1:停止振荡

  28.     /* MPLL config. */
  29.     stcMpllCfg.pllmDiv = 1ul;//MPLL输入时钟分频系数
  30.     stcMpllCfg.plln    =50ul;//MPLL倍频系数
  31.     stcMpllCfg.PllpDiv = 4ul;
  32.     stcMpllCfg.PllqDiv = 4ul;
  33.     stcMpllCfg.PllrDiv = 4ul;
  34.     CLK_SetPllSource(ClkPllSrcXTAL);//CMU MPLL  配置 寄存器的时钟源选择
  35.                                                                                                                                                 /*MPLL/UPLL输入时钟源选择
  36.                                                                                                                                                         0:选择外部高速振荡器作为MPLL/UPLL的输入时钟
  37.                                                                                                                                                         1:选择内部高速振荡器作为MPLL/UPLL的输入时钟*/
  38.     CLK_MpllConfig(&stcMpllCfg);//CMU MPLL  配置 寄存器 时钟分频配置

  39.     /* flash read wait cycle setting */
  40.     EFM_Unlock();
  41.     EFM_SetLatency(5ul);
  42.     EFM_Lock();

  43.     /* Enable MPLL. */
  44.     CLK_MpllCmd(Enable);//用于开始停止MPLL。0:MPLL动作开始 1:MPLL停止

  45.     /* Wait MPLL ready. */
  46.     while(Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
  47.     {
  48.         ;
  49.     }

  50.     /* Switch system clock source to MPLL. */
  51.     CLK_SetSysClkSource(CLKSysSrcMPLL);//CMU  系统时钟源切换寄存器
  52.                                                    /* 0 0 0:选择HRC时钟作为系统时钟     内部高速
  53.                                                                                                                                                                         0 0 1:选择MRC时钟作为系统时钟     内部中速
  54.                                                                                                                                                                         0 1 0:选择LRC时钟作为系统时钟     内部低速
  55.                                                                                                                                                                         0 1 1:选择XTAL时钟作为系统时钟    外部高速
  56.                                                                                                                                                                         1 0 0:选择XTAL32时钟作为系统时钟  外部低速
  57.                                                                                                                                                                         1 0 1:选择MPLL作为系统时钟        倍频
  58.                                                                                                                                                                         1 1 0:禁止设定
  59.                                                                                                                                                                         1 1 1:禁止设定*/

  60. }



打赏榜单

21小跑堂 打赏了 10.00 元 2021-01-29
理由:感谢参与原创奖励活动,请多多加油哦!

 楼主| binoo7 发表于 2021-1-29 13:51 | 显示全部楼层
系统给的例程中配置的是外部高速时钟,外部时钟频率是8M的,选择MPLL作为系统时钟源,进入MPLL之前先通过分频器分频,然后再进行倍频,倍频后再根据不同的需要进行分频,分频后根据不同的外设时钟再进行分频,这样的话就可以配置成不同的外设时钟,在配置的时候安装官方给的例程配置不会出错,因为在配置的时候有很多的注意事项如果各位对他的内部寄存器和时钟比较清晰可以单独配置寄存器,如果不太清楚的话就先学习,学习会了再根据自己的需要来配置时钟,大家有什么疑问可以在帖子下面留言,我看到后会尽快回复大家
 楼主| binoo7 发表于 2021-1-29 14:10 | 显示全部楼层
是不是还没有看懂?
那我再给大家剖析一下,这次加点图片展示,应该就理解了
首先大家看下面这张图片
736386013a3ee3de91.png
这张图片我把内部时钟用紫色的框起来了,外部时钟用红色框起来了,
这就解释了时钟:内部3种,外部两种
这次以外部高速时钟为例
大家看下面这张图
59196013a513497f4.png
首先外部高速时钟进来,通过选择器进行选择,这里选择有两个第一是外部高速时钟,第二是内部高速时钟作为PLL的时钟源,这里我们选择的是外部高速时钟,
外部高速时钟进入PLL之前需要进行分频,为什么要分频呢?应该是消除外部干扰,比如8M的外部高速时钟进入后,进行8分频,这样的话就得到了1M的时钟,
然后这1M的时钟再进行倍频,倍频后就得到了一个特别高速的时钟,
这个时钟是无法进行使用的,因为频率太快了,
所以还有进行再次的分频,分频后的时钟呢就可以作为系统时钟来使用了,
系统时钟有了,我们再根据AHP和APB上外设的不同,对系统时钟进行分频处理,
这样就得到了我们所需要的外设时钟了,然后根据不同的时钟进行通信。
总结一下:
               外部高速时钟
                      ↓
                   分频
                      ↓
                   倍频
                      ↓
            选择为系统时钟
                      ↓
            系统时钟分频
                      ↓
     不同的外设时钟总线再次分频
                      ↓
                    结束

评分

参与人数 1威望 +2 收起 理由
q87112 + 2 主板的文章没看到自己想要的东西,到这个箭头图才看到自己想要的东西,给力!!!

查看全部评分

mzd1207 发表于 2021-1-29 22:37 | 显示全部楼层
系统给的例程中配置的是外部高速时钟,外部时钟频率是8M的
麻花油条 发表于 2021-2-22 17:02 | 显示全部楼层
楼主优秀,棒棒哒
余三水 发表于 2021-2-22 19:01 | 显示全部楼层
这个原创是不是有点简单啦?不过还是支持原创的。
starforeye 发表于 2021-3-10 20:01 | 显示全部楼层
Set bus clk div.
这部分,是分那个频
如果是8M晶振,系统时钟是400M吗?
wziyi 发表于 2021-3-10 23:04 | 显示全部楼层
学习了
Essex 发表于 2021-5-13 11:07 | 显示全部楼层
我就是这样设置的,外部晶振作为时钟输入。但是很奇怪,我短接晶振引脚,单片机居然没有死,仍然在继续运行。不知道是我哪里设置的不对吗?
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);
}

评论

看手册上说,当外部晶振出现错误时候,芯片会自动切换到内部HRC 8Mhz的时钟源。所以应该还可以运行  发表于 2023-1-17 08:52
zhjun 发表于 2021-6-21 19:10 | 显示全部楼层
谢谢,总结的好,刚学习正好用上
ming_hu 发表于 2021-6-22 13:08 | 显示全部楼层
CAN使用时钟是哪里来的?
littlelida 发表于 2021-7-10 16:14 | 显示全部楼层
后来补充的这个时钟图很好,
要做的就是把每一个节点配置好,
是倍频,分频?
每一个MCU的时钟,其实都是通过这个图来计算的
 楼主| binoo7 发表于 2021-8-3 12:31 | 显示全部楼层
ming_hu 发表于 2021-6-22 13:08
CAN使用时钟是哪里来的?

233756108c6b87eff8.png
yongwong9901 发表于 2022-4-26 18:27 | 显示全部楼层
研究了好几天,看到这个贴算是总结了
MAA256 发表于 2022-5-24 08:46 | 显示全部楼层
精品贴
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

457

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部