本帖最后由 GD32爱好者111 于 2023-4-3 11:07 编辑
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,若客户选择其他数值晶振,需要修改除数寄存器,如有疑问欢迎留言或私信。
|