打印
[技术问答]

关于HC32F460的XTAL时钟设置的奇怪问题

[复制链接]
7381|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
各位大佬好!本人最近在摸索HC32F460的使用,其中在配置HC32F460使用外部晶体作为时钟时有个奇怪的问题,让我百思不得其解。
我选用的外部晶体是12M,我程序里通过锁相环的设置让系统时钟达到200MHz。并通过MCO口的时钟输出观察设置是否正常。按道理,除了锁相环的相关设置外,我还更改了两个地方,一个是Keil工程设置里的XTAL改成了12MHz,另一处是华大库函数文件system_hc32f460.h里的宏定义语句#define XTAL_VALUE ((uint32_t)8000000),我把8改成了12。
结果程序死活配置不成功。示波器看MCO就是1M(是内部MRC的输出)。最后没辙了,我一点点往回改,终于发现,当把system_hc32f460.h里的宏定义语句改回原来的#define XTAL_VALUE ((uint32_t)8000000)后,烧写程序仿真居然对了!MCO输出实测是25MHz,正是我期望的200M锁相环时钟的8分频输出,可我明明用的是12M的XTAL啊!我反复实验了几次,确认无疑,就是这个宏定义语句#define XTAL_VALUE ((uint32_t)8000000)绝对不能改!不管你实际用的什么频率,就要写8M,才能配置成功!
这是为什么呢?求教啊!



使用特权

评论回复
沙发
lavion| | 2021-6-28 02:12 | 只看该作者
你还要去更改 时钟倍频之类的参数。   系统默认的设定 是根据 8M然后 *25=200M。 你直接改12M,岂不是 12*25=300M ,直接超频50%,能成功才怪

使用特权

评论回复
评论
axman002 2021-7-2 10:27 回复TA
@martinhu :嗯,你这个解释靠谱,应该是这样 
martinhu 2021-6-29 09:51 回复TA
@axman002 :库函数有规则检查的,超过480M就不会通过,也不会给你配置。这就是你觉得为什么宏定义XTAL_VALUE必须写8M的原因,实际上你是骗过了规则检查,但是这样超规格使用容易出问题!!!! 
martinhu 2021-6-29 09:08 回复TA
@axman002 :不按手册操作,使用起来不心虚吗 
axman002 2021-6-28 16:54 回复TA
@martinhu :虽然手册上写了PLL最大输出480MHz,但是我用倍频到600M再三分频到200M的写法的确配置成功了,一切工作频率正常(只是那个宏定义XTAL_VALUE必须写8M) 
martinhu 2021-6-28 09:09 回复TA
思路是对的,不过PLL要先倍频至240M~400M,然后通过PLLQ分频到200M以下, 
板凳
axman002|  楼主 | 2021-6-28 16:51 | 只看该作者
lavion 发表于 2021-6-28 02:12
你还要去更改 时钟倍频之类的参数。   系统默认的设定 是根据 8M然后 *25=200M。 你直接改12M,岂不是 12*2 ...

不,你没有理解我的表述。锁相环这些我都配置好了,我是用12M晶体从600M三分频变下来到200M的,如果我不改那个宏XTAL_VALUE的宏定义,即保持8M的写法,那么实测工作频率正常。反之,我按照实际情况修改宏定义为12M,则配置失败。这真是很奇怪啊!

使用特权

评论回复
地板
chnchmhgw| | 2021-6-28 17:29 | 只看该作者
你好,你的外部晶振12Mhz如何配置修改的?
我目前也是修改了system_hc32f460.h的宏定义, XTAL_VALUE由8Mhz改为12Mhz, keil工程配置XTAL改为12Mhz;

其中,时钟初始化函数如下;
目前串口打印无输出,gpio翻转测试,没有测量到信号。当前使用的内部HRC时钟。请问,外部XTAL的12M还在如何调通,多谢大侠!!

static void ClkInit(void)
        {
                stc_clk_xtal_cfg_t         stcXtalCfg;
                stc_clk_mpll_cfg_t         stcMpllCfg;
                en_clk_sys_source_t  enSysClkSrc;
                stc_clk_sysclk_cfg_t stcSysClkCfg;
       
                MEM_ZERO_STRUCT(enSysClkSrc);
                MEM_ZERO_STRUCT(stcSysClkCfg);
                MEM_ZERO_STRUCT(stcXtalCfg);
                MEM_ZERO_STRUCT(stcMpllCfg);
       
                /* Set bus clk div. */
                stcSysClkCfg.enHclkDiv        = ClkSysclkDiv1;//100M
                stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;//50M
                stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;//100M
                stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;//50M
                stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;//25M
                stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;//25M
                stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;//50M
                CLK_SysClkConfig(&stcSysClkCfg);
       
                /* Switch system clock source to MPLL. */
                /* Use Xtal as MPLL source. */
                stcXtalCfg.enMode = ClkXtalModeOsc;
                stcXtalCfg.enDrv = ClkXtalLowDrv;
                stcXtalCfg.enFastStartup = Enable;
                CLK_XtalConfig(&stcXtalCfg);
                CLK_XtalCmd(Enable);
       
                /* MPLL config. */
                stcMpllCfg.pllmDiv = 2u; /* XTAL 12M / 2 */
                stcMpllCfg.plln = 50u;         /* 6M*50 = 300M */
                stcMpllCfg.PllpDiv = 3u; /* MLLP = 100M */
                stcMpllCfg.PllqDiv = 3u; /* MLLQ = 100M */
                stcMpllCfg.PllrDiv = 3u; /* MLLR = 100M */
                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(CLKSysSrcMPLL);
        }

