STM32F407之时钟、频率、存储概述

本文详细介绍了STM32F407的时钟系统,包括时钟源、PLL配置、电源管理、中断设置等关键内容。时钟源涉及HSI、HSE、PLL等,重点讲解了如何将系统时钟切换至168MHz,并配置Flash等待周期以确保高速运行。此外,还阐述了中断优先级分组和中断服务的设置方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STM32F407之时钟、频率、存储概述

1.整体特性

(1)F407带有FPU,可以进行浮点数硬件计算。

(2)两个DMA,每个有七个流控制器,支持外设和存储器之间的访问,也支持存储器到存储器之间的访问。具有FIFO功能。

(3)具有USB OTG 功能,可以做读卡器,亦可以读取U盘。

(4)具有以太网功能。

(5)两个SRAM(112,16KB),一个CCM RAM(内核耦合存储器)(只能CPU访问),总共192KB内存。

(6)具有FSMC功能(灵活地静态存储器访问)

(7)Flash具有1Mb大小,但bank(块)太大了,使用不便。

总线架构如下:

在这里插入图片描述

注意:每次芯片复位后,所有外设时钟都会被关闭(除了SRAM和Flash),外设使用前必须设置。

注意:对 APB 寄存器执行16位或 8位访问时,该访问将转换为32 位访问:总线桥将16位或8

位数据复制后提供给 32 位向量。

1.1存储器组织架构

程序存储器、数据存储器、寄存器和IO端口在同一个顺序的4GB地址空间内。

各字节按小端模式编码。编号低字节在低位。

可寻址的存储空间分为8个主要块,每个块512MB。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1.2 内嵌SRAM

有4KB的备份SRAM,这是给RTC(实时时钟)用的。

SRAM访问支持字节、16位、32位(字)。

112KB和16KB映射在0x2000 0000上,供所有AHB主控总线访问,是通用SRAM。

64KB的CCM SRAM,只能有CPU通过数据总线访问,个人理解是不能用来DMA传输,正常代码中使用应该没有问题。映射在0x1000 0000。

1.3Flash和自举程序

系统自举模式下从该存储器启动,具有一次性编程OTP字节(512)。

在这里插入图片描述

代码起始区域位于0x0000 0000,这意味通常是Flash提供自举空间。从SRAM自举需要设置中断向量偏离表,这里不关注了。

在这里插入图片描述

这里有几种下载程序模式,通常使用USART1,USB转TTL下载。专用下载器更好。

在这里插入图片描述

可以看到,扇区都挺大的,如果删除,一次删除的东西很多,并不适合频繁读取。

2.电源

期间的工作电压在1.8v<VDD<3.6v,VBAT可给备份域供电。本文暂不考虑备份域。

在这里插入图片描述

AD转换可以接外部参考电压,且大小在1.8v到VDDA之间。

调压器(1.2v域)用于给内核、存储器、数字外设供电,具有三个级别,全功率、低功耗、待机模式,待机模式下SRAM和寄存器的内容将丢失。

电源具有监控功能,当电压低于指定阈值VPOR(上电复位)、VPDR(掉电复位)时,就会保持复位状态,从1.8V开始工作。

欠压复位要求电源电压达到指定VBOR阈值,这个默认关闭。

可编程电压检测器PVD,可配置外部中断,用于执行紧急关闭系统的任务。

默认情况,系统复位和上电复位后,系统都是进入运行模式。

3.时钟介绍
3.1系统复位的触发事件:

(1)NRST引脚低电平(外部复位)

(2)窗口看门狗计数结束(WWDG复位)

(3)独立看门狗计数结束(IWDG复位)

(4)软件复位(SW复位)

(5)低功耗管理复位

软件复位和低功耗管理复位这里不考虑。

除了系统复位还有电源复位、备份率复位。

正常情况不考虑复位,因为这些会让问题变得复杂,除非已经把问题解决好了。

3.2系统时钟(SYSCLK)来源

在这里插入图片描述

在这里插入图片描述

可以看到,时钟非常复杂,这里只考虑额定最高频率168MHz的一种设置情况,超频或者低功耗使用的情况下,这里暂不考虑。

首先,大部分外设由系统时钟提供,指APB和AHB。

但是,USB、RNG、SDIO时钟,是由PLL48CLK提供,不大于48MHz。

12s的时钟,由PPL12SCLK提供,以实现高品质的音频性能。

外部时钟给USB和以太网MAC使用。

