Cortex-M3 入门指南(三):时钟总线与复位时钟控制器
【reset clock control 复位和时钟控制器】
时钟信号对于处理器非常重要,比如我们熟悉的 CPU 就是由时钟信号驱动的,而主频就是内核的的时钟信号频率。Cortex-M3 有着复杂的时钟树架构,而且我们需要在初始化阶段配置好时钟参数。
本文将会先介绍时钟相关的概念,然后介绍使用库函数便捷设置时钟总线的方法,在文章最后再深入学习库函数背后等效的时钟寄存器原理。
时钟源
STM32F103
中有 4 种可选时钟源:
高速外部时钟
(HSE): 以外部晶振作时钟源,晶振频率可取范围为 4~16 MHz,常用 8MHz 晶振,开发板上的 8MHz 时钟就是指的这个。高速内部时钟
(HSI): 由内部 RC 振荡器产生,频率为8MHz, 无须外接晶振,但精确性比外部时钟差。低速外部时钟
(LSE): 以外部晶振作时钟源,可以提供时钟信号给实时时钟模块,一般采用 32.768KHz 晶振,较为少用。低速内部时钟
(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总线上的外设,如
GPIO
,USART1
。 - 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 时钟设置一般分为以下几个步骤:
- 启用外部晶振 (可选)
- 等待外部晶振稳定
- 设置各总线分频系数
- 设置 FLASH 等待系数与预读取
- 启动锁相环
- 等待锁相环锁定
- 将 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_CR
,RCC_CFGR
,FLASH_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().is_pll() {}
}
RCC 寄存器手册 (P85)
Reference
STM32中的几个时钟SysTick、FCLK、SYSCLK、HCLK
原文链接:Cortex-M3 入门指南(三):时钟总线与复位时钟控制器 - 知乎 https://zhuanlan.zhihu.com/p/57918979
Cortex-M3 入门指南(三):时钟总线与复位时钟控制器的更多相关文章
- 【翻译转载】【官方教程】Asp.Net MVC4入门指南(2):添加一个控制器
2. 添加一个控制器 · 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-c ...
- 数迹学——Asp.Net MVC4入门指南(2):添加一个控制器
自嘲一下......万事还是得从官方的入门开始 由于找不到适合新新手的MVC入门实例所以回过头来做一下微软的 <Asp.Net MVC4入门指南>. 只有把自己放在太阳下暴晒,才知道自己有 ...
- Drools规则引擎入门指南(三)——使用Docker部署Workbench
其实本来我也是打算使用Tomcat来部署Workbench的,但是在网上看了几篇文章,超级繁琐的配置.各种版本.实在看不下去了索性就直接使用Docker来部署了.本次部署的版本是最新稳定版,对应dro ...
- require.js入门指南(三)
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- kotlin 语言入门指南(三)--编码习惯
这章主要讲当前 kotlin 的一些编码习惯. 命名 如无疑问,kotlin 的命名风格与以下的java风格一样: --驼峰命名法(不要使用下划线) --类名首字母大写 --方法和属性名首字母小写 - ...
- Asp.Net MVC4入门指南(2):添加一个控制器
MVC代表: 模型-视图-控制器 .MVC是一个架构良好并且易于测试和易于维护的开发模式.基于MVC模式的应用程序包含: · Models: 表示该应用程序的数据并使用验证逻辑来强制实施业务规则的数据 ...
- STM32学习之路入门篇之指令集及cortex——m3的存储系统
STM32学习之路入门篇之指令集及cortex——m3的存储系统 一.汇编语言基础 一).汇编语言:基本语法 1.汇编指令最典型的书写模式: 标号 操作码 操作数1, 操作数2,... ...
- redis入门指南(三)—— 事务、过期时间、SORT命令、消息通知与管道
写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 事务 1.redis中的事务由一组命令的集合组成,要么都执行,要么都不执行,同时redis的事务 ...
- 分布式服务框架 Zookeeper(三)官方入门指南
入门指南:使用ZooKeeper来协调分布式应用 这篇文档包含了让你快速上手ZooKeeper的信息.主要是针对那些想要试一把ZooKeeper的开发人员,包含了安装一个单一ZooKeeper服务器的 ...
随机推荐
- 牛客 109 C 操作数 (组合数学)
给定长度为n的数组a,定义一次操作为:1. 算出长度为n的数组s,使得si= (a[1] + a[2] + ... + a[i]) mod 1,000,000,007:2. 执行a = s:现在问k次 ...
- weblogic连接池
1.在 使用JDBC连接池的过程中,最常见的一个问题就是连接池泄漏问题.一个池里面的资源是有限的,应用用完之后应该还回到池中,否则池中的资源会被耗尽. WebLogic Server提供了一个Inac ...
- 版本控制工具SVN学习
教学视频链接:https://edu.aliyun.com/course/83?spm=5176.10731334.0.0.778e6580zC0Ri0 版本控制工具SVN学习 1,SVN的简介 在实 ...
- sql lesson21homework
2017-08-15 18:03:17 mysql> show databases;+--------------------+| Database |+---------- ...
- (一)初识JavaFX
JavaFX是一个强大的图形和多媒体处理工具包集合,它允许开发者来设计.创建.测试.调试和部署富客户端程序,并且和Java一样跨平台. JavaFX应用程序 由于JavaFX库被写成了Java API ...
- 409 Conflict - PUT https://registry.npm.taobao.org/-/user/org.couchdb.user:zphtown - [conflict] User xxx already exists
解决方法cmd执行 npm config set registry https://registry.npmjs.org/ 为什么,参考此文档:https://blog.csdn.net/adc_go ...
- linux 命令技巧(转)--history
本文介绍一些关于bash的能够提高效率的技巧,主要是关于历史命令操作和一些快捷键,让你在命令行下工作效率翻倍. 1.history-----最基本的查看历史命令 2.!n-----编号为n的历史命令 ...
- 牛客小白月赛12 C 华华给月月出题 (积性函数,线性筛)
链接:https://ac.nowcoder.com/acm/contest/392/C 来源:牛客网 华华给月月出题 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K, ...
- Android异常与性能优化相关面试问题-其他优化面试问题详解
Android不用静态变量存储数据: 静态变量等数据由于进程已经被杀死而被初始化.在Android中应用进程不是安全的,因为它会有系统给kill掉,但是在实际中可能会有这样的一个假象:当app被杀掉之 ...
- CSS基础学习-15.CSS3 动画效果