ET6001 CRG模块使用指南

简介

CRG全称为时钟复位模块(Clock and Reset Generator),该模块主要为芯片提供时钟及复位管理功能。 时钟模块包含外部时钟源,内部时钟源,PLL, 分频器,时钟门控,时钟丢失检测,时钟频偏检测等。

ET6001 时钟源包含:

  • 外部高速时钟源 HSXO 25MHz

  • 内部高速时钟源 HSOSC 25MHz

  • 外部低速时钟源 LSXO 32.768KHz

  • 内部低速时钟源 LSOSC 256KHz

复位包含外部管脚复位,POR复位,WDG复位,全局软复位和CPU全局复位,外部复位支持滤毛刺功能。ET6001 大部分模块支持单独模块复位。

功能概述

  • 支持外部时钟源HSXO和HSOSC选择

  • 支持PLL的倍频和分频设置

  • 支持各模块时钟门控和复位控制

  • 支持时钟丢失检测

  • 支持时钟频偏检测

  • 支持芯片复位设置

  • 支持各总线时钟频率获取

  • 支持各总线分频系数配置

系统时钟软件配置流程

  1. 确定PLL时钟源 - 选择外部时钟源HSXO或内部时钟源HSOSC 枚举类型:

    • CRG_PLLREFSEL_HSXO :外部时钟源HSXO

    • CRG_PLLREFSEL_HSOSC :内部时钟源HSOSC

  2. 确定PLL倍频和分频系数

    PLL输出FOUT时钟频率为:

    \[FOUTPOSTDIV = F_{in}* / REF_{DIV} * FB_{DIV} / POST1_{DIV} / POST2_{DIV}\]

    使能PLLBYPASS后, PLL输出FOUT时钟频率为:

    \[FOUTPOSTDIV = F_{in}\]
  3. 选择PLL0输出的时钟来源:
    • CRG_PLL0SOURCE_OSC256K : osc256k

    • CRG_PLL0SOURCE_OSC25M : osc25m

    • CRG_PLL0SOURCE_PLL0_FOUT : 选择PLL0的FOUT输出

    • CRG_PLL0SOURCE_PLL1_FOUT : 选择PLL1的FOUT输出

  4. 选择PLL1输出的时钟来源:

    • CRG_PLL1SOURCE_PLL0CLK : 选择PLL0的输出

    • CRG_PLL1SOURCE_PLL1_FOUT : 选择PLL1的FOUT输出

  5. 设置各总线时钟频率

    总线时钟分频由结构体 CRG_ClkInitTypeDef 进行配置, 除EFCCLK,QSPI, CAN外, 其他时钟分频只支持 偶数 分频。

    • CPUCLKDivider : CPUCLK分频系数

    • BUSCLKDivider : BUSCLK分频系数

    • AHBCLKDivider : AHBCLK分频系数

    • APB3CLKDivider :APB3CLK分频系数

    • EFCCLKDivider : EFCCLK分频系数

    • CANCLKDivider : CANCLK分频系数

    • ADDACLKDivider :ADCCLK分频系数

    • QSPICLKDivider : QSPICLK分频系数

    • SMCCLKDivider : SMCCLK分频系数

    然后通过调用函数 CRG_ClockDivConfig() 进行配置

6.设置系统时钟源
  • 通过函数 CRG_PLLClockSelConfig() 设置系统时钟配置

时钟配置代码说明

// 1. 定义PLL配置参数  PLLFOUT = 25MHz * 32 / 1 / 2  = 400MHz
static const  CRG_PLLInitTypeDef pll1Init =
{
    CRG_PLL_ON,  //.PLLState
        0x20,  //.PLLFBDiv
        0x00,  //.PLLFrac
        0x02,  //.PLLPostDiv1
        0x01,  //.PLLPostDiv2
        0x01,  //.PLLRefDiv
};
// PLLFOUT = 25MHz * 24 / 1 / 1  = 600MHz
const static CRG_PLLInitTypeDef pll0Init =
{
    CRG_PLL_ON,  //.PLLState
        0x18,  //.PLLFBDiv
        0x00,  //.PLLFrac
        0x01,  //.PLLPostDiv1
        0x01,  //.PLLPostDiv2
        0x01,  //.PLLRefDiv
};

