STM32

您所在的位置:网站首页 时钟的时针运动是什么现象形成的 STM32

STM32

2024-07-11 11:02:15| 来源: 网络整理| 查看: 265

前言

时钟系统是MCU必不可少的一部分,本文将针对以下问题进行讨论:

什么是时钟?如何理解STM32时钟结构?为什么MCU会有多个时钟源?STM32如何配置时钟 ?

目录

一、时钟简介

二、STM32时钟树

2.1、STM32F10X时钟源

2.2、系统时钟

三、关于时钟的一些思考

3.1、 时钟频率

3.2、多个时钟源

四、时钟配置分析

1、开始HSE时钟

2、等待HSE就绪(因为时钟起振等原因一定要有一部分时间缓冲稳定)

3、HSE状态正常就继续,异常就立即处理

3.1.1 HSE状态正常情况分析

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

3.1.3 选择PLL的时钟源

3.1.4 开启PLL时钟并等待就绪(凡是开启了就要等待)

3.1.5 选择PLL作为系统时钟源(默认也是这样)

五、总结

5.1 配置时钟的流程

5.2 学习一款MCU的时钟流程

一、时钟简介

首先,我们得搞清楚几个概念:

时钟:单片机的心脏,所有的外设的运作都需要时钟供能。时钟周期:又称为振荡周期,可以简单理解为传输一个0或1所需要的时间指令周期:执行一条指令(如 MOV A, #34H)所需要的时间。对于不同类型的指令,指令周期长度可能不同。机器周期:执行一个动作的时间周期。如:执行一个指令需要”取指令并译码“、”执行操作数“两个动作。

以上三个周期的关系图如下:(图为转载)

(其中蓝色部分包括了四个机器周期)

而因为时钟信号也是电信号的一种,所以它还兼具了供能的作用,且因电平变化的时间间隔一定,我们甚至可以用时钟来计时间(PS:这里时钟”供能“的说法是错误的,时钟并不能起到供能的作用,但是我觉得对于初学者而言,这样感性的理解问题也不大,只有记得时钟并不供能即可)

二、STM32时钟树

有了以上的感观认识之后,我们先来看看STM32F10X的时钟树:

2.1、STM32F10X时钟源

上图蓝色部分标出了 STM32的5个时钟源,分别是:

HSI:高速内部时钟(High Speed Internal),由芯片内部RC振荡器产生,频率为8MHZHSE:高速外部时钟(High Speed External),可外接4-16MHZ的晶振作为时钟源LSE:低速外部时钟,外接32.768KHZ时钟源LSI:低速内部时钟,由芯片内部的RC振荡器产生,频率为40KHZPLL:锁相环倍频输出。可以做到输入时钟的2-16倍的倍频输出

PS:这里把PLL也列为时钟源是参考了诸如正点原子和野火资料的说法,个人觉得实际的时钟源严格来说只能算4个,因为PLL本身只起倍频作用,本身并不能产生时钟频率。当然,这些都是人为定义的,不会影响使用和该知识点的理解,且有助于理解该知识。

2.2、系统时钟

知道有哪些时钟源之后,我们可以发现时钟树其实是我们熟知的AHB、APB1、APB2总线

时钟源与这些外设之间都通过红色部分的系统时钟SYSCLK连接在一起,由此观之这个系统时钟SYSCLK很重要!!!

可以看到,系统时钟有三个输入源:

HSI:8MHZPLLCLK:8-128MHZ(外接晶振一般为8MHZ)HSE:4-16MHZ

而SYSCLK可以接受的最大频率是72MHZ,这也是后面所有外设可以正常运作的频率。

可以见到,想要达到这个数字,只能通过PLL倍频得到(不止得到,你还可以用它超频)

对了,SYSCLK选择还连着一个CSS的东西,查了数据手册可以知道,CSS(时钟安全系统)

 

 可以看到,这东西简单点来说就是一个报警器。帮你检测HSE有没有问题,有的话先切换到内部时钟源HSI,然后提示相关信息。

分析到这里,我们对STM32时钟树可以有个相对清晰的认识:时钟源、然后配置总线时钟(AHB、APB1、APB2),最后具体总线上的外设的时钟挂载在总线时钟上

下面补充下没有提到的点:

低速内外部时钟应用(LSI和LSE)

低速时钟LSI和LSE简单从时钟树图中也可以看到,其中这两者都可以作为RTC(实时时钟)的时钟源,并且HSE的分频也可以,再者LSI可以作为独立看门狗时钟

MCO时钟输出:用于示波器观察时钟信号,调试用,简单来说可以测时钟源的频率,直观看波形 三、关于时钟的一些思考 3.1、 时钟频率

从2.1和2.2的讨论中,我们可以发现,系统时钟正常工作的时钟频率是72MHZ。但实际输入的系统时钟频率最大可以达到128MHZ,最低8MHZ,这意味着我们可以不遵循数据手册的规定,做点"违规操作"

我从网上找的的回答有:

频率高了,系统稳定性会受到影响,具体表现是进行通信的时候,外设可能无法接收到准确的信号以及功耗会变大频率低了,不能满足设备的频率要求,可能无法启动设备 3.2、多个时钟源

可能大家一开始接触时钟都会有这样一个疑问,为什么需要那么多时钟源,又分内部时钟源和外部时钟源?尽然外设都是受系统时钟管理,那么只用一个时钟不是就足够了吗?

基于以上的问题,翻阅资料和网上回答,得到的两个明显的结论:

多个时钟源可以在单个时钟源发生故障时,起到救急的作用一个外设有多个时钟源,可以根据需要选择相应频率的时钟源 四、时钟配置分析

STM32时钟树理解之后,就是时钟的配置问题了。

实际上,当我们创建工程导入启动文件的时候,在main函数开始调用之前,启动文件就已经调用了SystemInit函数对系统时钟进行初始化了。(这里说下启动文件的5个作用,设置堆栈指针、设置PC指针、初始化中断向量表、配置系统时钟、调用C库函数_main最终去到C的世界)。

那为什么还需要做配置分析?直接拿来用不就好了嘛?

我们且不论其它芯片如何,单就看stm32的固件库给我们提供的库函数(下图system_stm32f10x.c的截图):

 

人家ST官方只提供了24MHz,36MHz,48MHz,56MHz,72MHz五种频率的系统时钟设置。

如果项目对时钟有这5种频率外的需求还是得自己动手。基于以上原因,对时钟配置的分析就是刚需了。

那么,先让我们对着时钟树的图再梳理一遍系统时钟的来龙去脉。

输入源:

HSI直接输出,频率只有8MHz。HSE直接输出,范围4-16MHz,一般为8MHz。PLL:锁相环倍频输出,倍频范围是2-16倍。且PLL自身有两个输入源:HSI 二分频输出至PLL,这种方式的系统时钟最高可至64MHz。HSE直接输出至PLL。

输出源:

直接输出。输出至AHB总线,经预分频器可做 1~512 分频。AHB总线预分频后,经低速外设总线APB1和高速总线APB2。

因为考虑到功耗的问题,外设只有用到的时候才会开启时钟,所以SYSCLK只需要初始化总线时钟即可。

基于这个原因,对于系统时钟配置的流程大概可以总结为以下步骤:

1、选择并开启时钟源(使用PLL作为系统时钟源还需要选择倍频系数)

2、选择APB1、APB2和AHB的预分频系数

我想这里肯定有人和我一样,初学的时候有这样的疑惑,你这怎么一下子从时钟树的左边一下子跳到最右边,简直毫无逻辑可言(cnm),其实不然

如果AHB先开启,而APB1和APB2未设置的话会出现紊乱

下面以库函数 SetSysClockTo72()为示例,搭配数据手册学习配置过程,先把源码贴上:

* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 * and PCLK1 prescalers. * @note This function should be used only after reset. * @param None * @retval None */ static void SetSysClockTo72(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ /* Enable HSE */ RCC->CR |= ((uint32_t)RCC_CR_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CR & RCC_CR_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* Enable Prefetch Buffer */ FLASH->ACR |= FLASH_ACR_PRFTBE; /* Flash 2 wait state */ FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; /* HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; #ifdef STM32F10X_CL /* Configure PLLs ------------------------------------------------------*/ /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); /* Enable PLL2 */ RCC->CR |= RCC_CR_PLL2ON; /* Wait till PLL2 is ready */ while((RCC->CR & RCC_CR_PLL2RDY) == 0) { } /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL9); #else /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); #endif /* STM32F10X_CL */ /* Enable PLL */ RCC->CR |= RCC_CR_PLLON; /* Wait till PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) { } } else { /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */ } } #endif

第一眼看上去很长,寄存器也很多,但是没有关系。先把出现的寄存器记下来:

RCC->CRRCC->CFGRRCC->CFGR2FLASH->ACR

然后干嘛?当然是去查查手册这些寄存器是干嘛用的呀!由于还是小萌新阶段,只需要了解上面每个寄存器大概的作用结合源码学习即可,手册暂时不必深究。

 

 

 结合以上认识,下面我们来一段一段分析源码:(耐心对着参考手册看寄存器的各个位的作用)

1、开始HSE时钟 * SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ /* Enable HSE */ RCC->CR |= ((uint32_t)RCC_CR_HSEON);//HSEON -> HSE_ON 2、等待HSE就绪(因为时钟起振等原因一定要有一部分时间缓冲稳定) /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CR & RCC_CR_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } 3、HSE状态正常就继续,异常就立即处理

状态异常的话,经条件语句跳到下面用户可以自行定义异常处理

3.1.1 HSE状态正常情况分析 /* Enable Prefetch Buffer */ FLASH->ACR |= FLASH_ACR_PRFTBE; ​ /* Flash 2 wait state */ FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;

这里涉及到FLASH编程的知识,其中我看正点原子给的解释是CPU的反应速度快于FLASH的速度,所以这里需要等待两个状态,等待几个状态看你的时钟配置,可以看FLASH编程手册,里面有讲解(48-72MHZ是两个状态时间)

3.1.2 设置AHB 、APB1、APB2的预分频因子 /* HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 3.1.3 选择PLL的时钟源

源码里这段其实还有二三十行代码,不过那是互联型芯片的配置代码,这里f103是基础型,所以先暂时略过不看。

/* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); ​ /* HSE 与上 PLLMULL9 做到 72MHz的系统时钟输出 */ RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); 3.1.4 开启PLL时钟并等待就绪(凡是开启了就要等待) /* Enable PLL */ RCC->CR |= RCC_CR_PLLON; ​ /* Wait till PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) { } 3.1.5 选择PLL作为系统时钟源(默认也是这样) /* Select PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; ​ /* Wait till PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) { } 五、总结 5.1 配置时钟的流程 开启时钟并等待就绪若时钟异常就退出(用户可自行作相关异常处理)开启正常,先配置相关总线的预分频系数最后选择系统时钟是PLL还是HSI或者HSE,让外设得到时钟 5.2 学习一款MCU的时钟流程 看时钟树——分析时钟的来龙去脉查数据手册,找到以下问题的答案:时钟源怎么开启?相关外设的时钟怎么控制系统时钟源怎么选择

最后,理论赋予实践,自己动手配置一个其他的时钟或者自己写一个时钟配置函数,下面可参考我写的基于固件库函数的时钟配置函数写法(ST官方的都是基于寄存器编程的配置)



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