历史上的今天
返回首页

历史上的今天

今天是:2025年08月12日(星期二)

正在发生

2019年08月12日 | STM32-(26):RCC内部结构与原理分析

2019-08-12 来源:eefocus

RCC(Reset Clock Controller)复位与时钟控制器

这个在STM32中起到一个举足轻重的作用,所有的外设都由时钟来控制。通过控制时钟的开关、速度来控制外设的开关、运行速度来控制整体功耗。特别是对手持式设备、利用电池供电的设备都对功耗要求比较高。

一、时钟系统与内部结构

在这里插入图片描述
四个驱动单元
Cortex-M3内核ICode(地址)总线(I-bus).DCode(数据)总线(D-bus).和系统总线(S-bus)
GP-DMA(通用DMA)

三个被动单元
内部SRAM
内部闪存存储器
AHB到APB的桥(AHB2APBx),它连接所有的APB设备,APB2的时钟比APB1快。

在这里插入图片描述
简析: 首先,输入 OSC_OUT/OSC_IN,这是一路晶振,OSC32_IN/OSC32_OUT,第二路晶振,我们先看上面这一路,上面这一路是外部时钟(HSE OSC),外部时钟进来,也可先除以2(二分频)进来,进来之后又是一个选择开关,这个选择开关还有一路,HSI RC(内部时钟RC振荡器),内部时钟也可以直接进入后方,可以看到内部时钟是8Mhz,不管是内部时钟还是外部时钟,往后进入 PLL (锁相环),锁相环起一个倍频器的作用,输出一个倍频之后的 PLLCLK,又遇到一个选择开关,这个选择开关还有一路输入 ,HSE OSC(外部晶振)直接过来的,所以一共有三个时钟,可以通过设置选择某一路过来,过来之后得到一个SYSCLK(系统时钟),系统时钟往后可以为 AHB总线提供时钟源,AHB Prescaler 是一个预分频器,再往后分三路,第一路跑到 CPU 内核(内核用,72Mhz);第二路走到 APB1,提供给 APB1 控制的这些外设(最高36Mhz),如果这里还要用到通用定时器,这里还有一个 Multiplier(乘法器),目的是使定时器的时钟更快;第三路到 APB2,类似于 APB1,最高速度快一些,另外还有一个 ADC,由于ADC不需要太快的速度,所以还需要经过分频(ADC Prescaler);PLL 有一路没有走后方,直接下来供给 USB 外设使用,频率为48MHz(这个频率比较特殊,所以单独拉出来一路)

另外一路:OSC32_IN/OSC32_OUT,接的是外部 32.768KHz的晶振,简写成OSC32,为什么是32.768KHz ? 因为这个频率可以产生精确的秒信号(暂不深究)。这个晶振信号进来,经过 LSE OSC (外部低速时钟),进来一个32.768KHz的波,另外下方有一个低速的内部RC振荡器,大概40KHz,同时都进入后方的选择开关,这个选择开关的第三路输入是由上方提供的,三路输入,经选择开关选择,提供RTC时钟(实时时钟),当32.768这一路失效,可以选择另外两路,也能提供相对精确的时钟。

时钟监视系统 CSS:监视 HSE OSC 时钟,这个外部时钟会提供给 CPU 使用,当检测到HSE OSC 失效,则立即切换至 HSI RC

MCO接口:芯片上有一个专门的引脚叫MCO,可以通过选择开关来选择,可以通过示波器测量 SYSCLK、HSI、HSE、PLLCLK各个波形,根据脉冲波形来判断时钟是否正常。除此之外,也可以通过这个接口给其他器件充当晶振。即既能作为内部诊断,也能为外部提供晶振,并且提供晶振的时候还有多种选择。

为什么要这么多时钟?内部时钟?外部时钟?
有内部高速(HSI RC)、外部高速(HSE DSC)、外部低速(LSE DSC)、内部低速(LSI RC),首先高速、低速满足的外设是不一样的,比如低速满足 RTC 时钟和看门狗,至于外部内部,是当外部失效的时候也可以使用内部的振荡器,可以工作,只不过接了外部的晶振,时钟更加精确而已

时钟源

时钟是STM32的脉搏,是驱动源。使用任何一个外设都必须打开相应的时钟。这样的好处就是,如果不使用一个外设的时候,就把它的时钟关掉,从而可以降低系统的功耗,达到节能,实现低功耗的效果。

STM32的时钟可以由以下4个时钟源提供:
1、 HSI:高速内部时钟信号stm32单片机内带的时钟(8M频率)精度较差
2、 HSE:高速外部时钟信号精度高来源(1)HSE外部晶体/陶瓷谐振器(晶振)(2)HSE用户外部时钟
3、 LSE:低速外部晶体32.768kHz主要提供一个精确的时钟源一般作为RTC时钟使用
4、 LSI:低速内部时钟,主要提供给看门狗

