打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

LiSun

打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

系统时钟

时钟控制模块主要控制系统时钟以及外设时钟, 可以配置不同的时钟源作为系统时钟, 可以配置不同的系统时钟分频,可以启动或禁用外设时钟。另外为了确保高精度,内部时钟都具有校准功能。
本产品支持以下四个不同的时钟源作为系统时钟:
⚫ 内部高速 RC 时钟 HIRC(4MHz)(默认主频)
⚫ 外部低速晶振时钟 LXT(32.768KHz)
⚫ 内部低速 RC 时钟 LIRC(38.4KHz 与 32.768KHz 可配置)
⚫ 外部高速晶振时钟 HXT(4MHz~24MHz)

注:LXT、HXT 可以通过端子 PB5、PA1 从外部输入。使用外部振荡输入时,需要使能相应的振荡。选择外部振荡控制选择在 RCC_SYSCLKCR、RCC_LXTCR 寄存器中。
每种时钟源都可以单独的打开或关断,当它们不用时,可以关断它们来降低功耗。
有多个分频器可用于配置 AHB 和 APB 时钟域,AHB 和 APB 域的最大时钟频率为 24MHz。
Cortex M0+ SysTick 定时器由 AHB 时钟驱动,其可由 AHB/4 或 AHB 时钟频率直接驱动(通过SYST_CSR.CLKSOURCE 来配置)。RCC 可以使用 AHB 时钟(HCLK)的 4 分频作为 SysTick 定时器的外部时钟,通过对 SysTick 控制与状态寄存(SYST_CSR.CLKSOURCE)的设置,可选择上述时钟或 Cortex 时钟(HCLK)作为 SysTick 时钟。
需要特别注意的是:在切换系统时钟源的过程中需要按照正确的流程,具体流程参见“系统时钟切换”章节。

内部高速 RC 时钟 HIRC
默认的系统时钟是内部高速 RC 时钟,在芯片上电或复位后即开始工作,通过寄存器
RCC_HIRCCR[11:0]来配置内部高速时钟的频率,给出精确 4MHz、8MHz、16MHz、22.12MHz、24MHz 的频率值。因为内部高速时钟启动快,约 3us,为了让系统更为快速的响应外部中断,系统在从深度休眠模式被唤醒时,可以选择使用该时钟源作为系统时钟。

内部低速 RC 时钟 LIRC
内部低速 RC 时钟频率可配置成 38.4KHz、32.768KHz,在低速及对精度要求不高的应用场景下,可选择该时钟源作为系统时钟。

外部高速晶振时钟 HXT
外部高速晶振时钟需根据用户系统需求外接一个 4MHz~24MHz 的高速晶振。
外部晶振时钟可以选择两种输入方式:
⚫ HXT 外部晶体/陶瓷谐振器
⚫ HXT 用户外部时钟
为了减少时钟输出的失真和缩短启动稳定时间,晶体/陶瓷谐振器和负载电容器必须尽可能地靠近振荡器引脚。负载电容值必须根据所选择的振荡器来调整。

外部低速晶振时钟 LXT
外部低速晶振时钟需外接一个 32.768KHz 的低功耗晶振,具有超高精度以及低功耗。超低功耗模式下工作的模块都可以选择此时钟源作为时钟信号。
外部时钟源旁路请参考图 6-3 HXT/LXT 时钟源
在这里插入图片描述
系统时钟启动过程
上述四种时钟源都有一个启动稳定的时间, 时钟源使能后都会等待一段稳定时间后, 再把时钟输给系统使用, 图 6-4 内部高速时钟启动示意图以内部高速 RC 时钟 HIRC 为例说明时钟的启动稳定过程.
在这里插入图片描述
芯片上电后,系统使用 4MHz 的内部高速时钟作为启动时钟,启动完成后用户可以根据自己的需要来修改高速时钟的频率以及切换时钟源。

系统时钟切换

时钟源的切换是由寄存器RCC_SYSCLKSEL[3:0]来控制。在双时钟模式下,当系统时钟从当前时钟切换到目标时钟时,必须按照一定的流程来实现,否则就会出现异常。

内部高速切换到外部低速
以从 HIRC(内部高速 RC 时钟)切换到 LXT(外部低速晶振时钟)为例,具体流程如下:

  1. 通过 RCC_LXTCR.LXTPORT 位来配置要切换的时钟 LXT 使用的引脚为模拟引脚,或者通过对于引脚的 GPIOx_AFR=0x0F 来配置为模拟功能.
  2. 写 RCC_LXTCR.LXTEN 使能 LXT 时钟,
  3. 等待寄存器 RCC_LXTCR.LXTRDY 位被硬件置”1”,
  4. 写寄存器RCC_SYSCLKSEL.CLKSW[3:0]来切换时钟
  5. 根据需要关闭 HIRC 时钟.

内部高速切换到外部高速
从 HIRC(内部高速 RC 时钟)切换到 HXT(外部高速晶振时钟)为例,具体流程如下:

  1. 通过 RCC_SYSCLKCR.HXTPORT 位来配置要切换的时钟 HXT 使用的引脚为模拟引脚,或者通过对于引脚的 GPIOx_AFR=0x0F 来配置为模拟功能

  2. 写寄存器 RCC_SYSCLKCR.HXTEN 位使能 HXT 时钟,

  3. 等待寄存器 RCC_HXTCR.HXTRDY 位被硬件置”1”,

  4. 写寄存器 RCC_SYSCLKSEL.CLKSW[3:0]来切换时钟,

  5. 根据需要关闭 HIRC 时钟

内部低速切换到外部高速
从 LIRC(内部低速 RC 时钟)切换到 HXT(外部高速晶振时钟)为例,具体流程如下:

  1. 通过 RCC_SYSCLKCR.HXTPORT 位来配置要切换的时钟 HXT 使用的引脚为模拟引脚,
    或者通过对于引脚的 GPIOx_AFR=0x0F 来配置为模拟功能

  2. 写寄存器 RCC_SYSCLKCR.HXTEN 位使能 HXT 时钟

  3. 等待寄存器 RCC_HXTCR.HXTRDY 位被硬件置”1”

  4. 写寄存器 RCC_SYSCLKSEL.CLKSW[3:0]来切换时钟

  5. 根据需要关闭 LIRC 时钟

/********************************************************************************
* @file    bsp_system_clock.h
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-04-03
* @brief   NULL
********************************************************************************/

#ifndef __BSP_SYSTEM_CLOCK_H
#define __BSP_SYSTEM_CLOCK_H

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>

/* Public Function Prototypes ------------------------------------------------*/

void bsp_system_clock_config(void);

#endif

/********************************************************************************
* @file    bsp_system_clock.h
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-04-03
* @brief   NULL
********************************************************************************/

#include "cx32l003_hal.h"

/**
 * @brief  Configure the system clock to HIRC 24MH
 * @note   NULL
 * @retval None
 */
void bsp_system_clock_config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HIRC;
    RCC_OscInitStruct.HIRCState = RCC_HIRC_ON;
    RCC_OscInitStruct.HIRCCalibrationValue = RCC_HIRCCALIBRATION_24M;

    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
    }

    /** Initializes the CPU, AHB and APB busses clocks **/
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HIRC;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APBCLKDivider = RCC_PCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct) != HAL_OK)
    {
    }
}

posted on 2022-08-13 11:00  xuejianqiang  阅读(83)  评论(0编辑  收藏  举报
打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033