Cortex系统定时器(SysTick)(滴答计时器)可以使用8分频的AHB时钟(HCLK),也可以使用HCLK时钟。

定时器的时钟由硬件自动设置,当APB预分频器不为1时,等于APB时钟的2倍,若等于APB预分频器为1,则等于APB时钟频率。

本文中HCLK为168Mhz,APB肯定要分频的,所以定时器的时钟一般是两倍,APB最大42Mhz,所以定时器频率为84Mhz。

3.3HSE高速外部时钟和HSI高速内部时钟

两种配置方式:

在这里插入图片描述

第一种,非本文考虑范围。

一般使用第二种,要记住厂家焊好的晶振,或者自己焊接的晶振频率。

HSI内部信号由16Mhz的RC振荡器生成,准确度不够,系统复位后默认使用的是这个时钟源。

正常情况下,都是用的HSE时钟源,它的精度非常高。

3.4 PLL配置

这个是肯定要配置的,超频的秘诀就在其中,当然本文没有超频内容。

在这里插入图片描述

3.5LSE 低速外部时钟和LSI低速内部时钟

LSE大概率没有。。。。。。

LSI提供32678Hz的频率,RTC主要使用。

3.6时钟输出

最大速率不能超过100Mhz,也就是IO口的最大速率。

(1)MCO1可输出HSI、LSE、HSE、PLL时钟

(2)MCO2可输出HSE、PLL、SYSCLK、PLL12s时钟

本文用不到。

3.7 时钟测量

可以通过TIM5和TIM11的输入捕获功能测量时钟频率,有兴趣的可以试试。

3.8 寄存器配置(168Mhz)

这是关键部分了,RCC_CR 寄存器复位值不为0,第0/1/7位恒为1。

大概是复位后开启HSI时钟作为HCLK主时钟,并且自动校准。

所以我们要做的是把HCLK时钟切换到HSE倍频后的PLLCLK时钟。

(这里就不贴寄存器位描述,这个手册书应该人手一本,有需要给我留言)

留下邮件即可

直接上代码(只有寄存器代码,库函数和HAL库配置都很容易):

RCC->CR|=0x00000001;		//设置HISON,开启内部高速RC振荡
RCC->CFGR=0x00000000;		//CFGR清零 ,清除APB、AHB,PLL等配置
RCC->CR&=0xFEF6FFFF;		//HSEON,CSSON,PLLON清零,只开启HSI时钟
//虽然上述寄存器复位后,值就满足要求,但是这时的设置可适用于更多情况,如运行时修改频率
//CR寄存器上面说了,CFGR寄存器复位值全为0
RCC->PLLCFGR=0x24003010;	//PLLCFGR恢复复位值 
//赋值为复位值
RCC->CR&=~(1<<18);			//HSEBYP清零,外部晶振不旁路
//采用外部晶振,所以不旁路
RCC->CIR=0x00000000;		//禁止RCC时钟中断 
//关闭所有的时钟源就绪中断

