第15章 RCC—使用HSE/HSI配置时钟—零死角玩转STM32-F429系列

第15章     RCC—使用HSE/HSI配置时钟

全套200集视频教程和1000PDF教程请到秉火论坛下载:www.firebbs.cn

野火视频教程优酷观看网址:http://i.youku.com/firege

 

 

 

本章参考资料:《STM32F4xx中文参考手册》RCC章节。

学习本章时,配合《STM32F4xx中文参考手册》RCC章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分。

RCC reset clock control  复位和时钟控制器。本章我们主要讲解时钟部分,特别是要着重理解时钟树,理解了时钟树,F429的一切时钟的来龙去脉都会了如指掌。

1.1 RCC主要作用—时钟部分

设置系统时钟SYSCLK、设置AHB分频因子(决定HCLK等于多少)设置APB2分频因子(决定PCLK2等于多少)、设置APB1分频因子(决定PCLK1等于多少)、设置各个外设的分频因子;控制AHB、APB2和APB1这三条总线时钟的开启、控制每个外设的时钟的开启。对于SYSCLK、HCLK、PCLK2、PCLK1这四个时钟的配置一般是:HCLK = SYSCLK=PLLCLK = 180M,PCLK2=HCLK/2 = 90MPCLK1=HCLK/4 = 45M。这个时钟配置也是库函数的标准配置,我们用的最多的就是这个。

1.2 RCC框图剖析—时钟树

时钟树单纯讲理论的话会比较枯燥,如果选取一条主线,并辅以代码,先主后次讲解的话会很容易,而且记忆还更深刻。我们这里选取库函数时钟系统时钟函数:SetSysClock(); 以这个函数的编写流程来讲解时钟树,这个函数也是我们用库的时候默认的系统时钟设置函数。该函数的功能是利用HSE把时钟设置为:HCLK = SYSCLK=PLLCLK = 180M,PCLK1=HCLK/2 = 90MPCLK1=HCLK/4 = 45M下面我们就以这个代码的流程为主线来分析时钟树,对应的是图中的黄色部分,代码流程在时钟树中以数字的大小顺序标识。

151 STM32F429时钟树

1.2.1 系统时钟
1.    ①HSE高速外部时钟信号

HSE是高速的外部时钟信号,可以由有源晶振或者无源晶振提供,频率从4-26MHZ不等。当使用有源晶振时,时钟从OSC_IN引脚进入,OSC_OUT引脚悬空,当选用无源晶振时,时钟从OSC_IN和OSC_OUT进入,并且要配谐振电容。HSE我们使用25M的无源晶振。如果我们使用HSE或者HSE经过PLL倍频之后的时钟作为系统时钟SYSCLK,当HSE故障时候,不仅HSE会被关闭,PLL也会被关闭,此时高速的内部时钟时钟信号HSI会作为备用的系统时钟,直到HSE恢复正常,HSI=16M。

2.    ②锁相环PLL

PLL的主要作用是对时钟进行倍频,然后把时钟输出到各个功能部件。PLL有两个,一个是主PLL,另外一个是专用的PLLI2S,他们均由HSE或者HSI提供时钟输入信号。

主PLL有两路的时钟输出,第一个输出时钟PLLCLK用于系统时钟,F429里面最高是180M,第二个输出用于USB OTG FS的时钟(48M)、RNG和SDIO时钟(<=48M)。专用的PLLI2S用于生成精确时钟,给I2S提供时钟。

HSE或者HSI经过PLL时钟输入分频因子M(2~63)分频后,成为VCO的时钟输入,VCO的时钟必须在1~2M之间,我们选择HSE=25M作为PLL的时钟输入,M设置为25,那么VCO输入时钟就等于1M。

VCO输入时钟经过VCO倍频因子N倍频之后,成为VCO时钟输出,VCO时钟必须在192~432M之间。我们配置N为360,则VCO的输出时钟等于360M。如果要把系统时钟超频,就得在VCO倍频系数N这里做手脚。PLLCLK_OUTMAX = VCOCLK_OUTMAX/P_MIN = 432/2=216M,即F429最高可超频到216M。

VCO输出时钟之后有三个分频因子:PLLCLK分频因子p,USB OTG FS/RNG/SDIO时钟分频因子Q,分频因子R(F446才有,F429没有)。p可以取值2、4、6、8,我们配置为2,则得到PLLCLK=180M。Q可以取值4~15,但是USB OTG FS必须使用48M,Q=VCO输出时钟360/48=7.5,出现了小数这明显是错误,权衡之策是是重新配置VCO的倍频因子N=336,VCOCLK=1M*336=336M,PLLCLK=VCOCLK/2=168M,USBCLK=336/7=48M,细心的读者应该发现了,在使用USB的时候,PLLCLK被降低到了168M,不能使用180M,这实乃ST的一个奇葩设计。有关PLL的配置有一个专门的RCC PLL配置寄存器RCC_PLLCFGR,具体描述看手册即可。

PLL的时钟配置经过,稍微整理下可由如下公式表达:

VCOCLK_IN = PLLCLK_IN / M = HSE / 25 = 1M

VCOCLK_OUT = VCOCLK_IN * N = 1M * 360 = 360M

PLLCLK_OUT=VCOCLK_OUT/P=360/2=180M

