GD32W515系列PLLDIG做系统时钟的配置

1、PLLDIG简介

如图1所示,系统复位后, IRC16M时钟默认做为CK_SYS的时钟源,改变配置寄存器0, RCU_CFG0中的系统时钟变换位SCS可以切换系统时钟源为HXTAL或CK_PLLP或CK_PLLDIG。当SCS的值被改变,系统时钟将使用原来的时钟源继续运行直到转换的目标时钟源稳定。当一个时钟源被直接或通过PLL或PLLDIG间接作为系统时钟时,它将不能被停止。

                                                          图1 W515时钟树部分

 

2、在调试过程中遇到的问题如下:

  2.1 在不用WIFI的情况下,硬件上W515的AVDD33_CLK为RF和外部晶体HSE供电,因此在不用RF功能时其它几个电源脚可不接,这个AVDD33_CLK要接到电源,不然外部晶体没法起振

 2.2 在WIFI运行的时候,需要PLLDIG准确震荡在960MHz。给MCU CORE的输出时钟是960 MHz/2/3/4/5。

 2.3  如果WIFI不需要运行,PLLDIG的VCO可以配置到其他频率,FVCO可以配置为640M-960M中的任何频率。输出给MCU 的时钟就固定是FVCO的/2/3/4/5。

 2.4  外部晶振我们默认40MHz,若改变晶振源数值,如外部晶振为20MHz时,为了满足FVCO可以配置为640M-960M,换晶体后PLLDIG的除数寄存器要对应重新配置,否则无法稳定,注:必须打开RF时钟除数寄存器才可修改成功。

3、PLLDIG做系统时钟时,外设应用需要注意问题

当PLLDIG为主频时,会出现串口乱码情况,以W515 USART2(PB10,PB11)为例;原因如下:固件库中,USART2 默认APB2作为时钟源,而固件库中并没有把PLLDIG作为一个case去计算(如图2),从而导致USART2时钟源错误。修改方法多样,可以增加一个case,将PLLDIG加入,或者也可以直接根据计算把APB2总线频率固定(如图3)。

图2 增加PLLDIG的case修改

                                              图3  固定计算uclk值

4、代码附注:

#define HXTALSTB_DELAY     {                                  \
                              volatile uint32_t i;           \
                              for(i=0; i<0x2000; i++){       \
                              }                              \
                          }
static void switch_system_clock_to_plldig(void)
{
    uint32_t timeout = 0U;
    uint32_t stab_flag = 0U;

    rcu_system_clock_source_config(RCU_CKSYSSRC_PLLDIG);
    rcu_deinit();
    /* power up HXTAL */
    RCU_CTL |= RCU_CTL_HXTALPU;
    /* enable HXTAL */
    RCU_CTL |= RCU_CTL_HXTALEN;
    RCU_CTL |= RCU_CTL_HXTALENPLL;
    HXTALSTB_DELAY
    RCU_CTL |= RCU_CTL_HXTALREADY;

    /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
    do{
        timeout++;
        stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
    }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));

    /* if fail */
    if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
        while(1){
        }
    }
    rcu_plldig_config(RCU_PLLDIG_192M);
    rcu_plldigfsys_div_config(RCU_PLLDIGFSYS_DIV2);

    rcu_bandgap_poweron();
    rcu_plldig_poweron();
    rcu_plldig_enable();

    if(ERROR == rcu_osci_stab_wait(RCU_PLLDIG_CK)){
        while(1){
        }
    }
    
    RCU_APB1EN |= RCU_APB1EN_PMUEN;
    PMU_CTL0 |= PMU_CTL0_LDOVS;

    /* HXTAL is stable */
    /* AHB = SYSCLK */
    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
    /* APB2 = AHB/2 */
    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
    /* APB1 = AHB/4 */
    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;

    /* Configure the main PLL, PSC = 40, PLL_N = 360, PLL_P = 2 */ 
    RCU_PLL = (40U | (360U << 6U) | (((2U >> 1U) - 1U) << 16U) |
                   (RCU_PLLSRC_HXTAL) );

    /* enable PLLDIG */
    RCU_CTL |= RCU_CTL_PLLDIGEN;

    /* wait until PLLDIG is stable */
    while(0U == (RCU_CTL & RCU_CTL_PLLDIGSTB)){
    }

    /* select PLLDIG as system clock */
    RCU_CFG0 &= ~RCU_CFG0_SCS;
    RCU_CFG0 |= RCU_CKSYSSRC_PLLDIG;

    /* wait until PLLDIG is selected as system clock */
    while(0U == (RCU_CFG0 & RCU_SCSS_PLLDIG)){
    }
}

注:代码默认外部晶振40MHz,若客户选择其他数值晶振,需要修改除数寄存器,如有疑问欢迎留言或私信。

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值