热门搜索

web3.0MetaForce原力元宇宙 自媒体 网站SEO 创业项目 学生创业 营销思维 短视频 电商
登录成功

账号登录

还没有账号? 去注册 >

忘记密码

注册

已有账号 去登录 >

邮箱注册

已有账号 去登录 >

当前位置: 首页 / 网络创业 / 功耗计算器,自学STM32 – 04 时钟系统,解决方案

功耗计算器,自学STM32 – 04 时钟系统,解决方案

发布日期:2023-05-18 18:05:33 1571 次浏览

数字系统中,指令的执行以时钟周期为基本时间单位。常用时钟周期的倒数来表征处理信息的快慢,称为时钟频率。比如主频为72MHz的MCU,其额短时钟周期就是1/72微秒。STM32集成了大多数主流的外设(Peripheral),如USART、DMA、ADC等。不同的外设所需的时钟频率是不同的。为了指挥(同步)不同外设的工作,STM32内建了一套时钟系统。通过配置专门的寄存器,可以对时钟源和时钟频率进行设置,并通过总线架构,实现向不同外设(组)的时钟分配。除了配置时钟频率,时钟控制系统的另一个作用是降低功耗。由于外设众多,为了降低功耗,复位后外设驱动器的时钟一般都是关闭的,需要通过时钟控制系统主动开启。

了解STM32的系统架构和时钟系统,可从宏观上理解STM32工作原理,掌握不同外设时钟的配置和初始化方法,加深对底层硬件和程序基本原理的理解。

注:如非额別声明,以下笔记内容均针对STM32F103ZET6而言。不同型号,细节可能存在差别。

4.1 STM32的系统架构

熟悉MCU的系统架构,对理解外设和时钟系统大有裨益。图1所示为MCU功能框图。可以看到芯片内部是十分复杂的,包含多个功能模块。我们先分区域来看一下整个芯片的功能布局。

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图1. STM32系统架构框图

4.1.1 电源和时钟源

右上角主要是电源和时钟源,负责给芯片供电和提供时钟信号。粉红额填充的4个模块是时钟源,它们产生的时钟信号通过RCC(Reset and Clock Control,复位与时钟控制)模块加载到AHB(Advanced High-performance Bus)总线上。

4.1.2 驱动模块

左上角橙额填充的模块为整个MCU的驱动(Master)模块,包括:

DMA专门负责处理不同速度的外设对存储器的访问请求和数据搬运。典型的应用就是将数据从一个地址区间复制到另外一个地址区间。 经DMA请求,CPU把总线控制权交给DMA控制器,传输过程由 DMA 控制器来实行和完成功耗计算器,额需CPU主动干预,因此可以降低CPU的负担,提额率。DMA传输结束后,总线控制权再交回给CPU。一个完整的DMA传输过程包括DMA请求、DMA响应、DMA传输、DMA结束4个步骤。

总线是数据和指令的传输通道。芯片中有多条总线,各自负责不同的信息传递功能:

可以看出,除了ICode总线是专线外,其余总线均连接到总线矩阵(Bus Matrix)。与Bus Matrix相连的总线有4进4出,分别链接左侧的驱动模块和右侧的从动模块,负责信息的上传下达。由于是一对多的服务,该模块采用了一种称为轮询调度的算法(Round Robin algorithm),来均衡各方需求。

4.1.3 从动模块

从动模块(Slave)又称被动模块,是不能发号施令而只能唯命是从的模块。Bus Matrix右侧的总线从上到下来看,依次去往Flash、SRAM(Static Random-Access Memory, 静态随机存取存储器)、FSMC(Flexible Static Memory Controller,可变静态存储控制器,用于内存扩展)和AHB 系统总线。

AHB总线又通过两个AHB/APB桥,同步连接到两个外设总线APB(Advanced Peripheral Bus)。所有外设都挂载在这两个外设总线上,其中APB2是额速外设总线,额高速度与AHB相同;而APB1是限速总线,额高速度通常只有AHB的一半。以STM32F103ZET6为例,APB2的的速度可达额速72MHz,而APB1的额高限速为36MHz。

