Cortex-M3 入门指南(三):时钟总线与复位时钟控制器

 

【reset clock control  复位和时钟控制器】

时钟信号对于处理器非常重要,比如我们熟悉的 CPU 就是由时钟信号驱动的,而主频就是内核的的时钟信号频率。Cortex-M3 有着复杂的时钟树架构,而且我们需要在初始化阶段配置好时钟参数。

本文将会先介绍时钟相关的概念,然后介绍使用库函数便捷设置时钟总线的方法,在文章最后再深入学习库函数背后等效的时钟寄存器原理。

 

时钟源

STM32F103 中有 4 种可选时钟源:

  1. 高速外部时钟 (HSE): 以外部晶振作时钟源,晶振频率可取范围为 4~16 MHz,常用 8MHz 晶振,开发板上的 8MHz 时钟就是指的这个。
  2. 高速内部时钟 (HSI): 由内部 RC 振荡器产生,频率为8MHz, 无须外接晶振,但精确性比外部时钟差。
  3. 低速外部时钟 (LSE): 以外部晶振作时钟源,可以提供时钟信号给实时时钟模块,一般采用 32.768KHz 晶振,较为少用。
  4. 低速内部时钟 (LSI): 由内部 RC 振荡器产生,也主要提供信号给实时时钟模块,频率在 30-60KHz 间浮动,较为少用。

单片机启动时默认使用高速内部时钟 (HSI),启动之后可以通过 RCC 时钟控制寄存器器改用其他时钟源。

 

系统时钟 (SYSCLK)

系统时钟 SYSCLK 最大频率为 72MHz,它是供 STM32 中绝大部分部件工作的时钟源。系统时钟可由 PLL(锁相环)、HSI 或者 HSE 提供输入,并且通过 AHB(高速总线) 分频器分频后输出送给各模块使用。

 

锁相环 (PLL)

如果打算使单片机运行在最高频率 (72 MHz),我们还需要倍频高速时钟源的时钟信号。锁相环能够将输出频率锁定在输入频率的正整数倍。STM32F103 的锁相环提供了 2 到 16 倍的倍频系数。假设我们使用高速内部时钟源 (8 MHz) ,想要使 STM32F103 达到最高主频 (72 MHz),那么我们就要要启用锁相环,设置为 9 倍倍频,并将 SYSCLK 时钟源设置为 PLL。

 

时钟总线

STM32F103 中有 4 条时钟总线:

  • AHB 高速总线,时钟为 HCLK,最大频率为 72 MHz,时钟信号提供给存储器,DMA 及 Cortex 内核,是内核运行的时钟,也就是主频,它的大小与 STM32 运算速度,数据存取速度密切相关。
  • APB1 低速外设总线,时钟为 PCLK1,最大频率为 36 MHz,提供给挂载在APB1总线上的外设, 如 USART2
  • APB2 高速外设总线,时钟为 PCLK2,最大频率为 72 MHz,提供给挂载在APB2总线上的外设,如 GPIOUSART1
  • FCLK 自由运行时钟,独立于内核运行,一般设置为与 HCLK 同频率,常用于采样中断和调试模块供时。

 

使用库函数设置 复位时钟控制器 (RCC)

复位时钟控制器是 STM32F103 提供的一组寄存器,负责控制和设置上面提到的时钟源,锁相环倍频,各总线分频系数以及开关总线上的各类外设。

stm32f1xx_hal 提供了简洁的接口帮我们设置 RCC 寄存器,足够满足日常工作需要。工程上也推荐使用这种方式进行时钟树初始化。

下面例子中单片机使用外部 8MHz 晶振,并将所有总线设置为最高频率:

#![no_main]
#![no_std]  extern crate cortex_m; extern crate cortex_m_rt as rt; extern crate panic_halt; extern crate stm32f103xx_hal as hal;  use hal::prelude::*; use hal::stm32f103xx; use rt::entry;  #[entry] fn main() -> ! {  let dp = stm32f103xx::Peripherals::take().unwrap();   let mut flash = dp.FLASH.constrain();  let mut rcc = dp.RCC.constrain();   let clocks = rcc  .cfgr  .use_hse(8.mhz()) // 高速外部时钟源  .sysclk(72.mhz()) // 系统时钟  .hclk(72.mhz()) // AHB 高速总线  .pclk1(36.mhz()) // APB1 低速外设总线  .pclk2(72.mhz()) // APB2 高速外设总线  .freeze(&mut flash.acr); // 应用时钟配置   loop {} }

 

深入了解 RCC 寄存器

RCC 寄存器的设置比其他一般外设寄存器要更为复杂,因此一般不会手动设置。但是我们可以通过学习它来掌握的库函数背后的原理。

 