使用特权

评论回复
5
axman002|  楼主 | 2021-6-28 18:49 | 只看该作者
chnchmhgw 发表于 2021-6-28 17:29
你好,你的外部晶振12Mhz如何配置修改的?
我目前也是修改了system_hc32f460.h的宏定义, XTAL_VALUE由8Mhz ...

你仔细看我的说明,程序本身都是调用华大的库函数,没什么区别,但是那个宏定义我一开始也改成12M,结果死活不能成功。后来还是改回8M,就OK了!我也是莫名其妙,我的确用的12M晶体,而且还采用了PLL到600M的写法,居然也成功了!但是那个宏定义还就必须写8M!我也弄不清楚原因

使用特权

评论回复
评论
martinhu 2021-6-29 09:48 回复TA
楼主为什么一定要设置倍频到600M啊!!!!!!库函数有规则检查的, XTAL_VALUE需要改为12M,然后PLL倍频需要设置在240M~480M之间再分频下来,你如果设置600M,规则检查过不了!!!!!所以不成功,改成8M只是自欺欺人,实际上是超规格使用,如果出问题只能自己流泪了…… 
6
chnchmhgw| | 2021-6-29 09:14 | 只看该作者
axman002 发表于 2021-6-28 18:49
你仔细看我的说明,程序本身都是调用华大的库函数,没什么区别,但是那个宏定义我一开始也改成12M,结果 ...

亲,可以把你时钟配置的函数贴出来参考一下吗?外部晶振使用12Mhz。
我看下和你的异同,调试修改下,多谢!!!

使用特权

评论回复
7
martinhu| | 2021-6-29 09:47 | 只看该作者
axman002 发表于 2021-6-28 18:49
你仔细看我的说明,程序本身都是调用华大的库函数,没什么区别,但是那个宏定义我一开始也改成12M,结果 ...

库函数有规则检查的, XTAL_VALUE需要改为12M,然后PLL倍频需要设置在240M~480M之间再分频下来,你如果设置600M,规则检查过不了!!!!!所以不成功,改成8M只是自欺欺人,实际上是超规格使用,如果出问题只能自己流泪了……

使用特权

评论回复
8
chnchmhgw| | 2021-6-29 14:24 | 只看该作者
martinhu 发表于 2021-6-29 09:47
库函数有规则检查的, XTAL_VALUE需要改为12M,然后PLL倍频需要设置在240M~480M之间再分频下来,你如果设 ...

你好,大牛 martinhu。
参考4楼-地板的时钟初始化配置,看看是否正确,我这边配置的外部晶振12Mhz,时钟初始化之后;
没有串口调试输出,也没有gpio在定时器的翻转信号波形。
但是使用hc32f460jeua的内部HRC,就有调试串口输出和gpio翻转测试信号。

使用特权

评论回复
9
axman002|  楼主 | 2021-6-30 19:21 | 只看该作者
martinhu 发表于 2021-6-29 09:47
库函数有规则检查的, XTAL_VALUE需要改为12M,然后PLL倍频需要设置在240M~480M之间再分频下来,你如果设 ...

好的,那我明天再试下12M/3*100/2这样的设置,这总满足要求了,然后再看看XTAL——VALUE是不是可以改成12M了

使用特权

评论回复
10
chnchmhgw| | 2021-7-2 09:20 | 只看该作者
axman002 发表于 2021-6-30 19:21
好的,那我明天再试下12M/3*100/2这样的设置,这总满足要求了,然后再看看XTAL——VALUE是不是可以改成12 ...

你好,验证测试的怎么样?
从逻辑上来看,该修改的地方也修改了;PLL锁相环配置应该也没问题。
另外,我也尝试MLL另一种分频测试方案( XTAL / (pllmDiv=1) * (plln=30) / (PllqDiv=2) ),也没成功。debug单步调试,停在如下地方(见截图):

debug单步调试停止地方1.png (69.94 KB )

debug单步调试停止地方1.png

debug单步调试停止地方2.png (36.08 KB )

debug单步调试停止地方2.png