stm32将时钟信号(例如HSE)经过分频或倍频(PLL)后,得到系统时钟,系统时钟经过分频,产生外设所使用的时钟。

RCC 程序流程

设罝时钟流程:
1、 将RCC寄存器重新设罝为默认值 RCC_Delnit
2、 打开夕卜部高速时钟晶振HSE RCC_HSEConfig(RCC_HSE_ON);
3、 等待外部髙速时钟晶振工作 HSEStartUpStatus = RCC_WaitForHSEStartUp();
4、 设置AHB时钟 RCC_HCLKConfig;
5、 设罝高速APB时钟 RCC_PCLK2Config;
6、 设置低速速APB时钟 RCC_PCLK1Config
7、 设置PLL RCC_PLLConfig
8、 打开PLL RCC_PLLCmd(ENABLE);
9、 等待PLL工作 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) = RESET)
10、设置系统时钟 RCC_SYSCLKConfig
11、判断是否PLL是系统时钟 while[RCC_GetSYSCLKSource() != 0x08)
12、打开要使用的外设时钟 RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd ()

代码

RCC_Configuration

void RCC_Configuration(void) 

{

//=============================== 使用内部RC晶振 ===================================

    /*   

RCC_HSICmd(ENABLE);//使能内部高速晶振 ;

  RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);//选择内部高速时钟作为系统时钟SYSCLOCK=8MHZ

RCC_HCLKConfig(RCC_SYSCLK_Div1);//选择HCLK时钟源为系统时钟SYYSCLOCK

  RCC_PCLK1Config(RCC_HCLK_Div4);//APB1时钟为2M 

  RCC_PCLK2Config(RCC_HCLK_Div4);//APB2时钟为2M

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);//使能APB2外设GPIOB时钟

*/


//==========================使用外部RC晶振========================================

  RCC_DeInit(); //初始化为缺省状态

  RCC_HSEConfig(RCC_HSE_ON);  //高速时钟使能

  while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);  //等待高速时钟使能就绪


    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer 

    FLASH_SetLatency(FLASH_Latency_2);   // Flash 2 wait state 

    RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK 

    RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK 

    RCC_PCLK1Config(RCC_HCLK_Div2);   // PCLK1 = HCLK/2 

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // PLLCLK = 8MHz * 9 = 72 MHz  

    RCC_PLLCmd(ENABLE);   // Enable PLL 

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); // Wait till PLL is ready 


    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);   // Select PLL as system clock source 

    while(RCC_GetSYSCLKSource() != 0x08); // Wait till PLL is used as system clock source 


//====================================================================================

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能APB2外设GPIOC时钟

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); // Enable TIM2, TIM3 and TIM4 clocks ,可删掉

}


//以下具体函数的设置是参照寄存器手册配置的


/*******************************************************************************

* Function Name  : RCC_DeInit

* Description    : Resets the RCC clock configuration to the default reset state.

* Input          : None

* Output         : None

* Return         : None

* 功能           : 将外设RCC寄存器重设为缺省值 ;

*******************************************************************************/

void RCC_DeInit(void)

{

  /* Set HSION bit */

  RCC->CR |= (u32)0x00000001;


  /* Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], ADCPRE[1:0] and MCO[2:0] bits */

  RCC->CFGR &= (u32)0xF8FF0000;

  

  /* Reset HSEON, CSSON and PLLON bits */

  RCC->CR &= (u32)0xFEF6FFFF;


  /* Reset HSEBYP bit */

  RCC->CR &= (u32)0xFFFBFFFF;


  /* Reset PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE bits */

  RCC->CFGR &= (u32)0xFF80FFFF;


  /* Disable all interrupts */

  RCC->CIR = 0x00000000;

}


/*******************************************************************************

* Function Name  : RCC_HSEConfig

* Description    : Configures the External High Speed oscillator (HSE).

*                  HSE can not be stopped if it is used directly or through the 

*                  PLL as system clock.

* Input          : - RCC_HSE: specifies the new state of the HSE.

*                    This parameter can be one of the following values:

*                       - RCC_HSE_OFF: HSE oscillator OFF

*                       - RCC_HSE_ON: HSE oscillator ON

*                       - RCC_HSE_Bypass: HSE oscillator bypassed with external

*                         clock

* Output         : None

* Return         : None

* 功能           : 设置外设高速晶振(HSE)

*******************************************************************************/

void RCC_HSEConfig(u32 RCC_HSE)