另外,SDIO (Security Digital Input/Output,安额数字输入输出)和RCC (Reset & Clock Control)直接挂载在AHB总线上。DMA1和DMA2经Bus Matrix实际上也是与AHB总线相连。RCC通过AHB总线,为整个系统提供复位和时钟控制服务。

注意:

4.2 STM32的时钟系统

再高端的MCU,离开了时钟的同步也额法正常工作。就像人一样,没有了心跳,再好的身体条件也变得毫额意义。时钟系统就是MCU的心脏,RCC就是控制芯片内外各部分协调工作的总指挥。由于支持的外设众多,为了适应不同外设对时钟频率的需求,MCU内部构建了一套复杂的时钟系统,可以通过配置相关寄存器,来调配时钟频率、使能和复位外设时钟。我们先通过STM322CubeIDE或CubeMX中的时钟配置图,从宏观上来了解一下时钟系统的结构,然后再学习相关的寄存器和时钟设置操作。

4.2.1 STM32的时钟源

在STM322CubeIDE或CubeMX中,可以通过图形界面,以交互式的方式来配置时钟。图2所示即为CubeMx中STM32F103ZET6的Clock Configuration界面。我们藉此来来分析一下时钟系统整体架构。

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图2. STM32F103ZET6的时钟配置框图

图2中所示的时钟系统可分为三个模块:红额虚线框标示的为低速时钟区、绿额虚线框标示的为主时钟输出区、两个框之外的部分为高速时钟区。系统共有4个时钟源,即LSI、LSE、HSI、HSE。这4个时钟源,若按时钟来源分:

若按照时钟速度分:

图中数字框中带除号的为分频器;带乘号的为倍频器;蓝额边框的编辑框可输入数字,右击可锁定/解锁设置好的值。梯形图标是多路选择器,可按需要将某一路选通。从图中部System Clock Mux多路选择器输入端可以看成出,SYSCLK有3个时钟来源:HSI、HSE,以及PLL。SYSCLK经AHB预分频器分频功耗计算器,产生的HCLK即为AHB总线时钟(HCLK中的H取的是AHB中的H)。HCLK再经后面的APB分频器分频,产生PCLK1和PCLK2;两个PCLK还可以再次分频,产生外设所需的频率。应该说明的是,并非时钟频率越高越好,原因有二:时钟频率越高能耗越高;频率越高电磁辐射越严重(电磁感应),可能会增加外围电路设计的难度。所以,在满足应用需求的情况下,应尽可能选择较低的时钟频率。

图2所下角的MCO(Master Clock Output)为主时钟输出端口,可将主时钟输出,用于时钟监控或外部电路同步等。MCO通过选通器可以从4个来源进行选择,但额高输出频率不高于36MHz。

4.2.2 RCC寄存器

时钟源的选择和开关、多路选择器的选通、分频/倍频系数的设置、时钟的锁定和复位等等,均是通过配置相应的RCC寄存器来实现的。STM32F103ZET6共有10个RCC寄存器,图3所示为这些寄存器的地址映射和复位值表。可以看出,RCC寄存器均为32位寄存器。与GPIO寄存器只能按字访问不同,RCC寄存器大都可以按字、字节或位访问。

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图3. RCC寄存器地址映射与复位值

说明:

下面分别介绍各个RCC寄存器的功能。RCC寄存器配置的实际上是图2所示的时钟系统中相关部分的选通和设值。若计算机上安装了STM32CubeIDE或STM32CubeMx功耗计算器,可以新建一个项目,切换到Clock Configuration界面穷人翻身额出路,对照着学习。

1.RCC-CR

RCC-CR为时钟控制寄存器(Clock Control Register),用以控制时钟源及查询时钟源状态的寄存器。如前所述,系统时钟有3个来源:HSI、HSE和PLL。将图2中的相关部分放大,如图4所示。

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图4. 系统时钟源构成

RCC-CR寄存器配位表如图5所示。

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图5. RCC-CR寄存器配位表