RCC 时钟设置一般分为以下几个步骤:

  1. 启用外部晶振 (可选)
  2. 等待外部晶振稳定
  3. 设置各总线分频系数
  4. 设置 FLASH 等待系数与预读取
  5. 启动锁相环
  6. 等待锁相环锁定
  7. 将 SYSCLK 切换到锁相环信号输入

 

PS: 这里提到的 FLASH 等待系数和预读取都与 Cortex-M 架构设计有关。Cortex-M 核心采用了三级管道技术,简单来说就是当一个指令正在处理时,下一个指令已经被解码的同时第三个指令已经被预读取进缓存区了,这钟处理方式能够大幅提高处理器的运行效率。另外,FLASH 由于原理限制,很难达到与核心相同的高频率,因此在核心读取指令的速度超过 FLASH 发送指令速度的时候,核心需要暂时停下来等待。根据手册,STM32F103 的 FLASH 等待系数应根据核心频率 (HCLK) 设置:

HCLK        | FLASH WAIT STATE
-------------------------------
0 - 24 MHz  | 0 wait state
24 - 48 MHz | 1 wait state
48 - 72 MHz | 2 wait state

 

分频

事实上,AHB,APB1,APB2 等各总线的频率都严格成正整数倍关系,因为它们的时钟信号并不是单独产生的,而是根据特定结构分频出来的。分频就是按照预分频系数降低输入频率,预分频系数都为正整数。STM32F103 中的时钟树简化之后是这样的:

Example

我们这里用寄存器代替库函数初始化时钟树,代码与上节的库函数完全等效。下面用到的寄存器有 RCC_CRRCC_CFGRFLASH_ACR,由于篇幅较长,手册截图将放在后面以供参考。

use stm32f103xx;  pub fn rcc_clock_init(rcc: &mut stm32f103xx::RCC, flash: &mut stm32f103xx::FLASH) {  // 启动外部高速时钟 (HSE)  rcc.cr.write(|w| w.hseon().enabled());   // 等待外部高速时钟稳定  while !rcc.cr.read().hserdy().is_ready() {}   // 设置分频 AHB(HCLK) = SYSCLK, APB1(PCLK1) = SYSCLK / 2, APB2(PCK2) = SYSCLK  rcc.cfgr  .write(|w| w.hpre().no_div().ppre1().div2().ppre2().no_div());   // 设置锁相环为 9 x HSE  rcc.cfgr  .write(|w| w.pllsrc().external().pllxtpre().no_div().pllmul().mul9());   // 设置 flash : two wait states, 启用预读取  flash.acr.write(|w| w.latency().two().prftbe().enabled());   // 启动锁相环  rcc.cr.write(|w| w.pllon().enabled());   // 等待锁相环锁定  while !rcc.cr.read().pllrdy().is_locked() {}   // 使用锁相环输出作为 SYSCLK  rcc.cfgr.write(|w| w.sw().pll());   // 等待 SYSCLK 切换为锁相环  while !rcc.cfgr.read().sws().

转载于:https://www.cnblogs.com/tongongV/p/10833865.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103ZET6是一款基于ARM Cortex-M3内核的STM32系列单片机,它具有丰富的外设和强大的性能。关于时钟模块,STM32F103ZET6集成了多个时钟源和时钟模块,用于驱动和控制系统的运行。 该芯片的主要时钟源包括: 1. HSI(High-Speed Internal)内部高速时钟源:为8MHz的内部振荡器,用于提供系统的基本时钟,可以通过软件配置频率分频。 2. HSE(High-Speed External)外部高速时钟源:可以连接外部晶体振荡器或者外部时钟源,频率范围为4MHz至16MHz。 3. PLL(Phase-Locked Loop)锁相环:利用HSI或HSE作为输入时钟源,通过倍频、分频等操作产生高频稳定的时钟信号。PLL可以提供系统时钟(SYSCLK)、外设时钟(PCLK1和PCLK2)以及USB OTG FS时钟时钟模块包括以下几个部分: 1. RCC(Reset and Clock Control)复位时钟控制模块:用于配置和控制系统时钟源和时钟分频。可以设置主时钟源、系统时钟倍频、AHB、APB1和APB2总线的分频等。 2. 外设时钟使能:通过RCC模块可以使能和禁用各个外设的时钟,以控制外设的工作和功耗。 3. 系统定时器:STM32F103ZET6内部具有一个基本定时器(TIM6)和一个高级控制定时器(TIM1),用于提供精确定时和定时功能。 需要注意的是,具体的时钟配置和使用方法需要根据具体的应用和需求进行设置和调整。在使用STM32F103ZET6时钟模块时,建议参考官方文档和开发板的用户手册,以了解详细的使用方法和注意事项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值