{

  /* Check the parameters */

  assert_param(IS_RCC_HSE(RCC_HSE));


  /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/

  /* Reset HSEON bit */

  RCC->CR &= CR_HSEON_Reset;


  /* Reset HSEBYP bit */

  RCC->CR &= CR_HSEBYP_Reset;


  /* Configure HSE (RCC_HSE_OFF is already covered by the code section above) */

  switch(RCC_HSE)

  {

    case RCC_HSE_ON:

      /* Set HSEON bit */

      RCC->CR |= CR_HSEON_Set;

      break;

      

    case RCC_HSE_Bypass:

      /* Set HSEBYP and HSEON bits */

      RCC->CR |= CR_HSEBYP_Set | CR_HSEON_Set;

      break;            

      

    default:

      break;      

  }

}


/*******************************************************************************

* Function Name  : RCC_GetFlagStatus

* Description    : Checks whether the specified RCC flag is set or not.

* Input          : - RCC_FLAG: specifies the flag to check.

*                    This parameter can be one of the following values:

*                       - RCC_FLAG_HSIRDY: HSI oscillator clock ready

*                       - RCC_FLAG_HSERDY: HSE oscillator clock ready

*                       - RCC_FLAG_PLLRDY: PLL clock ready

*                       - RCC_FLAG_LSERDY: LSE oscillator clock ready

*                       - RCC_FLAG_LSIRDY: LSI oscillator clock ready

*                       - RCC_FLAG_PINRST: Pin reset

*                       - RCC_FLAG_PORRST: POR/PDR reset

*                       - RCC_FLAG_SFTRST: Software reset

*                       - RCC_FLAG_IWDGRST: Independent Watchdog reset

*                       - RCC_FLAG_WWDGRST: Window Watchdog reset

*                       - RCC_FLAG_LPWRRST: Low Power reset

* Output         : None

* Return         : The new state of RCC_FLAG (SET or RESET).

* 功能           : 检查指定的RCC标志位设置与否 ;

*******************************************************************************/

FlagStatus RCC_GetFlagStatus(u8 RCC_FLAG)