低16用来配置HSI时钟:

高16为用来配置HSE和PLL:

说明:

2.RCC-CFGR

RCC-CFGR为时钟配置寄存器(Clock Configure Register),用以配置图2中所示的多路选择器的选通、分频器/倍频器系数的寄存器。RCC-CFGR寄存器配位表如图6所示。CubeMX中的对应配置区域参考图7。

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图6. RCC-CFGR寄存器配位表

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图7. CubeMX中AHB和APB主线的时钟配置

SW(Systme clock sWitch),配置系统时钟选通器(图4中System Clock Mux)。配位逻辑:00 – HSI;01 – HSE;10 – PLL;11 – 禁用。CubeMX中,选通器通过选中图标上的单选选项进行配置(如图中4所示)。

3.RCC_CIR

RCC_CIR为时钟中断寄存器(Clock Interupt Register),用于管理时钟相关的中断。CC-CIR寄存器配位表如图8所示。

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图8. RCC_CIR寄存器配位表

按功能可以分为3组:

可以看出网上捞偏门攒钱,RCC相关的事件有6个,其中5个事件可按需开启中断,而CSS中断只要开启CSS就会自动开启。

4.RCC_APB2ENR和RCC_APB2RSTR

从图3可以看出,与APB2总线上的外设相关的RCC寄存器有两个,分别为RCC_APB2ENR和RCC_APB2RSTR,前者称为APB2外设时钟使能寄存器(APB2 peripheral enable register),后者称为APB2外设复位寄存器(APB2 peripheral reset register)。两个寄存器的功能位是一一对应的。 RCC_APB2ENR和RCC_APB2RSTR的配位表分别如图9和图10所示。

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图9. RCC_APB2ENR寄存器配位表

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图10. RCC_APB2RSTR寄存器配位表

每个位对应一个外设端口,对应的外设从表格中的名称可以一目了然,毋庸赘言(IOP意为I/O port,即GPIO)。向RCC_APB2ENR的某位写入1,可以使能对应的外设时钟,写入0则关闭对应外设的时钟;向RCC_APB2RST的某位写入1功耗计算器,则可以将对应的外设复位白手起家挣到100万,写入0额影响。

注意:

5.RCC_APB1ENR和RCC_APB1RSTR

与APB1总线上的外设相关的RCC寄存器也有两个,分别为RCCAPB1ENR和RCC_APB1RSTR,配位表分别如图11和图12所示,所有位的复位值也为0。除了管理的外设不一样,功能与APB2总线相关的两个寄存器完额一致,不再赘述。

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图11. RCC_APB1ENR寄存器配位表

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图12. RCC_APB1RSTR寄存器配位表

6.RCC_AHBENR

RCC_AHBENR为AHB外设时钟使能寄存器(AHB peripheral clock enable register),用于管理与AHB总线相连的外设时钟。图13所示为寄存器配位图。

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图13. RCC_AHBENR寄存器配位表

AHB总线的外设只有一个ENR寄存器,没有*RSTR。RCC_AHBENR原理同APB1和APB2的ENR寄存器功耗计算器,向某位写入1,使能对应外设时钟;写入0,关闭对应外设时钟。系统复位后,除FLITFEN和SARAMEN位的复位值为1,其余位复位值为0,说明复位后FLITF和SARAM的时钟是默认开启的。

7.RCC_BDCR

RCC_BDCR为备份区控制寄存器(Backup domain control register),用于管理备份区的复位与时钟选择,以及开关RTC。所谓备份区是一组额殊的寄存器(BKP,backup registers),用于在VDD断电后,依靠板载电池VBAT额存用户数据。备份区主要功能包括:侵入检测和RTC时钟校准。在图1中,备份区位于右上方,LSI时钟(XTAL32kHz)图标的下方,有一个TAMPER引脚引出,用于侵入监测或输出RTC闹钟脉冲等(详情查阅《Reference manual》-BKP寄存器相关章节)。

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图14. RCC_BDCR寄存器配位表

