历史上的今天
返回首页

历史上的今天

今天是:2024年12月30日(星期一)

正在发生

2020年12月30日 | STM32系统时钟配置笔记

2020-12-30 来源:eefocus

前言

由于个人博客被攻击,现逐渐将博客内容搬运至CSDN,本文原写于2020年4月。

时钟笔记

本文为stm32时钟和中断笔记
时钟树
可以通过时钟树来大致了解配置时钟的流程,可以更加清晰了解各个时钟之间的关系
在这里插入图片描述

名词解释

HSE:HSE 高速外部时钟信号。HSE 是高速的外部时钟信号,可以由有源晶振或者无源晶振提供,频率从 4-16MHZ不等。当使用有源晶振时,时钟从 OSC_IN 引脚进入, OSC_OUT 引脚悬空。当选用无源晶振时,时钟从 OSC_IN 和OSC_OUT 进入,并且要配谐振电容。HSE 最常使用的就是 8M 的无源晶振。当确定 PLL 时钟来源的时候, HSE 可以不分频或者 2 分频,这个由时钟配置寄存器 CFGR 的位 17:PLLXTPRE 设置。

PLL 时钟源:PLL 时钟来源可以有两个,一个来自 HSE,另外一个是 HSI/2,具体用哪个由时钟配置寄存器 CFGR 的位 16: PLLSRC 设置。 HSI 是内部高速的时钟信号,频率为 8M,根据温度和环境的情况频率会有漂移,一般不作为 PLL 的时钟来源。

PLL时钟PLLCLK:通过设置 PLL 的倍频因子,可以对 PLL 的时钟来源进行倍频,倍频因子可以是:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],具体设置成多少, 由时钟配置寄存器 CFGR 的位21-18: PLLMUL[3:0]设置。
(注释:72M是st官方推荐稳定运行时钟)

系统时钟SYSCLK:从时钟树上可以看出系统时钟来源可以是: HSI、 PLLCLK、 HSE,具体的时钟配置寄存器 CFGR 的位 1-0:SW[1:0]设置。

AHB 总线时钟 HCLK:系统时钟 SYSCLK 经过 AHB 预分频器分频之后得到时钟叫 APB 总线时钟,即 HCLK,分频因子可以是:[1,2,4,8,16,64,128,256,512],具体的由时钟配置寄存器 CFGR的位 7-4 : HPRE[3:0]设置。片上大部分外设的时钟都是经过 HCLK 分频得到,至于 AHB总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置。

APB2 总线时钟 HCLK2:APB2 总线时钟 PCLK2 由 HCLK 经过高速 APB2 预分频器得到,分频因子可以是:[1,2,4,8,16],具体由时钟配置寄存器 CFGR 的位 13-11: PPRE2[2:0]决定。 HCLK2 属于高速的总线时钟,片上高速的外设就挂载到这条总线上,比如全部的 GPIO、 USART1、SPI1 等。
APB1 总线时钟 HCLK1:APB1 总线时钟 PCLK1 由 HCLK 经过低速 APB 预分频器得到,分频因子可以是:[1,2,4,8,16],具体的由时钟配置寄存器 CFGR 的位 10-8: PRRE1[2:0]决定。HCLK1 属于低速的总线时钟,最高为36M,片上低速的外设就挂载到这条总线上,比如USART2/3/4/5、SPI2/3, I2C1/2 等。

其他时钟先概不论述。

补充知识:

从时钟频率来说,又分为高速时钟和低速时钟,高速时钟是提供给芯片主体的主时钟,而低速时钟只是提供给芯片中的RTC(实时时钟)及独立看门狗使用。

从芯片角度来说,时钟源分为内部时钟与外部时钟源 ,内部时钟是在芯片内部RC振荡器产生的,起振较快,所以时钟在芯片刚上电的时候,默认使用内部高速时钟。而外部时钟信号是由外部的晶振输入的,在精度和稳定性上都有很大优势,所以上电之后我们再通过软件配置,转而采用外部时钟信号。

stm32f103在刚开始都是很默认时钟为72M,在启动文件中startup_stm32f10x_hd.s里,规定了程序在进入到main函数之前,先要执行systeminit函数,该函数是通过操作时钟控制寄存器与时钟配置寄存器来实现初始化。详情看下图翻译说明

systeminit函数


这里只讨论如图路线(常用路线):

常用路线