u16 retry=0; 
u8 status=0;
RCC->CR|=1<<16;				//HSE 开启 
while(((RCC->CR&(1<<17))==0)&&(retry<0X1FFF))retry++;//等待HSE RDY
//等待HSE稳定,时间8191个系统周期,此时时钟为16Mhz。
if(retry==0X1FFF)status=1;	//HSE无法就绪
else   
{
	RCC->APB1ENR|=1<<28;	//电源接口时钟使能
	//RCC APB1 peripheral clock enable register
	//默认全禁止,详情请看对应寄存器。
	//位 28 PWREN:电源接口时钟使能 (Power interface clock enable)
	PWR->CR|=3<<14; 		//高性能模式,时钟可到168Mhz
	//PWR power control register
	//位 14 VOS:调压器输出电压级别选择 (Regulator voltage scaling output selection)
	//设置为级别1,最高工作性能。
	//其他位为低功耗模式,复位模式,停止模式等配置。
	RCC->CFGR|=(0<<4)|(5<<10)|(4<<13);//HCLK 不分频;APB1 4分频;APB2 2分频. 
	//RCC clock configuration register
	//MCO1/MCO2 输出使能,及分频配置
	//外设时钟配置,分频
	//系统时钟分频,配置。
	//默认情况和具体配置看手册!!!!!!!!!
	//这里只是设置了外设时钟分频,默认系统时钟依旧为HSI
	//AHB默认不分频=168
	//APB1 4分频=168/4=42,此为最大值
	//APB2 2分频,此为最大值84Mhz
	RCC->CR&=~(1<<24);	//关闭主PLL,禁止后才能进行PPL配置-
	//RCC clock control register
	//复位值:0x0000 XX83,其中 X 未定义。功能概览
	//1.PLLI2S 时钟使能及锁定,默认关闭。
	//2.PLL 时钟使能、锁定。
	//3.时钟安全系统
	//4.HSE和HSI时钟控制。
	//默认开启HSI
	RCC->PLLCFGR=pllm|(plln<<6)|(((pllp>>1)-1)<<16)|(pllq<<24)|(1<<22);//配置主PLL,PLL时钟源来自HSE
    //plln:主PLL倍频系数(PLL倍频),取值范围:64~432.
	//pllm:主PLL和音频PLL分频系数(PLL之前的分频),取值范围:2~63.
	//pllp:系统时钟的主PLL分频系数(PLL之后的分频),取值范围:2,4,6,8.(仅限这4个值!)
	//pllq:USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频),取值范围:2~15.
    //外部晶振为8M的时候,推荐值:plln=336,pllm=8,pllp=2,pllq=7.
	//采用等于,覆盖复位值
	//USB,随机,SDIO等外设分频
	//PLL时钟源选择HSE(位22)
	RCC->CR|=1<<24;			//打开主PLL
	while((RCC->CR&(1<<25))==0);//等待PLL准备好 
	//位25,指示PLL是否锁定、就绪。

	//上面是配置好了PLL时钟,但此时CPU时钟为默认时钟HSI=16Mhz,
	//为了提高CPU频率,需要执行对应的操作。参考手册第61页。
	//提高需要先改变flash等待周期数,再选取cpu时钟源
	//降低需要先选择时钟源,再改写等待周期数
	//改变不会立即生效,需要检测两个操作的状态。

	FLASH->ACR|=1<<8;		//指令预取使能.
	FLASH->ACR|=1<<9;		//指令cache使能.
	FLASH->ACR|=1<<10;		//数据cache使能.
	FLASH->ACR|=5<<0;		//5个CPU等待周期. 
	//Flash access control register
	//可设置数据、指令缓存和预存使能。
	//等待周期为5,即工作电压最高。
	RCC->CFGR&=~(3<<0);		//清零
	//清零低2位,即系统时钟选择寄存器
	RCC->CFGR|=2<<0;		//选择主PLL作为系统时钟	 
	while((RCC->CFGR&(3<<2))!=(2<<2));//等待主PLL作为系统时钟成功.
	//检查系统时钟状态 ,等待设置成功。
} 
//设置完成后
//系统最高的CPU工作频率168Mhz
//USb固定为48Mhz,AHB=168Mhz,APB2=84Mhz,APB1=42MHZ,USB=48MHZ。

代码里面注释非常清楚了,这都是看手册注释的,这里补充flash周期选择的原因。

在这里插入图片描述

由于Flash读取速度慢于CPU,当CPU工作频率较高时,需要设置等待周期以至于数据、指令顺利读到,不然会出错。图中明显可以看出需要设置5个周期(168Mhz下),不过不用太担心flash拖累了CPU的速度,stm32有ART自适应实时存储器加速器,可实现“0等待周期”的效果。

上面的代码有几个关键,一个是开启HSE时钟,再就调节PWR-CR寄存器的VOS位,调高电压级别,允许系统全功率运行,再就是通过PLL倍频HSE到合适的频率,设置合理分频频率到各个外设,设置好flash的等待周期。

上面的都成功后,在选取CPU时钟源到PLLCLK,然后等待成功即可。

正常情况,使用168MHz最大配置即可,超频或者低功耗需要先熟悉后再使用。后面也许有文章会考虑这方面需求。

4.中断设置

在这里,只给出最基本的中断设置代码。

STM32F407具有82个中断,内核支持256个,但通常都会限定数量。

具体中断看数据手册。

中断的设置要看M4内核手册,这里定性简单描述下。

SCB->AIRCR寄存器是设置中断优先级分组的,中断有两段优先级,最高是抢占优先级,再就是抢占组里的子优先级。这里就是设置抢占优先级的,stm32最多只支持16位抢占优先级,也就是4位。

4位优先级分组可分五种情况,即0,1,2,3,4位抢占优先级,对应剩下位为响应优先级,即子优先级。

分组0-4即对应上述五种情况,抢占优先级>响应优先级。

然后优先级对应的数字越小,优先级也就越高。

下面是最常见的中断设置代码,中断偏移等本文不考虑。