使用特权

评论回复
11
axman002|  楼主 | 2021-7-2 10:25 | 只看该作者
chnchmhgw 发表于 2021-7-2 09:20
你好,验证测试的怎么样?
从逻辑上来看,该修改的地方也修改了;PLL锁相环配置应该也没问题。
另外,我 ...

你的PLL频率是180M吗?如果这样,你的FLASH等待时间设置不对。用户手册P.237说HCLK在168~200M之间,要插入5个等待周期。所以你应该写EFM_SetLatency(EFM_LATENCY_5)而不是EFM_SetLatency(EFM_LATENCY_4)!

使用特权

评论回复
12
chnchmhgw| | 2021-7-6 15:26 | 只看该作者
你好,PLL的频率是180Mhz。
Flash等待时间尝试修改了,根据建议,由EFM_SetLatency(EFM_LATENCY_4)改为EFM_SetLatency(EFM_LATENCY_5)。修改后,仍然没有效果。
我司采用的外部晶振为12MHz有源晶振,华大hc32f460的外部的晶振为8MHz无源晶振,是否哪里还需特殊配置?

我司的晶振模块原理图如下图所示:手册的外部时钟输入说明如下:


有源晶振原理图设计.jpg (68.31 KB )

有源12M晶振设计

有源12M晶振设计

外部有源晶振设置说明.png (95.45 KB )

用户手册的外部时钟设置说明

用户手册的外部时钟设置说明

使用特权

评论回复
13
axman002|  楼主 | 2021-7-6 16:20 | 只看该作者
chnchmhgw 发表于 2021-7-6 15:26
你好,PLL的频率是180Mhz。
Flash等待时间尝试修改了,根据建议,由EFM_SetLatency(EFM_LATENCY_4)改为EFM_ ...

我用的12M晶体是工作正常的。我就直接把我的配置代码主要部分贴在这你看看有哪里不一样吧:
    /* Set bus clk div. */
    stcSysClkCfg.enHclkDiv = ClkSysclkDiv1;     //HCLK:200M
    stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;    //Exclk:100M
    stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;    //Pclk0:200M
    stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;    //Pclk1:100M
    stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;    //Pclk2:50M
    stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;    //Pclk3:50M
    stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;    //Pclk4:100M
    CLK_SysClkConfig(&stcSysClkCfg);

        XtalInit();    //Xtal的配置
        CLK_SetSysClkSource(ClkSysSrcXTAL);  //切换到XTAL
        MpllInit();
        while(CLK_GetFlagStatus(ClkFlagMPLLRdy)!=Set)   //等待锁相环稳定
        {}
       CLK_SetSysClkSource(CLKSysSrcMPLL);

这样就行了。其中的几个函数均直接来自华大的库函数文件(分频系数按实际情况做了修改)

使用特权

评论回复
14
chnchmhgw| | 2021-7-8 14:25 | 只看该作者
axman002 发表于 2021-7-6 16:20
我用的12M晶体是工作正常的。我就直接把我的配置代码主要部分贴在这你看看有哪里不一样吧:
    /* Set b ...

昨天细看了代码,定位到原因,配置12Mhz的外部有源晶振,hc32f460运行起来,串口也有了输出打印。
华大hc32f460的官方板使用8Mhz无源晶振,关键点如下:
8M无源晶振配置:stcXtalCfg.enMode = ClkXtalModeOsc;
12M有源晶振配置:stcXtalCfg.enMode = ClkXtalModeExtClk;

           /* Switch system clock source to MPLL. */
            /* Use Xtal as MPLL source. */
            /* active crystal:ClkXtalModeExtClk,passive crystal:ClkXtalModeOsc */
                stcXtalCfg.enMode = ClkXtalModeExtClk;
                stcXtalCfg.enDrv = ClkXtalLowDrv;
                stcXtalCfg.enFastStartup = Enable;
                CLK_XtalConfig(&stcXtalCfg);
                CLK_XtalCmd(Enable);

以上问题解决。

配置12MHz有源晶振,具体配置总结如下:
(1)system_hc32f460.h的宏定义, XTAL_VALUE由8Mhz改为12Mhz
(2)keil工程配置XTAL改为12Mhz
(3)时钟初始化代码,stcXtalCfg.enMode = ClkXtalModeExtClk;(重点)
(4)PLL锁相环按照手册要求配置,在频率范围内

以上就是注意细节点。欢迎交流讨论。

使用特权

评论回复
评论
martinhu 2021-7-8 16:01 回复TA
原来是有源晶振啊…… 
15
wakayi| | 2021-8-6 20:51 | 只看该作者
这个速度会不会太快

使用特权

评论回复
16
aoyi| | 2021-8-6 20:53 | 只看该作者
这个问题的出现和解决非常值得借鉴啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

36

帖子

0

粉丝