跳转至

时钟配置


1、简介

本文围绕芯片的主频配置、内部晶振和外部晶振的选择,每个外围设备接口的分频如何修改,IIS时钟配置展开说明。

CI14LP系列芯片的时钟管理由SCU(System Control Unit)模块负责,相关接口位于 driver\ci14lp_chip_driver\inc\ci14lp_scu.h,系统时钟全局变量接口位于 system\ci_system.h。


2、主频配置

  • CI14LP系列芯片的主频通过PLL配置,正常模式(全速)主频为73.728M,降频模式主频为12.288M,低功耗模式主频为12.288M,相关宏定义位于 driver\ci14lp_chip_driver\inc\ci14lp_scu.h:
#define NORMAL_MAIN_FREQUENCY       (PLL_73728000)   //(不可更改)正常模式(全速)的主频
#define NORMAL_MAIN_FREQUENCY_DOWN  (PLL_12288000)   //(不可更改)正常模式(降频)的主频
#define LOWPOWER_MAIN_FREQUENCY     (PLL_12288000)   //(不可更改)低功耗模式的主频
  • 或者直接调用接口配置主频
#include "ci_scu.h"
#include "ci_system.h"

/* 设置PLL0频率为73.728M */
scu_pll_set_freq(SCU_PLL_INDEX_PLL0, PLL_73728000);
scu_pll_init(SCU_PLL_INDEX_PLL0, PLL_73728000);

/* 获取PLL频率并更新系统时钟全局变量 */
uint32_t main_freq = scu_get_pll_frequency(SCU_PLL_INDEX_PLL0);
set_ipcore_clk(main_freq);
set_ahb_clk(main_freq);
set_apb_clk(main_freq / 2);

注意

  • PLL频率选择枚举 pll_freq_t 支持 12.288M、24.576M、49.152M、73.728M。
  • 正常模式(全速)主频不可更改,为73.728M。

3、晶振选择

  • 如果模组外挂了晶振,可以配置选择外部晶振,否则选择内部RC,作为系统工作频率时钟源。CI14LP支持内部RC4M、内部RC32K、外部OSC4M/OSC26M、外部OSC32K等时钟源。

  • 通过SCU接口配置SRC时钟源(内部RC或外部OSC):

#include "ci_scu.h"

scu_src_clk_select(SCU_SRC_CLK_OUTSIDE_OSC);   //使用外部OSC作为SRC时钟源
scu_src_clk_select(SCU_SRC_CLK_INNER_RC);      //使用内部RC作为SRC时钟源
scu_src_clk_select(SCU_SRC_CLK_BY_EFUSE);      //系统默认,efuse选择(未烧录efuse选外部osc,烧录了efuse选内部rc)
  • 外部晶振时钟来源选择(OSC4M/OSC26M 或 OSC32K):
scu_ext_osc_clk_select(SCU_EXT_OSC4M_OR_OSC26M);  //系统外部晶振来源于OSC4M或OSC26M
scu_ext_osc_clk_select(SCU_EXT_OSC32K);           //系统外部晶振来源于OSC32K
  • 系统工作时钟选择(SRC或PLL):
scu_sys_clk_select(SCU_SYS_CLK_SRC);   //系统的工作时钟为SRC频率
scu_sys_clk_select(SCU_SYS_CLK_PLL);   //系统的工作时钟为PLL频率

4、外设系统时钟频率配置

  • 先明确几个概念:
  • AHB:Advanced High performance Bus,高级高性能总线,这是一种系统总线。主要用于高性能模块如CPU、DMA、UART等之间的连接
  • APB:是Advanced Peripheral Bus的缩写,这是一种外围总线。主要用于低频率的周围外设之间的连接,例如IIC、GPIO、PWM等
  • IPCORE_CLK:系统主频

  • 时钟分频关系说明:

  • 晶振时钟通常为4.096MHz(PLL_SRC_CLK)
  • 晶振时钟经过倍频后得到PLL时钟
  • PLL时钟经过一级分频可得到IPCORE_CLK主频
  • PLL时钟经过两级分频可得到PCLK

  • 可调用接口得到IPCORE_CLK等时钟的值,再根据分频值去推算每个外围设备接口的默认时钟

#include "ci_system.h"

void device_clk_test()
{
    //获取IPCORE_CLK主频
    uint32_t ipcore_clk = get_ipcore_clk();                  //从接口读取IPCORE_CLK主频

    //获取PCLK时钟
    uint32_t pclk = get_apb_clk();                           //从接口读取PCLK时钟

    //获取UART时钟
    uint32_t uart_clk = get_ahb_clk() / 2;                   //AHB时钟和IPCORE_CLK时钟相同

    //获取PWM或TIMER时钟
    uint32_t pwm_timer_clk = get_src_clk() / 16;             //选择时钟源为晶振时,默认分频为16

    //获取IWDG的时钟
    uint32_t iwdg_clk = get_src_clk() / 16;                  //默认分频为16,计算得到IWDG的系统时钟

    //获取iic、gpio的时钟
    uint32_t iic_clk = pclk;
    uint32_t gpio_clk = pclk;
}
  • 如需修改各外设的分频值,可参考下列方式调用接口(注意:更改分频系数时需按顺序操作):
#include "ci_scu.h"
#include "ci_system.h"