// 2. 定义时钟配置参数, 配置值为 分频值 - 1
const static CRG_ClkInitTypeDef clkInit =
{
    CRG_PLL0SOURCE_PLL0_FOUT,  //.PLL0CLKSource
    CRG_PLL1SOURCE_PLL1_FOUT,  //.PLL1CLKSource
                        0x01,  //.CPUCLKDivider        //300M
                        0x01,  //.BUSCLKDivider        //150M
                        0x01,  //.AHBCLKDivider        //300M
                        0x01,  //.APB13CLKDivider      //75M
                        0x01,  //.EFCCLKDivider        //75M
                        0x01,  //.QSPICLKDivider       //200M
                        0x04,  //.CANCLKDivider        //80M
                        0x0b,  //.ADDACLKDivider       //50M
                        0x00,  //.SMCCLKDivider        //75M
                        0x01,  //.APBBUS2CLKSrcSel
                        0x01,  //.QSPICLKSrcSel
                        0x01,  //.CANCLKSrcSel
};


// 3. 配置时钟
static void SystemClock_Config(void)
{
    /* Select PLL Ref Source */
    if (CRG_PLLRefConfig(pllRef, HSXO_VALUE) != DRV_OK)
    {
        while (1);
    }
    /* Configure CPU, BUS, Peripherals Clock  dividers  */
    if (CRG_ClockDivConfig((const CRG_ClkInitTypeDef *)&clkInit) != DRV_OK)
    {
        while (1);
    }

    /* Configure PLL1 div  400MHz*/
    if (CRG_PLLConfig(CRG_PLL1, (const CRG_PLLInitTypeDef *)&pll1Init) != DRV_OK)
    {
        while (1);
    }

    /* Configure PLL0 div 400MHz */
    if (CRG_PLLConfig(CRG_PLL0, (const CRG_PLLInitTypeDef *)&pll0Init) != DRV_OK)
    {
        while (1);
    }
    /* Select PLL Fout Source */
    if (CRG_PLLClockSelConfig((const CRG_ClkInitTypeDef *)&clkInit) != DRV_OK)
    {
        while (1);
    }
}

复位及门控配置说明

芯片上电后,部分模块并没有处于解复位状态,如果需要使用这些模块,需要先解除复位。SDK启动文件 SystemInit 函数中默认将所有模块复位解除,用户可以根据需要选择性地解除复位。

  • 通过函数 CRG_PeriphReset() 设置模块复位, 输入参数为枚举类型:CRG_PeriphResetTypeDef

  • 通过函数 CRG_PeriphClock_Enable() 设置模块时钟门控关闭

  • 通过函数 CRG_PeriphClock_Disable() 设置模块时钟门控开启

  • 通过函数 CRG_GlobalSoftReset() 设置芯片全局软复位

系统总线及模块时钟频率获取

  • 通过函数 CRG_GetCPUFreq() 获取CPU时钟频率

  • 通过函数 CRG_GetAHBFreq() 获取BUS总线时钟频率

  • 通过函数 CRG_GetAPB2ClkFreq() 获取APB2总线时钟频率

  • 通过函数 CRG_GetAPB13PClkFreq() 获取APB3总线时钟频率

  • 通过函数 CRG_GetCANClkFreq() 获取CAN时钟频率

  • 通过函数 CRG_GetWDGClkFreq() 获取WDG时钟频率

  • 通过函数 CRG_GetSYSCNTClkFreq() 获取系统计数器SYSCNT时钟频率

  • 通过函数 CRG_GetQSPIClkFreq() 获取QSPI时钟频率