锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

GD32F4(5):GD32F450时钟配置为200M过程分析

时间:2022-11-07 19:30:00 220f450v5a三极管f450光电开关传感器

GD32F450时钟树分析

文章目录

  • GD32F450时钟树分析
    • 1. 系统环境
    • 2. 时钟树图
    • 3. GD32F时钟配置函数450
      • 3.1 SystemInit函数
      • 3.2 system_clock_config函数
      • 3.3 system_clock_200m_25m_hxtal函数
      • 3.4 根据程序中的配置,绘制配置后的时钟路线图

1. 系统环境

2. 时钟树图

任何一个MCU,熟悉时钟树,熟悉时钟树,熟悉时钟树mcu需要修改时钟配置。

对于GD32F其时钟控制单元提供了一系列频率的时钟功能,包括:

  • 外部高速晶体振荡器时钟(HXTAL)。
  • 外部低速晶体振荡器时钟(LXTAL),一般接32.768K晶振
  • 一个内部48M RC振荡器时钟(IRC48M),这个48M时钟校准控制器(CTC)和USB提供时钟。
  • 一个内部16M RC振荡器时钟(IRC16M。
  • 一个内部32K RC振荡器时钟(IRC32K)。
  • 三个相环(PLL)、一个HXTAL时钟监视器(CKM)、时钟预分频器、时钟多路复用器和时钟门控电路。

GD32F4系列MCU时钟树如下图所示:
在这里插入图片描述

AHB、APB1、AHB2和Cortex-M4时钟来自系统时钟(CK_SYS),可以选择系统时钟的时钟源IRC16M、 HXTAL或PLL。

最大运行时钟频率为240MHz,但数据手册显示GD32F450最高可达到200M,GD32F470最高到达240M。

独立看门狗定时器有独立的时钟源(IRC32K),实时时钟(RTC)使用IRC32K、 LXTAL或HXTAL的分频(通过配置RCU_CFG0寄存器的RTCDIV位)作为时钟源。

3. GD32F时钟配置函数450

首先,让我们简要描述一下GD32F关于450的启动过程,GD32F对450编译和启动过程的详细分析,我将写另一篇文章,重点是记录官方带来的内容demo如何将程序GD32F450时钟配置到200M的。

startup_gd32f450.s文件中有以下汇编代码:

;/* reset Handler */ Reset_Handler   PROC                 EXPORT  Reset_Handler                     [WEAK]                 IMPORT  SystemInit                 IMPORT  __main                 LDR     R0, =SystemInit  ;将SystemInit函数地址加载到R0寄存器                 BLX     R0     ;执行SystemInit设置时钟,执行后返回                 LDR     R0, =__main      ;将__main加载函数地址R0寄存器                 BX      R0     ;执行__main函数,不再返回,__main用户将被重新调用main从此,函数进入用户编写的程序                 ENDP 

和STM32的启动过程相同,芯片上电先调用Reset_Handler,Reset_Handler会调用两个函数,一个是SystemInit配置系统时钟,另一个是__main,本章重点介绍SystemInit函数;

时钟的配置由三个函数完成,SystemInit执行会调用system_clock_configsystem_clock_config执行在调用system_clock_200m_25m_hxtal,最后完成200M具体的时钟配置函数和内部代码逻辑如下:

3.1 SystemInit函数

void SystemInit (void) { 
           /* FPU settings ------------------------------------------------------------*/   #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)///默认不开始     ///     SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Acess */
    //其实这个CP10、CP11并不是真正的寄存器,它其实是协处理器的名字,ARM拥有16个协处理器,常被命名为CP0—CP15,其中CP0—CP7由厂家定义协处理功能,而CP8—CP15预留给ARM使用,CP15提供一些系统控制功能,这包括体系结构和特征识别,以及控制、状态信息和配置支持,还提供了性能监视器寄存器。CP14主要提供debug系统的控制、Thumb执行环境、字节码执行。CP10、CP11 两个协处理器一起,提供了浮点运算和向量操作,以及高级的 SIMD 指令扩展。协处理器8、9、12和13预留给ARM将来使用。因为协处理器是协助内核的,16个协处理器共提供出16*32位,基本每个位都有其相应的功能(不使用的位除外),我们平时都接触不到,因此我们平时都忽略它。
  #endif
  /* Reset the RCU clock configuration to the default reset state ------------*/
  /* Set IRC16MEN bit */
  //选择内部16M时钟 
  RCU_CTL |= RCU_CTL_IRC16MEN;
  //将时钟进行2分频,等待时钟稳定,这里会等待的久一点,
  RCU_MODIFY
  //上面程序的目的是设置当前系统内核的时钟,此时系统的时钟为8M
      
  //下面的Reset都是关闭操作,将各种时钟模块的使能全部关闭,变成失能
  /* Reset CFG0 register */
  RCU_CFG0 = 0x00000000U;

  /* Reset HXTALEN, CKMEN and PLLEN bits */
  //关闭外部高速时钟、高速时钟时钟监视器(CKM)、PLL锁相环使能
  RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);

  /* Reset PLLCFGR register */
  RCU_PLL = 0x24003010U;

  /* Reset HSEBYP bit */
  RCU_CTL &= ~(RCU_CTL_HXTALBPS);

  /* Disable all interrupts */
  RCU_INT = 0x00000000U;
         
  /* Configure the System clock source, PLL Multiplier and Divider factors, AHB/APBx prescalers and Flash settings ----------------------------------*/
  //进入时钟配置,重新配置系统相关时钟
  system_clock_config();
}