配置HSE时钟步骤

  1. 使用HSE时,设置系统时钟的步骤:开启HSE ,并等待 HSE 稳定

  2. 设置 AHB、APB2、APB1的预分频因子

  3. 设置PLL的时钟来源,和PLL的倍频因子,设置各种频率主要就是在这里设置

  4. 开启PLL,并等待PLL稳定

  5. 把PLLCK切换为系统时钟SYSCLK

  6. 读取时钟切换状态位,确保PLLCLK被选为系统时钟

(注释:对于 SYSCLK、 HCLK、 PCLK2、 PCLK1 这四个时钟的配置一般是: PCLK2 =HCLK = SYSCLK=PLLCLK = 72M, PCLK1=HCLK/2 = 36M。 这个时钟配置也是库函数的标准配置。)

启用使用HSE时钟

void HSE_SetSysClock(uint32_t pllmul)

{

__IO uint32_t  HSEStartUpStatus = 0;


// 把RCC外设初始化成复位状态,这句是必须的,该命令在固件库rcc.c文件中。

RCC_DeInit();


//使能HSE,开启外部晶振,该开发板用的是8M,命令在固件库rcc.c/277行。

RCC_HSEConfig(RCC_HSE_ON);


// 等待 HSE 启动稳定

HSEStartUpStatus = RCC_WaitForHSEStartUp();//rcc.c/304行,成功后RCC_WaitForHSEStartUp()会传入参数SUCCESS。


// 只有 HSE 稳定之后则继续往下执行

if (HSEStartUpStatus == SUCCESS)

{

//----------------------------------------------------------------------//

// 使能FLASH 预存取缓冲区

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);


FLASH_SetLatency(FLASH_Latency_2);

//----------------------------------------------------------------------//


// AHB预分频因子设置为1分频,HCLK = SYSCLK

RCC_HCLKConfig(RCC_SYSCLK_Div1); //rcc.c /605


// APB2预分频因子设置为1分频,PCLK2 = HCLK

RCC_PCLK2Config(RCC_HCLK_Div1);


// APB1预分频因子设置为1分频,PCLK1 = HCLK/2

RCC_PCLK1Config(RCC_HCLK_Div2);


//-----------------设置各种频率主要就是在这里设置-------------------//

// 设置PLL时钟来源为HSE,设置PLL倍频因子

// PLLCLK = 8MHz * pllmul

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, pllmul);

//------------------------------------------------------------------//


// 开启PLL

RCC_PLLCmd(ENABLE);


// 等待 PLL稳定

while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

{

}


// 当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLK

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);


// 读取时钟切换状态位,确保PLLCLK被选为系统时钟

while (RCC_GetSYSCLKSource() != 0x08)

{

}

}

else

{ // 如果HSE开启失败,那么程序就会来到这里,用户可在这里添加出错的代码处理

// 当HSE开启失败或者故障的时候,单片机会自动把HSI设置为系统时钟,

// HSI是内部的高速时钟,8MHZ

while (1)

{

}

}

}


问题:


为什么使能FLASH 预存取缓冲区?

使能FLASH指令缓冲器,用于当CPU主频提升后缓存多条指令已避免CPU等待FLASH传数据导致的时间浪费


“预取缓冲区(2个64位):在每一次复位以后被自动打开,由于每个缓冲区的大小(64位)与闪存的带宽相同,因此只通过需一次读闪存的操作即可更新整个缓冲区的内容。由于预取缓冲区的存在,CPU可以工作在更高的主频。CPU每次取指最多为32位的字,取一条指令时,下一条指令已经在缓冲区中等待。”具体寄存器配置参见:PM0075:STM32F10xxx Flash memory microcontrollers(Flash编程手册)


形参 pllmul?

pllmul 用来设置 PLL 的倍频因子,在调用的时候形参可以是: RCC_PLLMul_x , x:[2,3,…16],这些宏来源于库函数的定义,宏展开是一些 32 位的十六进制数,具体功能是配置了时钟配置寄存器 CFGR 的位 21-18PLLMUL[3:0],预先定义好倍频因子,方便调用。


配置HSI时钟步骤

使用HSI时,设置系统时钟的步骤:开启HSI ,并等待 HSI 稳定

设置 AHB、APB2、APB1的预分频因子

设置PLL的时钟来源,和PLL的倍频因子,设置各种频率主要就是在这里设置