void device_div_test()
{
    /* 更改分频系数的详细步骤:
     * (1)、关闭外设时钟:scu_set_device_clock_en
     * (2)、复位外设Reset:scu_set_device_reset
     * (3)、设置外设时钟分频参数div:scu_set_div_parameter
     * (4)、复位释放外设ResetRelease:scu_set_device_reset_release
     * (5)、打开外设时钟:scu_set_device_clock_en
     */
    scu_set_device_clock_en(HAL_UART0_BASE, DISABLE);   //关闭UART0时钟
    scu_set_device_reset(HAL_UART0_BASE);               //复位UART0
    scu_set_div_parameter(HAL_UART0_BASE, 2);           //设置UART0为2分频
    scu_set_device_reset_release(HAL_UART0_BASE);       //复位释放UART0
    scu_set_device_clock_en(HAL_UART0_BASE, ENABLE);    //打开UART0时钟
}

5、IIS时钟配置

5.1、IIS时钟分频关系介绍

  • 先了解几个IIS的专有名词,以下会用此类名词来说明IIS时钟配置。
  • IIS具有独立的时钟和数据信号,IIS接口由MCLK、SCK、LRCK、SDI、SDO这些信号线组成。
  • MCLK:主时钟,通常为音频采样率(LRCK的频率)的64/128/256/384/768倍。
  • SCK:位时钟,一个时钟周期传输一个bit数据,通常为音频采样率(LRCK时钟)的32、64倍。
  • LRCK:帧时钟,用于切换左右声道的数据,IIS格式下LRCK为0表示当前数据帧是左声道数据,为1表示当前数据帧是右声道数据。

  • IIS的时钟分频配置,有单独的一套配置接口,支持多组IIS使用独立的时钟通路。

  • 第1级时钟来源选择有4个(iis_clock_source_t):PLL0、PAD B组MCLK输入、PLL1、PAD A组MCLK输入。

  • 第2级IIS时钟分频器选择有3个(iis_divder_t):SRC0、SRC1、SRC2,3个独立的分频器,可分出不一样的MCLK时钟。

  • 第3级MCLK配置器选择有4个(iis_mclk_t):MCLK0~MCLK3,可独立配置不同的过采样率(iis_mclk_over_sample_t:64/128/256/384/768)和SCK/LRCK比值(iis_sck_lrck_wid_t:32/64)。

  • 第4级每个IIS的SCK和LRCK来源选择(iis0_scklrck_src_t、iis1tx_scklrck_src_t、iis1rx_scklrck_src_t),也能作为PAD输出SCK和LRCK的来源(iis_pad_scklrck_src_t)。

5.2、IIS时钟示例代码

  • 一步配置接口定义:
//位于#include "ci_scu.h"中

void iis_clk_config(iis_clk_config_t* config);
  • 调用一步配置接口,配置IIS0为master模式的时钟通路示例:
#include "ci_scu.h"
#include "ci_system.h"

void init_iis_clk_sample()
{
    uint32_t sample_rate = 16000;                       //音频采样率
    uint32_t ipcore_clk = get_ipcore_clk();             //时钟源频率
    uint32_t fs = 256;

    float div = ((float)ipcore_clk / (float)sample_rate / (float)fs);  //根据时钟源频率、音频采样率和过采样率,计算分频值

    iis_clk_config_t config = {0};
    config.device_select = IISNum0_TX;                  //配置IIS0的时钟通路
    config.model_sel = IIS_MASTER;                      //配置为master模式
    config.div_config.source = IIS_CLOCK_SOURCE_PLL0;   //选择时钟源为PLL0
    config.div_config.divder = IIS_DIV_REGISTER_SRC0;   //选择SRC0分频器
    config.div_config.div = (uint16_t)div;              //配置分频参数
    config.mclk_config.mclk = IIS_MCLK_MCLK0;           //选择MCLK0配置器
    config.mclk_config.src = IIS_DIV_REGISTER_SRC0;     //MCLK0来源于SRC0分频器
    config.mclk_config.over_sample.mclk0_oversample = IIS_MCLK_OVER_SAMPLE_256;  //配置过采样率为256
    config.mclk_config.sck_lrck_ratio = IIS_SCK_LRCK_WID_64;  //配置SCK/LRCK比值为64
    config.iis_scklrck_src.iis0tx_scklrck_src = IIS0_SCKLRCK_FROM_MCLK0;  //选择MCLK0产生的SCK和LRCK
    iis_clk_config(&config);

    uint32_t lrck = sample_rate;                        //LRCK的频率
    uint32_t sck = sample_rate * 64;                    //计算得到SCK的频率
    uint32_t mclk = sample_rate * fs;                   //计算得到MCLK的频率
}
  • 分多步配置的接口定义:
//位于#include "ci_scu.h"中

void scu_iis_src_config(iis_clock_div_config_t *config);                          //设置IIS时钟源和分频值
void scu_iis_mclk_config(iis_mclk_config_t *config);                              //设置IIS MCLK(0、1、2、3)时钟参数
void scu_iis_clk_config(iisnumx_t device, uint8_t clk_source);                    //设置IIS(0、1)时钟参数
void scu_iis_pad_mclk_output(iis_pad_group_t type, iis_divder_t src);             //设置IIS PAD输出MCLK
void scu_iis_pad_mclk_input(iis_pad_group_t type);                                //设置IIS PAD输入MCLK
void scu_iis_pad_clk_output(iis_pad_group_t type, iis_pad_scklrck_src_t src);     //设置IIS PAD输出SCK、LRCK
void scu_iis_pad_clk_input(iis_pad_group_t type);                                 //设置IIS PAD输入SCK、LRCK
  • 其实一步配置接口内,也是调用的分步接口。

6、注意事项

  • 通常配置晶振选项是在配置PLL时钟之前

  • 修改外设分频时,需关闭外设时钟,再修改分频值,再打开时钟。

  • 修改SCU配置寄存器前,需先调用 scu_unlock_topcrg_cfg() / scu_unlock_subcrg_cfg() 解锁,配置完成后调用 scu_lock_topcrg_cfg() / scu_lock_subcrg_cfg() 锁定。