历史上的今天
返回首页

历史上的今天

今天是:2025年02月25日(星期二)

正在发生

2020年02月25日 | 第15章 RCC—使用HSE/HSI配置时钟—零死角玩转STM32-F429系列

2020-02-25 来源:eefocus

本章参考资料:《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 = 90M,PCLK1=HCLK/4 = 45M。这个时钟配置也是库函数的标准配置,我们用的最多的就是这个。


1.2 RCC框图剖析—时钟树

时钟树单纯讲理论的话会比较枯燥,如果选取一条主线,并辅以代码,先主后次讲解的话会很容易,而且记忆还更深刻。我们这里选取库函数时钟系统时钟函数:SetSysClock(); 以这个函数的编写流程来讲解时钟树,这个函数也是我们用库的时候默认的系统时钟设置函数。该函数的功能是利用HSE把时钟设置为:HCLK = SYSCLK=PLLCLK = 180M,PCLK1=HCLK/2 = 90M,PCLK1=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指的是F407,F429最高应该是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、设置 AHB、APB2、APB1的预分频因子

 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的时钟来源,设置M,N,P,Q

38 

// Configure the main PLL

39         RCC->PLLCFGR = PLL_M|(PLL_N<<6)|

40                        (((PLL_P >> 1) -1) << 16) |

41                        (RCC_PLLCFGR_PLLSRC_HSE) |

42                        (PLL_Q << 24);

43 

44 

// ④使能主PLL

45         RCC->CR |= RCC_CR_PLLON;

46 

47 

// 等待PLL稳定

48 

while ((RCC->CR & RCC_CR_PLLRDY) == 0) {

49         }

50 

/*----------------------------------------------------*/

51 

// 开启 OVER-RIDE模式,以能达到更改频率

52         PWR->CR |= PWR_CR_ODEN;

53 

while ((PWR->CSR & PWR_CSR_ODRDY) == 0) {

54         }

55         PWR->CR |= PWR_CR_ODSWEN;

56 

while ((PWR->CSR & PWR_CSR_ODSWRDY) == 0) {

57         }

58 

// 配置FLASH预取指,指令缓存,数据缓存和等待状态

59         FLASH->ACR = FLASH_ACR_PRFTEN

60                      |FLASH_ACR_ICEN

61                      |FLASH_ACR_DCEN

62                      |FLASH_ACR_LATENCY_5WS;

63 

/*---------------------------------------------------*/

64 

65 

// ⑤选择主PLLCLK作为系统时钟源

66         RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

67         RCC->CFGR |= RCC_CFGR_SW_PLL;

68 

69 

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

70 

while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS )

71                != RCC_CFGR_SWS_PLL);

72         {

73         }

74     } else {

75 

// HSE 启动出错处理

76     }

77 }

1.2.2 其他时钟

通过对系统时钟设置的讲解,整个时钟树我们已经把握的有六七成,剩下的时钟部分我们讲解几个重要的。


1.A、RTC时钟

RTCCLK 时钟源可以是 HSE 1 MHz( HSE 由一个可编程的预分频器分频)、 LSE 或者 LSI时钟。选择方式是编程 RCC 备份域控制寄存器 (RCC_BDCR) 中的 RTCSEL[1:0] 位和 RCC时钟配置寄存器 (RCC_CFGR) 中的 RTCPRE[4:0] 位。所做的选择只能通过复位备份域的方式修改。我们通常的做法是由LSE给RTC提供时钟,大小为32.768KHZ。LSE由外接的晶体谐振器产生,所配的谐振电容精度要求高,不然很容易不起震。


2.B、独立看门狗时钟

独立看门狗时钟由内部的低速时钟LSI提供,大小为32KHZ。


3.C、I2S时钟

I2S时钟可由外部的时钟引脚I2S_CKIN输入,也可由专用的PLLI2SCLK提供,具体的由RCC 时钟配置寄存器 (RCC_CFGR)的I2SSCR位配置。我们在使用I2S外设驱动W8978的时候,使用的时钟是PLLI2SCLK,这样就可以省掉一个有源晶振。