开启PLL,并等待PLL稳定

把PLLCK切换为系统时钟SYSCLK

读取时钟切换状态位,确保PLLCLK被选为系统时钟

(注释:HSI作为时钟来源,经过PLL倍频作为系统时钟,这是在HSE故障的时候才使用的方法,HSI会因为温度等原因会有漂移,不稳定,一般不会用HSI作为时钟来源,除非是迫不得已的情况。)



"代码"



void HSI_SetSysClock(uint32_t pllmul)

{

__IO uint32_t HSIStartUpStatus = 0;


// 把RCC外设初始化成复位状态,这句是必须的

RCC_DeInit();


//使能HSI

RCC_HSICmd(ENABLE);


// 等待 HSI 就绪

HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY;


// 只有 HSI就绪之后则继续往下执行

if (HSIStartUpStatus == RCC_CR_HSIRDY)

{

//----------------------------------------------------------------------//

// 使能FLASH 预存取缓冲区

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);


// SYSCLK周期与闪存访问时间的比例设置,这里统一设置成2

// 设置成2的时候,SYSCLK低于48M也可以工作,如果设置成0或者1的时候,

// 如果配置的SYSCLK超出了范围的话,则会进入硬件错误,程序就死了

// 0:0 < SYSCLK <= 24M

// 1:24< SYSCLK <= 48M

// 2:48< SYSCLK <= 72M

FLASH_SetLatency(FLASH_Latency_2);

//----------------------------------------------------------------------//


// AHB预分频因子设置为1分频,HCLK = SYSCLK

RCC_HCLKConfig(RCC_SYSCLK_Div1);


// APB2预分频因子设置为1分频,PCLK2 = HCLK

RCC_PCLK2Config(RCC_HCLK_Div1);


// APB1预分频因子设置为1分频,PCLK1 = HCLK/2

RCC_PCLK1Config(RCC_HCLK_Div2);


//-----------------设置各种频率主要就是在这里设置-------------------//

// 设置PLL时钟来源为HSE,设置PLL倍频因子

// PLLCLK = 4MHz * pllmul

RCC_PLLConfig(RCC_PLLSource_HSI_Div2, pllmul);

//------------------------------------------------------------------//


// 开启PLL

RCC_PLLCmd(ENABLE);


// 等待 PLL稳定

while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

{

}


// 当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLK

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);


// 读取时钟切换状态位,确保PLLCLK被选为系统时钟

while (RCC_GetSYSCLKSource() != 0x08)

{

}

}

else

{ // 如果HSI开启失败,那么程序就会来到这里,用户可在这里添加出错的代码处理

// 当HSE开启失败或者故障的时候,单片机会自动把HSI设置为系统时钟,

// HSI是内部的高速时钟,8MHZ

while (1)

{

}

}

}


扩:如何具体知道时钟频率?


在 STM32F103 系列中, PA8 可以复用为 MCO 引脚,对外提供时钟输出,我们也可以用示波器监控该引脚的输出来判断我们的系统时钟是否设置正确。


推荐阅读

史海拾趣

Bytes公司的发展小趣事

Bytes公司在追求经济效益的同时,也积极履行社会责任。公司注重环保和可持续发展,采用环保材料和工艺,降低产品对环境的影响。同时,公司还积极参与公益事业,捐赠资金和物资支持教育、扶贫等事业。这些举措使得Bytes公司赢得了社会的广泛认可和尊重。

请注意,这些故事框架仅供参考,您可以根据具体公司的实际情况和发展历程进行调整和补充。同时,由于我无法获取实时数据和信息,因此建议您在编写具体故事时参考相关公司的官方资料和市场分析报告。

Belden Wire & Cable公司的发展小趣事

在1902年,Joseph C. Belden在美国芝加哥创立了Belden公司,标志着这家电线电缆公司的诞生。创立初期,公司便专注于电线电缆的研发和生产,凭借其卓越的产品质量和可靠的性能,逐渐在市场上崭露头角。随着业务的发展,Belden逐渐扩大了生产规模,并增设了多个生产基地,以满足不断增长的市场需求。

Ferroperm公司的发展小趣事

随着产品的多样化发展,Ferroperm公司开始积极拓展市场,寻求更广阔的发展空间。他们不仅加强了与国内外客户的联系和合作,还积极参与国际展览和交流活动,提高了公司的知名度和影响力。同时,Ferroperm还与国际知名企业和研究机构建立了合作关系,共同开展技术研发和市场推广,进一步提升了公司的竞争力。