//设置NVIC分组
//NVIC_Group:NVIC分组 0~4 总共5组 		   
void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)	 
{ 
	u32 temp,temp1;	  
	temp1=(~NVIC_Group)&0x07;//取后三位
	temp1<<=8;
	temp=SCB->AIRCR;  //读取先前的设置
	temp&=0X0000F8FF; //清空先前分组
	temp|=0X05FA0000; //写入钥匙
	temp|=temp1;	   
	SCB->AIRCR=temp;  //设置分组	    	  				   
}


//设置NVIC 
//NVIC_PreemptionPriority:抢占优先级
//NVIC_SubPriority       :响应优先级
//NVIC_Channel           :中断编号
//NVIC_Group             :中断分组 0~4
//注意优先级不能超过设定的组的范围!否则会有意想不到的错误
//组划分:
//组0:0位抢占优先级,4位响应优先级
//组1:1位抢占优先级,3位响应优先级
//组2:2位抢占优先级,2位响应优先级
//组3:3位抢占优先级,1位响应优先级
//组4:4位抢占优先级,0位响应优先级
//NVIC_SubPriority和NVIC_PreemptionPriority的原则是,数值越小,越优先	   
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)	 
{ 
	u32 temp;	  
	MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
	temp=NVIC_PreemptionPriority<<(4-NVIC_Group);	  
	temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
	temp&=0xf;//取低四位
    
	NVIC->ISER[NVIC_Channel/32]|=1<<NVIC_Channel%32;//使能中断位(要清除的话,设置ICER对应位为1即可)
	//ISER有多个寄存器,【】表示选择。
	NVIC->IP[NVIC_Channel]|=temp<<4;				//设置响应优先级和抢断优先级
	//IP 有80个,其中67个可用,每个有32位,每八位控制一个中断向量。   	    	  				   
} 

NVIC_Channel就是官方已经帮你预定义好的中断服务函数名称,这里使能中断,并且设置对应的中断优先级情况。

初始设置就这样了,上面代码只是核心,,,,,

(未完待续)

### STM32F407时钟配置方法 #### 配置概述 STM32CubeMX 是一款功能强大的图形化工具,能够简化基于STM32微控制器的开发过程。对于STM32F407系列芯片而言,在“Clock Configuration”选项卡中可以完成系统时钟和外设时钟频率设定[^1]。 当进入该界面后,可以通过调整PLL(Phase-Locked Loop)、AHB/APB总线分频器以及内部/外部晶振参数来实现目标工作频率的设置。这些操作会直接影响到MCU性能表现及其功耗水平[^2]。 #### 外部高速与时钟源选择 针对高性能需求的应用场景下,推荐启用HSE(External High Speed Oscillator),它提供了更加精确稳定的基准信号给整个系统的运行提供保障;而对于一些特定的功能模块比如RTC(real time counter),则需要用到LSE(Low-speed external oscillator)作为其独立供电下的计时依据,一般固定为32.768KHz[^3]. #### 主要步骤说明如下: - **启动项目并选定设备型号** 打开STM32CubeMX软件之后新建工程文件,并从中挑选出对应的目标器件——即这里所讨论的对象STM32F407VE/VET/E/Z/N/G/B/C/D/W/R/P/T/U/Y/M/L/K/J/H/F/E-DISCO板子之一版本号即可满足要求. - **访问时钟树结构编辑页面** 完成上述基本初始化动作以后,“Pinout & Configuration”标签页里找到 “Clock Configuration”,点击进去就能看到详细的时钟架构图解视窗呈现出来供进一步定制修改之用了。 - **定义核心处理器速度及其他关联参数** 根据实际应用场景的不同考量因素综合权衡决定最终数值大小范围内的合理取舍方案。例如常见的 Cortex-M4 内核最高可达 168 MHz 的主频限制条件下进行优化处理得到最佳平衡点位置处停止迭代计算流程直至达到预期效果为止。 下面给出一段简单的C语言代码片段展示如何读取当前系统时钟值: ```c #include "stm32f4xx_hal.h" uint32_t GetSysClockFreq(void){ return HAL_RCC_GetSysClockFreq(); } ``` 此函数利用HAL库封装好的API接口调用来获取实时更新后的全局变量存储地址指向的内容返回给调用者继续后续逻辑运算分析判断分支走向等等用途广泛适用性强兼容性好易于维护扩展升级等功能特性兼具一身值得信赖长期合作共谋发展大业! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值