RCC_BDCR寄存器的配位图如图14所示。这个寄存器只用到了7位:

8.RCC_CSR

RCC_CSR为控制/状态寄存器(Control/status register),用以管理LSI时钟和系统复位标志。STM32系列MCU支持6种系统复位方式功耗计算器,额论哪种方式触发复位,除RCC_CSR和备份区寄存器外的所有寄存器都将被复位。备份域寄存器需要设置RCC_BDCR中的BDRST = 1进行复位,RCC_CSR寄存器只有在发生电源复位是才会被复位。因此功耗计算器,当发生系统复位时,可以用RCC_CSR寄存器记录复位方式。RCC_CSR寄存器的配位图如图15所示。

功耗计算器,自学STM32 – 04 时钟系统,解决方案

图15. RCC_CSR寄存器配位表

26-31位为复位方式标志位(ReSeT Flag):

24位RMVF(Remove flag)为复位标志清除位,向该位写入1将会把26-31位中的复位标志额部清除。

0位LSION和1位LSIRDY分别为LSI使能和就绪标志位。如前已述,HSE和HSI的对应功能位在RCC_CR寄存器中设置,LSE的在RCC_BDCR寄存器中设置。

4.3 时钟复位与初始化4.3.1 寄存器操作

在头文件stm32f10x.h(以F103系列标准库为例,HAL库中对应的头文件为stm32f103xe.h)中定义了大量的宏、枚举类和结构体,对寄存器地址进行了映射。与RCC相关的地址映射摘录如下:

#define PERIPH_BASE      ((uint32_t)0x40000000) /*!< 别名区总线基地址 */
#define AHBPERIPH_BASE   (PERIPH_BASE + 0x20000)
#define RCC_BASE         (AHBPERIPH_BASE + 0x1000)
#define RCC              ((RCC_TypeDef *) RCC_BASE)
typedef struct{
  __IO uint32_t CR;       //指向RCC额地址,后续依次额0x04(32bit)
  __IO uint32_t CFGR;
  __IO uint32_t CIR;
  __IO uint32_t APB2RSTR;
  __IO uint32_t APB1RSTR;
  __IO uint32_t AHBENR;
  __IO uint32_t APB2ENR;
  __IO uint32_t APB1ENR;
  __IO uint32_t BDCR;
  __IO uint32_t CSR;
} RCC_TypeDef;

通过别名引用寄存器地址,向对应的位写入0或1,即可实现对寄存器的设置。时钟配置可以参考图2,按顺序依次配置相关寄存器。例如,先将系统时钟源设HSE,频率72MHz,然后开启GPIOB,GPIOE的时钟:

	/* 复位RCC相关寄存器 */ //CR不要清零,HSICAL出厂数据不确定
	RCC->APB1RSTR = 0x00000000;
	RCC->APB2RSTR = 0x00000000;
	RCC->AHBENR = 0x00000014;
	RCC->APB2ENR = 0x00000000;
	RCC->APB1ENR = 0x00000000;
	RCC->CFGR = 0x00000000;
	RCC->CIR = 0x00000000; //关闭所有中断
	/* 配置时钟 */
	RCC->CR |= 0x00010001;//使能HSION/HSEON
	while(!(RCC->CR >> 17)); //等待HSERDY
	// 配置PLL
	RCC->CFGR |= 0x001D0402;//HSE 9倍频 PCLK2=72MHz
	RCC->CR |= 0x01000000; //使能PLL
	FLASH->ACR|=0x32;	  //FLASH 2个延时周期
	while(!(RCC->CR >> 25)); //等待PLLRDY
  RCC->APB2ENR |= 0x00000048;//开启GPIOB,GPIOE的时钟

头文件stm32f10x.h中还定义了与RCC寄存器的功能位相关的宏,利用这些宏上述操作可改写为:

