打印
[MM32软件]

MM32F0140学习笔记——时钟系统RCC

[复制链接]
908|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
RCC 是 Reset and clock Control 模块的缩写,可用于复位片上外设模块寄存器以及设置时钟树的时钟频率。本篇笔记将探讨 MM32F0140 微控制器上复位寄存器和设置时钟的操作流程,并以 pokt-f0140 开发板作为实际演示平台进行实验,实现 48MHz 开发板系统时钟。
RCC 功能描述

使用特权

评论回复
沙发
laocuo1142|  楼主 | 2022-4-2 10:58 | 只看该作者
软件复位片上外设模块寄存器
通过设置 RCC_AHBRSTR 寄存器、RCC_APB1RSTR 寄存器以及 RCC_APB2RSTR 寄存器中对应外设模块位,可以实现软件复位片上外设模块寄存器。
设置时钟树频率

​                                                                                                       图 1. RCC 时钟树框图


如图 1 所示,RCC 时钟树主要分成以下四部分:
  • 系统时钟
  • MCO时钟输出
  • 总线时钟
  • 外设时钟
下文将探讨 RCC 时钟树上系统时钟的配置流程、系统时钟与总线时钟的关系以及部分外设时钟与总线时钟的关系。



使用特权

评论回复
板凳
laocuo1142|  楼主 | 2022-4-2 10:59 | 只看该作者
配置系统时钟
MM32F0140 支持四个独立时钟源:
  • 高速内部时钟(HSI)
  • 高速外部时钟 (HSE)
  • 锁相环(PLL)
  • 低速内部时钟(LSI)
通过配置 RCC_CFGR[SW] ,可以选择不同的时钟源作为系统时钟源。通过读取RCC_CFGR[SWS] 的值,可以确定系统时钟源选择。值得注意的是,当使能上述四个时钟源后,需要等待 RCC 寄存器中对应的时钟准备就绪标志被拉高,才能确认时钟源被使能完成。( eg. 配置 RCC_CR[HSION] = 1 也即使能高速内部时钟后, 需要等待 RCC_CR[HSIRDY] 被拉高后,才能确认 HSI 准备就绪。)

使用特权

评论回复
地板
laocuo1142|  楼主 | 2022-4-2 11:02 | 只看该作者
在上述四个独立时钟源中,PLL 配置相对复杂。PLL 频率取决于 PLL 输入时钟频率 FREFIN、 PLL 时钟倍频因子N 以及PLL 时钟分频因子M和P。PLL 频率 FCLKO 的计算公式为


FCLKO  = FREFIN N / ( M P )


其中,输入时钟频率 FREFIN, 可以通过配置 RCC_PLLCFGR[PLLXTPRE] 和 RCC_PLLCFGR[PLLSRC] 进行选择 ,可选项有 HSI 输出时钟频率 、HSE 输出时钟频率以及 HSE 输出时钟的 2 分频频率。配置此项前,需要使能对应的时钟输入源。分频因子 M = RCC_PLLCFGR[PLL_DM] + 1, P = RCC_PLLCFGR[PLL_PM] + 1; 倍频因子 N = RCC_PLLCFGR[PLL_DN] + 1。这三个系数可以通过配置 PLLCFGR 寄存器的相应位实现。M 值 和 P 值的区别在于,M 值是 PLL 对于输入时钟频率的分频, P 值是 PLL 作为系统时钟输出时的分频。

使用特权

评论回复
5
laocuo1142|  楼主 | 2022-4-2 11:05 | 只看该作者
系统时钟与总线时钟
片上总线时钟由系统时钟一次或多次分频后得到。通过设置 RCC_CFGR[PPRE2] / RCC_CFGR[PPRE1] / RCC_CFGR[HPRE] 可以分别配置APB2,APB1 和 AHB1 总线时钟分频系数。总线时钟频率最高可达 72 MHz。
总线时钟与外设时钟
通过配置 RCC_AHBENR 寄存器、RCC_APB1ENR 寄存器以及 RCC_APB2ENR 寄存器的特定外设位,使能总线上外设时钟,从而可以允许总线对外设寄存器的读写操作。


对于大部分外设而言,外设时钟频率与外设所在总线频率相同。但有以下几个特例。


对于非 tiM1 的定时器而言,如果所在总线时钟分频系数不为 1,则定时器时钟频率为 2 倍频的总线时钟频率。TIM1 的时钟频率取决于 AHB 总线时钟和 APB2 总线时钟。如果 AHB 总线时钟和 APB2 总线时钟都不分频,则 TIM1 时钟频率和 APB2 时钟频率相同;如果 AHB 总线时钟和 APB2 总线时钟仅有一方分频,则 TIM1 时钟频率为 2 倍频的总线分频时钟频率。如果 AHB 总线时钟和 APB2 总线时钟都分频,则 TIM1 时钟频率为 4 倍频的 APB 总线时钟频率。