USBCLK = VCOCLK_OUT/Q=360/7=51.7。暂时这样配置,到真正使用USB的时候会重新配置。

3.    ③系统时钟SYSCLK

系统时钟来源可以是:HSI、PLLCLK、HSE,具体的由时钟配置寄存器RCC_CFGR的SW位配置。我们这里设置系统时钟:SYSCLK = PLLCLK = 180M。如果系统时钟是由HSE经过PLL倍频之后的PLLCLK得到,当HSE出现故障的时候,系统时钟会切换为HSI=16M,直到HSE恢复正常为止。

4.    ④AHB总线时钟HCLK

系统时钟SYSCLK经过AHB预分频器分频之后得到时钟叫APB总线时钟,即HCLK,分频因子可以是:[1,2,4,8,16,64,128,256,512],具体的由时钟配置寄存器RCC_CFGR的HPRE设置。片上大部分外设的时钟都是经过HCLK分频得到,至于AHB总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好APB的时钟即可。我们这里设置为1分频,即HCLK=SYSCLK=180M。功能框图中的最高168M指的是F407F429最高应该是180M,是官方中文翻译文档的一个疏忽。

5.    ⑤APB2总线时钟HCLK2

APB2总线时钟PCLK2由HCLK经过高速APB2预分频器得到,分频因子可以是:[1,2,4,8,16],具体由时钟配置寄存器RCC_CFGR的PPRE2位设置。HCLK2属于高速的总线时钟,片上高速的外设就挂载到这条总线上,比如全部的GPIO、USART1、SPI1等。至于APB2总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好APB2的时钟即可。我们这里设置为2分频,即PCLK2 = HCLK /2= 90M。

6.    ⑥APB1总线时钟HCLK1

APB1总线时钟PCLK1由HCLK经过低速APB预分频器得到,分频因子可以是:[1,2,4,8,16],具体由时钟配置寄存器RCC_CFGR的PPRE1位设置。
HCLK1属于低速的总线时钟,最高为45M,片上低速的外设就挂载到这条总线上,比如USART2/3/4/5、SPI2/3,I2C1/2等。至于APB1总线上的外设的时钟设置为多少,得等到我们使用该外设的时候才设置,我们这里只需粗线条的设置好APB1的时钟即可。我们这里设置为4分频,即PCLK1 = HCLK/4 = 45M。

7.    设置系统时钟库函数

上面的6个步骤对应的设置系统时钟库函数如下,为了方便阅读,已经把跟429不相关的代码删掉,把英文注释翻译成了中文,并把代码标上了序号,总共6个步骤。该函数是直接操作寄存器的,有关寄存器部分请参考数据手册的RCC的寄存器描述部分。

代码 13 设置系统时钟库函数

 1 /*
				
 2  * 使用HSE时,设置系统时钟的步骤
				
 3  * 1、开启HSE ,并等待 HSE 稳定
				
 4  * 2、设置 AHBAPB2APB1的预分频因子
				
 5  * 3、设置PLL的时钟来源
				
 6  *    设置VCO输入时钟分频因子        m
				
 7  *    设置VCO输出时钟倍频因子        n
				
 8  *    设置PLLCLK时钟分频因子          p
				
 9  *    设置OTG FS,SDIO,RNG时钟分频因子 q
				
10  * 4、开启PLL,并等待PLL稳定
				
11  * 5、把PLLCK切换为系统时钟SYSCLK
				
12  * 6、读取时钟切换状态位,确保PLLCLK被选为系统时钟
				
13  */
				
14 
			
15 #define PLL_M 25
				
16 #define PLL_N 360
				
17 #define PLL_P 2
				
18 #define PLL_Q 7
					

如果要超频的话,修改PLL_N这个宏即可,取值范围为:192~432。

1 void SetSysClock(void)

 2 {
     
     
				
 3 
			
 4     __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
				
 5 
			
 6 
								// ①使能HSE
				
 7     RCC->CR |= ((uint32_t)RCC_CR_HSEON);
				
 8 
			
 9 
								// 等待HSE启动稳定
				
10 
							do { 
       
				
11         HSEStatus = RCC->CR & RCC_CR_HSERDY;
				
12         StartUpCounter++;
				
13     } while ((HSEStatus==0)&&(StartUpCounter
				
14                               !=HSE_STARTUP_TIMEOUT));
				
15 
			
16 
							if ((RCC->CR & RCC_CR_HSERDY) != RESET) { 
       
				
17         HSEStatus = (uint32_t)0x01;
				
18     } else { 
       
				
19         HSEStatus = (uint32_t)0x00;
				
20     }
				
21 
			
22 
							// HSE 启动成功
			
23 
							if (HSEStatus == (uint32_t)0x01) { 
         
				
24 
								// 调压器电压输出级别配置为1,以便在器件为最大频率
				
25 
							// 工作时使性能和功耗实现平衡
			
26         RCC->APB1ENR |= RCC_APB1ENR_PWREN;
				
27         PWR->CR |= PWR_CR_VOS;
				
28 
			
29 
								// ②设置AHB/APB2/APB1的分频因子
				
30 
							// HCLK = SYSCLK / 1
				
31         RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
				
32 
							// PCLK2 = HCLK / 2
				
33         RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
				
34 
							// PCLK1 = HCLK / 4
				
35         RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
				
36 
			
37 
								// ③配置主PLL
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值