4.D、PHY以太网时钟

F429要想实现以太网功能,除了有本身内置的MAC之外,还需要外接一个PHY芯片,常见的PHY芯片有DP83848和LAN8720,其中DP83848支持MII和RMII接口,LAN8720只支持RMII接口。秉火F429开发板用的是RMII接口,选择的PHY芯片是LAB8720。使用RMII接口的好处是使用的IO减少了一半,速度还是跟MII接口一样。当使用RMII接口时,PHY芯片只需输出一路时钟给MCU即可,如果是MII接口,PHY芯片则需要提供两路时钟给MCU。


5.E、USB PHY 时钟

F429的USB没有集成PHY,要想实现USB高速传输的话,必须外置USB PHY芯片,常用的芯片是USB3300。当外接USB PHY芯片时,PHY芯片需要给MCU提供一个时钟。


外扩USB3300会占用非常多的IO,跟SDRAM和RGB888的IO会复用的很厉害,鉴于USB高速传输用的比较少,秉火429就没有外扩这个芯片。


6.F、MCO时钟输出

MCO是microcontroller clock output的缩写,是微控制器时钟输出引脚,主要作用是可以对外提供时钟,相当于一个有源晶振。F429中有两个MCO,由PA8/PC9复用所得。MCO1所需的时钟源通过 RCC 时钟配置寄存器 (RCC_CFGR) 中的 MCO1PRE[2:0] 和 MCO1[1:0]位选择。MCO2所需的时钟源通过 RCC 时钟配置寄存器 (RCC_CFGR) 中的 MCO2PRE[2:0] 和 MCO2位选择。有关MCO的IO、时钟选择和输出速率的具体信息如下表所示:

image.png?imageView2/2/w/550

1.3 配置系统时钟实验

1.3.1 使用HSE

一般情况下,我们都是使用HSE,然后HSE经过PLL倍频之后作为系统时钟。F429系统时钟最高为180M,这个是官方推荐的最高的稳定时钟,如果你想铤而走险,也可以超频,超频最高能到216M。


如果我们使用库函数编程,当程序来到main函数之前,启动文件:startup_stm32f429_439xx.s已经调用SystemInit()函数把系统时钟初始化成180MHZ,SystemInit()在库文件:system_stm32f4xx.c中定义。如果我们想把系统时钟设置低一点或者超频的话,可以修改底层的库文件,但是为了维持库的完整性,我们可以根据时钟树的流程自行写一个。


1.3.2 使用HSI

当HSE直接或者间接(HSE经过PLL倍频)的作为系统时钟的时候,如果HSE发生故障,不仅HSE会被关闭,连PLL也会被关闭,这个时候系统会自动切换HSI作为系统时钟,此时SYSCLK=HSI=16M,如果没有开启CSS和CSS中断的话,那么整个系统就只能在低速率运行,这是系统跟瘫痪没什么两样。


如果开启了CSS功能的话,那么可以当HSE故障时,在CSS中断里面采取补救措施,使用HSI,重新设置系统频率为180M,让系统恢复正常使用。但这只是权宜之计,并非万全之策,最好的方法还是要采取相应的补救措施并报警,然后修复HSE。临时使用HSI只是为了把损失降低到最小,毕竟HSI较于HSE精度还是要低点。


F103系列中,使用HSI最大只能把系统设置为64M,并不能跟使用HSE一样把系统时钟设置为72M,究其原因是HSI在进入PLL倍频的时候必须2分频,导致PLL倍频因子调到最大也只能到64M,而HSE进入PLL倍频的时候则不用2分频。


在F429中,无论是使用HSI还是HSE都可以把系统时钟设置为180M,因为HSE或者HSI在进入PLL倍频的时候都会被分频为1M之后再倍频。