3.2 system_clock_config函数

static void system_clock_config(void)
{ 
        
...
#elif defined (__SYSTEM_CLOCK_200M_PLL_25M_HXTAL)
    //利用外部高速时钟(评估板带的是25M晶振),配置系统时钟为200M
    system_clock_200m_25m_hxtal();
#endif 
}

3.3 system_clock_200m_25m_hxtal函数

static void system_clock_200m_25m_hxtal(void)
{ 
        
    uint32_t timeout = 0U;
    uint32_t stab_flag = 0U;
    
    /* enable HXTAL */
    //开启外部高速时钟
    RCU_CTL |= RCU_CTL_HXTALEN;

    /* 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 */
    //若外部高速时钟异常,上面等待超时,则进入这里永远等待,系统会卡在while(1)里面
    if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ 
        
        while(1){ 
        
            //我感觉这里不合理,按理说外部时钟异常,应该触发相应的中断,并自动切换到内部高速时钟运行,而不是卡在这里。以后我有时间会把这个函数改改,现在先这样用吧。
            
        }
    }
    //运行到这里,说明外部高速时钟正常启动,下面就要按照时钟树,来配置系统和各个模块的时钟 
    
    RCU_APB1EN |= RCU_APB1EN_PMUEN;//使能APB1总线
    PMU_CTL |= PMU_CTL_LDOVS;//配置使能内部电压调节器1.2V域供电

    //时钟的配置原则应该是从内向外,对照时钟树图,就可以非常清楚的明白时钟配置过程
    /* HXTAL is stable */
    /* AHB = SYSCLK */
    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;//系统SYS时钟到AHB总线时钟不进行分频
    /* APB2 = AHB/2 */
    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;//APB2是AHB的2分频
    /* APB1 = AHB/4 */
    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;//APB1是AHB的4分频
	//GD32F450有3个PLL(PLL、PLLI2S、PLLSAI),这里只配置了一个PLL,
    //现在外部晶振时钟是25M,通过PSC的25分频,变成1M,然后再PLL内倍频400倍,变成400M,然后再经过P进行2分频,变成200M,传给系统时钟。同时400M还进行了Q的9分频,产生大约48M的CK48M给USB提供时钟去了。
    //当更换外部晶振的频率后的时候,通过修改PSC就可以进行匹配了
    /* Configure the main PLL, PSC = 25, PLL_N = 400, PLL_P = 2, PLL_Q = 9 */ 
    RCU_PLL = (25U | (400U << 6U) | (((2U >> 1U) - 1U) << 16U) |
                   (RCU_PLLSRC_HXTAL) | (9U << 24U));

    /* enable PLL */
    RCU_CTL |= RCU_CTL_PLLEN;//上面配置完了,就要使能PLL

    /* wait until PLL is stable */
    //等待PLL配置时钟稳定下来
    while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ 
        
    }
    //在用户手册3.3.4章节,说如果1.2V电源域工作在高频状态下,且打开了多种功能,建议进入高驱动模式。
    /* Enable the high-drive to extend the clock frequency to 200 Mhz */
    //使能高驱动模式
    PMU_CTL |= PMU_CTL_HDEN;
    //等待PMU_CS寄存器的HDRF被置位
    while(0U == (PMU_CS & PMU_CS_HDRF)){ 
        
    }
    
    /* select the high-drive mode */
    //将LDO切换到高驱动模式
    PMU_CTL |= PMU_CTL_HDS;
    //等待PMU_CS寄存器的HDSRF被置位。进入高驱动模式
    while(0U == (PMU_CS & PMU_CS_HDSRF)){ 
        
    } 
    
    /* select PLL as system clock */
    //设置SCS[1:0],将时钟切换到刚配置好的PLL这条系统时钟线路
    RCU_CFG0 &= ~RCU_CFG0_SCS;
    RCU_CFG0 |= RCU_CKSYSSRC_PLLP;

    /* wait until PLL is selected as system clock */
    //等待PLL这条系统时钟配置能稳定给系统提供时钟
    while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ 
        
    }
   	//到此处,系统完成了从8M到200M的切换
}

3.4 根据程序中的配置,绘制配置后的时钟路线图

最后,我们来绘制一下程序中配置的路径,其中绿色的是开始配置8M的时钟线路,红色的是配置200M的时钟线路,如下图:

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章