{

  u32 tmp = 0;

  u32 statusreg = 0;

  FlagStatus bitstatus = RESET;


  /* Check the parameters */

  assert_param(IS_RCC_FLAG(RCC_FLAG));


  /* Get the RCC register index */

  tmp = RCC_FLAG >> 5;


  if (tmp == 1)               /* The flag to check is in CR register */

推荐阅读

史海拾趣

国芯佳品公司的发展小趣事

机顶盒,全称为数字视频变换盒,是现代家庭娱乐中不可或缺的重要设备。它作为连接电视机与外部信号源的桥梁,不仅承担着接收数字电视信号并将其转换为适合电视播放格式的基本任务,还通过技术的不断演进,极大丰富了用户的视听体验。

从专业角度来看,机顶盒经历了从模拟到数字的飞跃,涵盖了多种类型,如DVB-S(数字卫星机顶盒)、DVB-C(有线电视数字机顶盒)、IPTV机顶盒等。这些机顶盒通过不同的传输介质(如有线电缆、卫星天线、宽带网络)接收信号,并借助内部高效的解码器,将数字信号转换成高质量的音视频流,实现了高清乃至4K超高清的播放效果。

在科普层面,机顶盒的普及极大地推动了家庭娱乐的多元化。它不仅让用户能够收看更多样化的电视节目,还能通过连接互联网,提供电子节目指南、在线视频、网页浏览、社交媒体互动等增值服务。此外,一些先进的机顶盒还集成了智能语音助手、家庭影院功能,甚至支持存储个人媒体文件,让用户的娱乐体验更加个性化、便捷化。

随着5G、云计算、人工智能等技术的不断发展,机顶盒正朝着更高清、更智能、更互动的方向迈进。它不仅将继续作为电视内容的接收和展示终端,更将成为智能家居生态系统中的重要一环,为用户带来更加丰富、沉浸的娱乐享受。

Eurofarad公司的发展小趣事

Eurofarad始终将品质管理作为公司发展的重要保障。公司建立了完善的质量管理体系,从原材料采购到生产、检测、包装等各个环节都进行严格的质量控制。同时,Eurofarad还注重持续改进,不断优化生产流程和提高生产效率,确保产品的品质和性能始终保持在行业领先水平。

德崧电子(D-SWITCH)公司的发展小趣事

在电子开关行业,防水性能一直是重要的技术指标。德崧电子(D-SWITCH)公司在成立初期就意识到了这一点,并投入大量资源进行研发。经过数年的努力,公司成功研发出了具有TUV IP67/IP68防水等级认证的防水型开关。这一突破性的技术不仅解决了市场上防水开关性能不稳定的问题,还大大提高了产品的可靠性和使用寿命。凭借这一技术优势,德崧电子在市场上迅速崭露头角,赢得了客户的广泛认可。

Hirosugi-Keiki公司的发展小趣事

在电子开关行业,防水性能一直是重要的技术指标。德崧电子(D-SWITCH)公司在成立初期就意识到了这一点,并投入大量资源进行研发。经过数年的努力,公司成功研发出了具有TUV IP67/IP68防水等级认证的防水型开关。这一突破性的技术不仅解决了市场上防水开关性能不稳定的问题,还大大提高了产品的可靠性和使用寿命。凭借这一技术优势,德崧电子在市场上迅速崭露头角,赢得了客户的广泛认可。

艾华集团(AISHI)公司的发展小趣事

1985年,艾立华和王安安怀揣着3700元的全部家当,毅然决然地踏上了创业之路。他们租下了两间不到50平方米的废弃小平房,与几名工人一起,手工制作铝电解电容器。由于资金、技术和市场的限制,艾华集团最初只能接一些其他企业不愿意做的、用量很少但又刚需的项目。然而,即便是在这样的困境中,艾立华和王安安也始终坚持对产品品质的精益求精,他们深知,只有高品质的产品才能在市场上立足。

Electronicon Kondensatoren GmbH公司的发展小趣事

ELECTRONICON Kondensatoren GmbH,其前身为RFT Kondensatorenwerk Gera,于20世纪30年代末与德国图林根东部的Gera的电容器制造商建立了紧密的合作。自此,ELECTRONICON开始崭露头角,专注于电容器技术的研发与生产。公司始终将产品的质量和可靠性作为核心理念,为未来的发展奠定了坚实的基础。

问答坊 | AI 解惑

2006年 四川省大学生电子设计竞赛试题-12V-220V逆变电源

本帖最后由 paulhyde 于 2014-9-15 04:25 编辑 电子设计竞赛试题-12V/220V逆变电源 一、电子设计竞赛试题设计任务 设计并制作一12V/220V逆变电源 二、电子设计竞赛试题设计要求 1、基本要求 (1)输入12V直流(汽车蓄电池提供) (2) ...…

查看全部问答>

电脑族每分钟需眨眼15次 屏幕成视力杀手 ZT

长时间盯着电脑的朋友们,小心保护眼睛啊! 当电脑改变着我们生活的同时,许多人的视力在显示器面前也在悄悄地发生着变化。电脑伤眼已经是一个不争的事实。据美国全国职业保健与安全研究所的一项调查证明,每天在电脑前工作3小时以上的人中,有90% ...…

查看全部问答>

成都华为高薪寻求软件和硬件工程师

1) 软件工程师(高级工程师) 工作职责 1、从事网络设备的底层软件、主机软件、业务软件、网管软件等研发工作; 2、负责软件项目、模块的需求分析、设计、编码实现、验证; 3、参与相关质量活动,确保软件设计及实现工作按时保质完成。 ...…

查看全部问答>

usb通讯干扰

我通过USB实现电机控制器与PC机的通信,电机控制器启动电机转动后,usb通讯就中断,重新插拔有时候能连接上,但是马上就又断,有时候计算机上显示,无法识别设备。而电机不转的时候,通讯正常。其中,电机控制器采用4层板,电机控制器主芯片为ARM, ...…

查看全部问答>

Verilog能编写UDP的测试程序么?

Verilog能编写UDP的测试程序么?如果可以,请问开头结尾怎么写,谢谢!…

查看全部问答>

TI LM3S811板卡和USB仿真器图纸

LM3S811板卡图纸和M3的USB仿真器图纸   Protel格式,唯一需要注意的是绝对不要使用下面和JTAG复用的引脚,否则会锁死811。   GPIO管脚  对应的JTAG接口     PB7         ...…

查看全部问答>

各位大侠:如何通过430编程把数据包往电脑上发送?(用网线而不是串口)

问题补充:总的结构为:430单片机(F5438)——>ENC28J60(以太网控制芯片)——>网口——>电脑(用来测试传输速度)。谢谢了…

查看全部问答>

修改12864串口驱动程序

主函数main.c #include <msp430g2553.h> #include\"LCD12864P.h\" void main() { WDTCTL = WDTPW + WDTHOLD; Ini_Lcd(); lcd_pos(1,0); Disp_HZ(\"液晶12864\",5); lcd_pos(3,4); ...…

查看全部问答>

GamePop推出“永久免费”GamePop迷你,卖游戏送游戏机

有史以来第一款免费游戏机,只需购买GamePop的服务,即可在多种设备上运行 移动公司BlueStacks宣布免费提供其GamePop移动游戏服务的游戏机——GamePop迷你。新设备将运行果冻豆4.2,通过HDMI电缆连接到电视,包括500款挑选出来的流行移动游戏。 ...…

查看全部问答>