还有一种情况是,有些用户不想用HSE,想用HSI,但是又不知道怎么用HSI来设置系统时钟,因为调用库函数都是使用HSE,下面我们给出个使用HSI配置系统时钟例子,起个抛砖引玉的作用。


1.3.3 硬件设计

1、RCC


2、LED一个


RCC是单片机内部资源,不需要外部电路。通过LED闪烁的频率来直观的判断不同系统时钟频率对软件延时的效果。


1.3.4 软件设计

我们编写两个RCC驱动文件,bsp_clkconfig.h和bsp_clkconfig.c,用来存放RCC系统时钟配置函数。

推荐阅读

史海拾趣

amcc [applied micro circuits corp]公司的发展小趣事

Applied Micro Circuits Corp(AMCC)是一家半导体公司,主要从事高性能处理器和高速互连解决方案的设计和制造。以下是关于AMCC公司发展的五个相关故事:

  1. 公司成立与早期发展:AMCC公司于1979年由Hemant Kanakia等人在美国加利福尼亚州的圣塔克拉拉创立。公司最初专注于设计和制造用于通信和数据中心应用的集成电路芯片。在成立初期,AMCC致力于开发高性能、低功耗的处理器和互连解决方案,以满足不断增长的通信市场需求。

  2. 技术创新与产品发布:AMCC公司在技术创新方面处于行业领先地位。公司持续投入研发,并推出了一系列创新产品。1997年,AMCC发布了第一款64位PowerPC处理器,开创了其在高性能处理器市场的先河。随后,公司不断推出新一代的处理器产品,包括PowerPC、ARM等系列,以满足不同客户的需求。

  3. 业务拓展与市场扩张:随着时间的推移,AMCC不断拓展其业务范围和市场覆盖。公司不仅在通信领域取得了成功,还逐渐进军数据中心、云计算、存储等新兴领域。AMCC通过与各大客户和合作伙伴的紧密合作,扩大了产品的市场份额和影响力。

  4. 收购与整合:AMCC通过一系列收购和整合,加强了自身的技术实力和市场竞争力。公司收购了一些在特定领域具有核心技术的公司,如Tahoe Networks(2004年)、3ware(2005年)、Mindspeed Technologies(2014年)等。这些收购使得AMCC得以快速扩大产品线,并加速了公司在新兴市场的布局。

  5. 英特尔收购:2016年,英特尔公司宣布以约17亿美元的价格收购AMCC。这一交易使得AMCC成为英特尔旗下的子公司,英特尔得以借助AMCC在通信和数据中心领域的技术优势和客户资源,进一步拓展其在半导体行业的地位。此次收购也标志着AMCC作为独立实体的终结,但其在半导体行业的技术贡献和市场影响将持续延续。

这些故事展示了AMCC公司在技术创新、产品发布、业务拓展、收购整合等方面的发展历程,以及其作为半导体行业重要参与者的地位和影响力。

台湾第一电阻(Firstohm)公司的发展小趣事
电冰箱不制冷可能由多种原因引起,包括电源问题、温度设置不当、制冷系统故障等。首先,检查电源插头是否牢固插入插座,并确保插座有电。其次,检查温度设置是否正确,冷藏室温度一般应设置在2-4摄氏度,冷冻室温度应设置在-18摄氏度左右。如果以上均正常,可能是制冷系统出现故障,如压缩机故障、制冷剂泄漏等,需要请专业人员进行检查和维修。
DB Unlimited公司的发展小趣事

DB Unlimited始终将客户放在心中最重要的位置。公司坚持以客户为中心的服务理念,为客户提供全方位、高品质的服务。无论是售前咨询、售后服务还是技术支持等方面,DB Unlimited都始终秉持着专业、高效、热情的态度,赢得了客户的广泛赞誉和信赖。这种客户至上的服务理念也成为了公司不断发展壮大的重要保障之一。

请注意,以上故事框架仅供参考,实际的故事需要根据DB Unlimited公司的真实发展历程和具体事实进行编写。

振华(CEC)公司的发展小趣事