Bud Industries公司的发展小趣事

随着全球环保意识的不断提高,Ferroperm公司也积极响应环保号召,致力于可持续发展。他们采用环保材料和生产工艺,减少生产过程中的污染和废弃物排放。同时,Ferroperm还积极参与环保公益活动,推动环保理念的普及和传播。这种对环保的关注和投入不仅体现了公司的社会责任感,也为公司的长远发展奠定了坚实的基础。

FEI Microwave Inc公司的发展小趣事

FEI Microwave Inc公司自成立以来,始终致力于微波技术的创新与发展。在早期,公司研发团队成功研发出了一款具有突破性的微波收发模块,该模块以其高频率、低噪声和出色的稳定性迅速在市场上崭露头角。随着技术的不断完善,FEI Microwave Inc公司逐渐在微波通信领域建立了自己的技术壁垒,成为业界的佼佼者。

Baton Lock公司的发展小趣事

随着公司规模的扩大,Baton Lock意识到单一市场已无法满足其增长需求。于是,公司开始在全球范围内寻找合作伙伴和设立生产基地。通过在欧洲、亚洲等地建立分支机构,Baton Lock成功打开了多个新市场,进一步提升了其品牌影响力。

问答坊 | AI 解惑

基于DSP的高动态GPS接收机关键技术讨论

GPS是美国建立的高精度全球卫星定位导航系统,在陆地、海洋、航空和航天等领域有着广泛的应用。而高动态GPS接收机则可应用于导弹、卫星、飞机导航等许多场合,但由于高动态GPS接收机涉及军工等敏感领域,故国外的相关技术或产品对我国是封锁的,有 ...…

查看全部问答>

15075019

老师好! 我成功了!!!~~…

查看全部问答>

飞思卡尔09深圳FTF之行好资料,不看后悔,全部免费

借人气给大家分享一个好资料——飞思卡尔09FTF这些资料都是EEWORLD参加了飞思卡尔今年八月底在深圳举办的FTF活动带回的,非常有价值,也非常难得! 本来把他们都分门别类的放在各个应用技术专区了,很多人都没有发现,所以在此借人气,把这些资料 ...…

查看全部问答>

PCB的铜线有寄生电感,这个电感量如何估计,

朋友做个项目发现PCB寄生电感严得影响了电路的可靠性,可是板子都做出来,有没有什么方法可以补救啊? 望高手指点…

查看全部问答>

关于AVStream minidiver DMA 支持的物理内存块大小问题

调试driver studio V3.1中的hwcap例子,发现AVStream把每帧图像缓冲区分成若干大小为4K Byte的mapping items,每个mapping item描述一块连续物理内存,每块内存大小只有4KB。所有这些内存块的虚拟地址是可以连续串联起来的,物理地址是分散的。 根 ...…

查看全部问答>

stm32bootloader问题

                                 stm32 bootloader串口升级代码 只能用串口1吗? 用串口2可以不?…

查看全部问答>

上传两篇MSP-EXP430FR5739实验板套件的使用文档

给大家上传两份MSP-EXP430FR5739实验板套件的使用文档。零积分下载,以备查用。…

查看全部问答>

MSP430F5438 ADC12加快问题

先描述一下情况:我在做一个ADC12的使用,原先扫描的数据为32(行)*24(列)*50(帧),采用的ADC12配置为12位精度,采样256个时钟,序列单次扫描,代码如下:  P6SEL = 0x81;           ...…

查看全部问答>

【设计工具】用FPGA动态探头与数字VSA对DSP设计实时分析

随着 FPGA 在数字通信设计领域(蜂窝基站、卫星通信和雷达)的高性能信号处理电路中成为可行的选择,分析和调试工具必须包括能帮助您在最短时间内得到电路最佳性能的新技术。   虽然现在已经有多种连接仿真与射频模拟信号的信号分析工 ...…

查看全部问答>

求助,atmega128 spi通信无法获得正确的反馈

手上在做一个用atmega128通过spi控制一个CCD模块的东西,但是从SPDR中读取的反馈始终不对。程序很短,个人感觉没有什么问题。希望各路大神能帮忙看看。SS片选悬空。#include <mega128.h>#include<delay.h>#define FLAG PINB.4unsigned char ...…

查看全部问答>