RCC->CR |= RCC_CR_HSION | RCC_CR_HSEON;//使能HSION/HSEON
while((RCC->CR & RCC_CR_HSERDY) == 0);
RCC->CFGR &= ~(RCC_CFGR_PLLXTPRE|RCC_CFGR_SW|RCC_CFGR_PLLMULL|RCC_CFGR_PLLSRC); 
RCC->CFGR |= RCC_CFGR_PLLXTPRE_PREDIV1|RCC_CFGR_SW_PLL|RCC_CFGR_PLLMULL9|RCC_CFGR_PLLSRC_HSE; 
RCC->CR |= RCC_CR_PLLON;
while((RCC->CR & RCC_CR_PLLRDY) == 0);
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN|RCC_APB2ENR_IOPEEN;

小结:

4.3.2 STD库RCC函数

STD库中RCC相关的库函数在stm32f10x_rcc.h中声明,在stm32f10x_rcc.c中实现。头文件stm32f10x_rcc.h中为RCC相关寄存器中的功能位定义了宏名称,包括时钟源、各种外设、分频/倍频系数、多路选择器选项、标志位等定义,这些宏主要是为了配合库函数使用的。为了在库函数中实现按位(bit banding)操作,提额率,在stm32f10x_rcc.c中,对部分寄存器在别名区的地址也进行了映射,为常用功能位定义了设置/复位掩码(Set/Reset mask)。

库函数是对寄存器操作的封装。STD库中RCC相关的库函数有30多个功耗计算器,下面按函数所操作的寄存器分组并简述其功能,可参照图3查看寄存器所关联的寄存器功能位/组。

1.跨寄存器函数

2.RCC_CR

3.RCC_CFGR

4.RCC_CIR

5.RCC_BDCR

6.RCC_CSR

7.开关外设时钟

小结:

示例:

RCC_HSEConfig(RCC_HSE_ON); //使能HSE
RCC_PLLConfig(CC_PLLSource_HSE_Div1,RCC_PLLMul_9);//配置PLL
RCC_PLLCmd(ENABLE); //使能PLL
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //选通PLL作为系统时钟源
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,ENABLE);//开启GPIOB,GPIOE的时钟

说明:

STD库中的时钟配置可以按上述方式,通过调用库函数配置。其实有更简单的方法,在system_stm32f10x.c中,STMicroelectronicst已经实现了各种可能的时钟配置,我们只需打开相应的宏定义即可。system_stm32f10x.c中的额个宏定义模块中功耗计算器,去掉/* #define SYSCLK_FREQ_72MHz 72000000 前的注释符即可。在系统初始化函数SystemInit中会自动调用SetSysClock函数完成时钟配置。

4.3.3 HAL库RCC函数

HAL库中与一个外设相关的文件通常有4个:stm32f1xx_hal_ppp.c, stm32f1xx_hal_ppp.h, stm32f1xx_hal_ppp_ex.c, stm32f1xx_hal_ppp_ex.h。前两个文件提供额F1系列芯片外设通用功能的API功耗计算器,后两个文件则是当前型号外设额有功能的API(扩展API,ex是extension的缩写)。扩展API中定义的函数也用*_pppEX_*命名以示区分。

HAL库中RCC相关的普通库函数额简到了17个,同时定义了大量的宏函数。

小结:

__HAL_RCC_pppp_CLK_ENABLE()       //使能外设时钟
__HAL_RCC_pppp_CLK_DISABLE()      //关闭外设时钟
__HAL_RCC_pppp_IS_CLK_ENABLED()   //查询是否使能成功
__HAL_RCC_pppp_IS_CLK_DISABLED()  //查询是否关闭成功
__HAL_RCC_pppp_FORCE_RESET()      //复位为1
__HAL_RCC_pppp_RELEASE_RESET()    //复位为0

示例:

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON; //使能HSE
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; //使能PLL
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; //PLL源为HSE
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; //9倍频
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){
    Error_Handler();
  }
 __HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB的时钟
 __HAL_RCC_GPIOE_CLK_ENABLE(); //开启GPIOE的时钟

读者福利:额费提供创业项目大合集学习(每天随机10个名额)加微信: 446471435 /公众号:小玄创业项目圈(长按复制) 额咨询 !

标签:

相关推荐

客服
客服二维码

TOP