中国振华电子集团有限公司(简称振华)自成立之初,就致力于电子产品的研发与生产。初期,公司面临着技术落后、资金短缺等诸多困难,但创始人及团队凭借坚定的信念和不懈的努力,成功开发出了一系列具有市场竞争力的电子产品。随着产品质量的提升和市场份额的扩大,振华逐渐在电子行业中崭露头角。

Hi-Light Electronic Co Ltd公司的发展小趣事

中国振华电子集团有限公司(简称振华)自成立之初,就致力于电子产品的研发与生产。初期,公司面临着技术落后、资金短缺等诸多困难,但创始人及团队凭借坚定的信念和不懈的努力,成功开发出了一系列具有市场竞争力的电子产品。随着产品质量的提升和市场份额的扩大,振华逐渐在电子行业中崭露头角。

Ava Electronics Corp公司的发展小趣事

AVA电子的创始人凭借对市场的敏锐洞察和对技术的深刻理解,于2004年决定成立这家以IT产品为主的新兴高科技企业。当时,中国的电子行业正迎来一轮发展高潮,而流媒体技术、网络控制技术和多媒体音视频切换及传输技术则被认为是未来行业发展的关键。然而,创业初期,公司面临着资金短缺、人才匮乏以及市场竞争激烈等多重挑战。创始人带领团队,通过不断研发创新产品,积极拓展市场,逐渐在行业中站稳脚跟。

问答坊 | AI 解惑

430初学入门资料总结

刚开始学习MSP430开发。搜集了点有用的资料和大家分享。希望在后续的开发中能不断完善…

查看全部问答>

铁电的时序是不是需要模拟?

本信息来自合作QQ群:AVR单片机学习与交流群(17727270) 群管理员在坛子里的ID:铜河 ATMEL的扩展FLASH好象可以直接直接访问…

查看全部问答>

在tf卡上CeMountDBVol为什么会出错?

{                         CeMountDBVol(&g_guidDB, szPath, …

查看全部问答>

请问哪位大大有TMS320F2812的SCI初始化代码啊?

老师要我写一个SCI的初始化代码,我看了这个芯片的文档后,还是感觉云里雾里的,后天就要交了,着急死了。。。 一直弄不明白TXWAKE、WUT这两个信号到底是干嘛用的。。。求牛人解救啊。。。…

查看全部问答>

JTAG烧程序

小弟刚刚开始接触MSP430,请问斑主MSP-FET430P140可否对MSP430F149通过JTAG口直接烧程序进去,谢谢。…

查看全部问答>

交换开发板

我现在想用lm3s8962或者TMS320F交换lpc2000系列开发板。 联系方式:kxs002@163.com QQ:81960697…

查看全部问答>

求一篇dcdc直流开关电源的设计论文

具体要求 1、 开关电源与线性电源进行对比,总结开关电源的优点。 2、 在对开关电源的整体结构进行了介绍的基础上,对开关电源的主回路和控制回路进行设计:在主回路中整流电路采用单相桥式、功率转换电路采用单端正激功率转换电路、采用增加副边 ...…

查看全部问答>

LPC1114如何加密

rt, 我使用LPCxpresso 编译器。 #define NO_CRP          0xFFFFFFFF #define NO_ISP_MAGIC    0x4E697370 #define CRP1_MAGIC      0x12345678 #define CRP2_MAGIC    ...…

查看全部问答>

rm48的CAN通信

用RM48的芯片做的板子搞测试,板子间采用CAN通信,但是在接收端能接收到msg的ID,但是msg的内容却无法接收。这是怎么回事?…

查看全部问答>

68013的开发板成本价出售

本帖最后由 wu2345 于 2014-3-4 12:03 编辑 68013的开发板成本价出售。板上把68013的IO都引出来了,方便使用。 价格68013(20)+板子(10)+TLV1117(1)+方口usb(1)+晶振、按键和其他阻容、贴装费(共8)。要eeprom的根据容量适当收取费用,保 ...…

查看全部问答>