CPU 系统定时器频率 SysTick ,为 8 分频的 AHB 总线时钟频率。

使用特权

评论回复
6
laocuo1142|  楼主 | 2022-4-2 11:07 | 只看该作者
样例1 pokt-f0140 开发板初始化 48MHz 系统时钟
在 SDK 中已有支持的 pokt-f0140 开发板上,在任一样例工程中的 clock_init.c 中,通过 CLOCK_BootToHSE48MHz() 实现 48MHz 系统时钟和总线时钟。其中,HSE的输出时钟频率为12MHz。


主要代码如下:
void CLOCK_BootToHSE48MHz(void){    /* enable HSE.使能HSE时钟。 */    RCC->CR |= RCC_CR_HSEON_MASK;    /* check HSE ready mask.时钟准备就绪。 */    while ( RCC_CR_HSERDY_MASK != (RCC->CR & RCC_CR_HSERDY_MASK) )    {    }    /* F_clko = F_refin * N/(M*P), F_refin = 12M. HSE输出频率为12MHz,倍频系数为8,分频系数为 1*2 = 2,PLL时钟频率为 12*8/2 = 48MHz。 */    RCC->PLLCFGR = RCC_PLLCFGR_PLLSRC(1) /* (pllsrc == 1) ? HSE : HSI. */                 | RCC_PLLCFGR_PLLDN(7) /* N = DN+1. */                 | RCC_PLLCFGR_PLLDM(1) /* M = DM+1. */                 | RCC_PLLCFGR_PLLDP(0) /* P = DP+1. */                 | RCC_PLLCFGR_PLLLDS(1)                 | RCC_PLLCFGR_PLLICTRL(3) /* 10uA. */                 ;    /* Enable PLL. 使能PLL时钟并等待时钟准备就绪。*/    RCC->CR |= RCC_CR_PLLON_MASK;    while((RCC->CR & RCC_CR_PLLRDY_MASK) == 0)    {    }    /* Enable the FLASH prefetch. */    RCC->AHB1ENR |= RCC_AHB1ENR_FLITFEN_MASK; /* enable the access to FLASH. */    FLASH->ACR = FLASH_ACR_LATENCY(1u) /* setup divider: 1 for 48Mhz, 2 for 72MHz.. */               | FLASH_ACR_PRFTBE_MASK /* enable flash prefetch. */               ;    /* Setup the dividers for each bus. 为各总线设置分频系数。 */    RCC->CFGR = RCC_CFGR_HPRE(0)   /* div=1 for AHB freq. */              | RCC_CFGR_PPRE1(0x0)  /* div=1 for APB1 freq. */              | RCC_CFGR_PPRE2(0x0)  /* div=1 for APB2 freq. */              | RCC_CFGR_MCO(7)    /* use PLL/2 as output. */              ;    /* Switch the system clock source to PLL. 选择系统时钟源为PLL。*/    RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW_MASK) | RCC_CFGR_SW(2); /* use PLL as SYSCLK */    /* Wait till PLL is used as system clock source.检查SWS标志,确认系统时钟源设置。 */    while ( (RCC->CFGR & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS(2) )    {    }}样例2 pokt-f0140 开发板使能 GPIOA 模块时钟
在 SDK 中已有支持的 pokt-f0140 开发板上,可以通过以下代码使能 GPIOA 模块时钟。
RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOA, true);样例3 pokt-f0140 开发板复位 GPIOA 模块寄存器
在 SDK 中已有支持的 pokt-f0140 开发板上,可以通过以下代码复位 GPIOA 模块寄存器。
RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOA);

使用特权

评论回复
7
tpgf| | 2022-5-1 10:43 | 只看该作者
什么功能用到这个时钟呢

使用特权

评论回复
8
磨砂| | 2022-5-1 10:54 | 只看该作者
非常非常重要的一个时钟

使用特权

评论回复
9
晓伍| | 2022-5-1 11:00 | 只看该作者
它的时钟源都可以是什么啊

使用特权

评论回复
10
八层楼| | 2022-5-1 11:15 | 只看该作者
感觉时钟很是复杂啊

使用特权

评论回复
11
观海| | 2022-5-1 11:23 | 只看该作者
排版有问题 看不好吧

使用特权

评论回复
12
guanjiaer| | 2022-5-1 11:33 | 只看该作者
复制下来自己排版

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1181

主题

5171

帖子

12

粉丝