STM32F10x之RCC

1 综述

1.1 时钟源

在STM32中,一共有5个时钟源,分别是HSI、HSE、LSI、LSE、PLL。

  • HSI:高速内部时钟源,RC振荡器,频率为8MHz。
  • HSE:高速外部时钟源,可接石英/陶瓷谐振器或外部时钟,频率范围为4~16MHz。
  • LSI:低速内部时钟源,RC振荡器,频率为40KHz。
  • LSE:低速外部时钟源,接频率为32.768KHz的石英晶体。
  • PLL:锁相环倍频输出,严格来说它不是独立时钟源,需要外接时钟源,输入可接HSI/2,HSE或是HSE/2。PLL倍频范围为x2~x16,但最大输出频率不能超过72MHz。

其中,LSI供独立看门狗IWDG使用,也可以被选为实时时钟源,不过,实时时钟源还可以选择LSE或者是HSE的128分配。在STM32中,全速功能的USB模块,其串行接口引擎需要一个48MHz的时钟源,该时钟源只能从PLL端获取,可选择分频1分频或1.5分频,若使用USB模块则必须先使能PLL并且时钟配置为72MHz或48MHz。

此外,在STM32中,可以选择一个时钟信号从MCO(PA8)脚输出,可以选择时钟源为PLL输出的2分频、HSI、HSE或系统时钟。

系统时钟SYSCLK,他提供STM32中绝大部分不见的工作时钟,系统时钟可以选择PLL输出、HSE和HSI、系统时钟最大频率为72MHz,通过AHB分配器分频后送给各个模块使用,AHB分配器可选1、2、4、8、·6、64、128、256、512分频,AHB分配器输出时钟可以供5大模块使用:

  • 送给AHB总线、内核、内存和DMA使用的HCLK时钟。
  • 通过8分频后送个Cortex的系统定时器时钟STCLK。
  • 直接送给Cortex的空闲运行时钟FCLK。
  • 送个低速外设总线APB1分配器,APB1分配器可以选择1、2、4、8和16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz);另一路送个定时器(TIM2~TIM7)倍频器使用,该定时器倍频器根据APB1分频值自动选择x1或x2倍频(APB1分频值为1时,定时器倍频器为1倍频,APB1分频值为其它值时,定时器倍频器采用2倍频)。
  • 送给高速外设总线APB2分频器,APB2分配器可选择1、2、4、8和16分频,其输出一路供APB2外设使用(PLCK2,最大频率为72MHz);一路送给定时器(TIM1&TIM8)使用,该定时器倍频器根据APB2分频值自动选择x1或x2倍频(APB2分频值为1时,定时器倍频器为1倍频,APB2分频值为其它值时,定时器倍频器采用2倍频);此外,APB2分配器输出还有一路供给ADC分配器使用,ADC分配器分频后供ADC模块使用,ADC分频可选2、4、6和8分频,不过ADC模块最大输入时钟不错过14MHz。

1.2 时钟树

图1 STM32时钟树

2. 时钟源

2.1 HSE时钟

高速外部时钟信号(HSE)可以有以下两种时钟源产生:

  • HSE外部晶体/陶瓷谐振器
  • HSE用户外部时钟

为了减少时钟输出的失真和缩短启动稳定时间,晶体/陶瓷谐振器和负载电容器必须尽可能地靠近振荡器引脚,负载电容值必须根据所选择的振荡器来调整。

图2 HSE/LSE时钟源

外部时钟源(HSE旁路)
在这个模式里,必须提供外部时钟,它的频率最高可达25MHz,用户可通过设置在时钟控制寄存器中的HSEBYP和HSEON位来选择这一模式。外部时钟信号(50%占空比的方波、正弦波或三角波)必须连到SOC_IN引脚,同时保证OSC_OUT引脚悬空,见图2)。

外部晶体/陶瓷谐振器(HSE晶体)
4~16Mz外部振荡器可为系统提供更为精确的主时钟,相关的硬件配置可参考图1,进一步信息可参考数据手册的电气特性部分。在时钟控制寄存器RCC_CR中的HSERDY位用来指示高速外部振荡器是否稳定,在启动时,直到这一位被硬件置’1’,时钟才被释放出来。如果在时钟中断寄存器RCC_CIR中允许产生中断,将会产生相应中断,HSE晶体可以通过设置时钟控制寄存器里RCC_CR中的HSEON位被启动和关闭。

2.2 HSI时钟

HSI时钟信号由内部8MHz的RC振荡器产生,可直接作为系统时钟或在2分频后作为PLL输入。HSI RC振荡器能够在不需要任何外部器件的条件下提供系统时钟,它的启动时间比HSE晶体振荡器短,然而,即使在校准之后它的时钟频率精度仍较差。
校准:制造工艺决定了不同芯片的RC振荡器频率会不同,这就是为什么每个芯片的HSI时钟频率在出厂前已经被ST校准到1%(25°C)的原因。系统复位时,工厂校准值被装载到时钟控制寄存器的HSICAL[7:0]位,如果用户的应用基于不同的电压或环境温度,这将会影响RC振荡器的精度,这时用户可以通过时钟控制寄存器里的HSITRIM[4:0]位来调整HSI频率,时钟控制寄存器中的HSIRDY位用来指示HSI RC振荡器是否稳定,在时钟启动过程中,直到这一位被硬件置’1’, HSI RC输出时钟才被释放。 HSI RC可由时钟控制寄存器中的HSION位来启动和关闭。如果HSE晶体振荡器失效, HSI时钟会被作为备用时钟源。

2.3 PLL时钟

内部PLL可以用来倍频HSI RC的输出时钟或HSE晶体输出时钟。PLL的设置(选择HSI振荡器除2或HSE振荡器为PLL的输入时钟、配置倍频因子)必须在其被激活前完成,一旦PLL被激活,这些参数就不能被修改。如果PLL中断在时钟中断寄存器里被允许,当PLL准备就绪时,可产生中断申请。如果需要在应用中使用USB接口, PLL必须被设置为输出48或72MHZ时钟,用于提供48MHz的USBCLK时钟。

2.4 LSE时钟

LSE晶体是一个32.768kHz的低速外部晶体或陶瓷谐振器,它为实时时钟或者其他定时功能提供一个低功耗且精确的时钟源。LSE晶体通过在备份域控制寄存器(RCC_BDCR)里的LSEON位启动和关闭,在备份域控制寄存器(RCC_BDCR)里的LSERDY指示LSE晶体振荡是否稳定,在启动阶段,直到这个位被硬件置’1’后, LSE时钟信号才被释放出来。如果在时钟中断寄存器里被允许,可产生中断申请。

外部时钟源(LSE旁路)
在这个模式里必须提供一个32.768kHz频率的外部时钟源。你可以通过设置在备份域控制寄存器(RCC_BDCR)里的LSEBYP和LSEON位来选择这个模式。具有50%占空比的外部时钟信号(方波、正弦波或三角波)必须连到OSC32_IN引脚,同时保证OSC32_OUT引脚悬空,见图1。

2.5 LSI时钟

LSI RC担当一个低功耗时钟源的角色,它可以在停机和待机模式下保持运行,为独立看门狗和自动唤醒单元提供时钟。 LSI时钟频率大约40kHz(在30kHz和60kHz之间)。LSI RC可以通过控制/状态寄存器(RCC_CSR)里的LSION位来启动或关闭,在控制/状态寄存器(RCC_CSR)里的LSIRDY位指示低速内部振荡器是否稳定,在启动阶段,直到这个位被硬件设置为’1’后,此时钟才被释放。如果在时钟中断寄存器(RCC_CIR)里被允许,将产生LSI中断申请。

LSI校准
可以通过校准内部低速振荡器LSI来补偿其频率偏移,从而获得精度可接受的RTC时间基数,以及独立看门狗(IWDG)的超时时间(当这些外设以LSI为时钟源)。校准可以通过使用TIM5的输入时钟(TIM5_CLK)测量LSI时钟频率实现,测量以HSE的精度为保证,软件可以通过调整RTC的20位预分频器来获得精确的RTC时钟基数,以及通过计算得到精确的独立看门狗(IWDG)的超时时间。

LSI校准步骤如下:
1.打开TIM5,设置通道4为输入捕获模式;
2.设置AFIO_MAPR的TIM5_CH4_IREMAP位为’1’,在内部把LSI连接到TIM5的通道4;
3.通过TIM5的捕获/比较4事件或者中断来测量LSI时钟频率;
4.根据测量结果和期望的RTC时间基数和独立看门狗的超时时间,设置20位预分频器。

2.6 系统时钟

系统复位后, HSI振荡器被选为系统时钟,当时钟源被直接或通过PLL间接作为系统时钟时,它将不能被停止,只有当目标时钟源准备就绪了(经过启动稳定阶段的延迟或PLL稳定),从一个时钟源到另一个时钟源的切换才会发生,在被选择时钟源没有就绪时,系统时钟的切换不会发生,直至目标时钟源就绪,才发生切换。在时钟控制寄存器(RCC_CR)里的状态位指示哪个时钟已经准备好了,哪个时钟目前被用作系统时钟。

2.7 RTC时钟

通 过 设 置 备 份 域 控 制 寄 存 器 (RCC_BDCR) 里 的 RTCSEL[1:0] 位 , RTCCLK 时 钟 源 可 以 由HSE/128、 LSE或LSI时钟提供,除非备份域复位,此选择不能被改变,LSE时钟在备份域里,但HSE和LSI时钟不是,因此:

  • 如果LSE被选为RTC时钟:只要VBAT维持供电,尽管VDD供电被切断, RTC仍继续工作。
  • 如果LSI被选为自动唤醒单元(AWU)时钟:如果VDD供电被切断, AWU状态不能被保证。
  • 如果HSE时钟128分频后作为RTC时钟:如果VDD供电被切断或内部电压调压器被关闭(1.8V域的供电被切断),则RTC状态不确定。必须设置电源控制寄存器(PWR_CR)的DPB位为’1’(取消后备区域的写保护)。

2.8 看门狗时钟

如果独立看门狗已经由硬件选择或软件启动, LSI振荡器将被强制在打开状态,并且不能被关闭,在LSI振荡器稳定后,时钟供应给IWDG。

2.9 时钟输出

STM32允许输出时钟信号到外部MCO引脚,不过相应的GPIO端口寄存器必须被配置为相应功能。以下8个时钟信号可被选作MCO时钟:

  • SYSCLK
  • HSI
  • HSE
  • 除2的PLL时钟
  • PLL2时钟
  • PLL3时钟除以2
  • XT1外部3~25MHz振荡器(用于以太网)
  • PLL3时钟(用于以太网)在MCO上输出的时钟必须小于50MHz(这是I/O端口的最大速度)。

时钟的选择由时钟配置寄存器(RCC_CFGR)中的MCO[3:0]位控制。

3 外设时钟系统

以下介绍不同总线上挂载各种外设,不同的芯片系列可能缺少某些外设,用户应根据自己的芯片型号确定。

1.AHB总线外设:DMA1、DMA2、SRAM、FLASH、CRC、FSMC、SDIO、OTG(互联型设备)、ETH(互联型设备)。
2.APB1(低速外设总线):TIM2TIM7、TIM12TIM14、WWDG、SPI2SPI3、USART2USART3、UART4UART5、I2C1I2C2、USB、CAN1~CAN2、BKP、DAC、CEC。
3.APB2(高速外设总线):AFIO、GPIOAGPIOG、ADC1ADC2、TIM1、TIM8、SPI1、USART1、ADC3、TIM15TIM17、TIM9TIM11。

4 RCC库函数

4.1 时钟频率

typedef struct
{
  uint32_t SYSCLK_Frequency;  /*!< 系统时钟频率,单位:Hz */
  uint32_t HCLK_Frequency;    /*!< AHB总线时钟频率,单位:Hz */
  uint32_t PCLK1_Frequency;   /*!< APB1总线时钟频率,单位:Hz */
  uint32_t PCLK2_Frequency;   /*!< APB2总线时钟频率,单位:Hz */
  uint32_t ADCCLK_Frequency;  /*!< ADC模块输入时钟频率,单位:Hz */
}RCC_ClocksTypeDef;

4.2 RCC库函数

RCC库函数原型及实现请详见stm32f10x_rcc模块,以下仅介绍各接口的作用。

函数名 描述
RCC_DeInit 将外设RCC寄存器重设为缺省值
RCC_HSEConfig 设置外部高速晶振( HSE)
RCC_WaitForHSEStartUp 等待 HSE 起振
RCC_AdjustHSICalibrationValue 调整内部高速晶振( HSI)校准值
RCC_HSICmd 使能或者失能内部高速晶振( HSI)
RCC_PLLConfig 设置 PLL 时钟源及倍频系数
RCC_PLLCmd 使能或者失能
PLLRCC_SYSCLKConfig 设置系统时钟( SYSCLK)
RCC_GetSYSCLKSource 返回用作系统时钟的时钟源
RCC_HCLKConfig 设置 AHB 时钟( HCLK)
RCC_PCLK1Config 设置低速 AHB 时钟( PCLK1)
RCC_PCLK2Config 设置高速 AHB 时钟( PCLK2)
RCC_ITConfig 使能或者失能指定的 RCC 中断
RCC_USBCLKConfig 设置 USB 时钟( USBCLK)
RCC_ADCCLKConfig 设置 ADC 时钟( ADCCLK)
RCC_LSEConfig 设置外部低速晶振( LSE)
RCC_LSICmd 使能或者失能内部低速晶振( LSI)
RCC_RTCCLKConfig 设置 RTC 时钟( RTCCLK)
RCC_RTCCLKCmd 使能或者失能 RTC 时钟
RCC_GetClocksFreq 返回不同片上时钟的频率
RCC_AHBPeriphClockCmd 使能或者失能 AHB 外设时钟
RCC_APB2PeriphClockCmd 使能或者失能 APB2 外设时钟
RCC_APB1PeriphClockCmd 使能或者失能 APB1 外设时钟
RCC_APB2PeriphResetCmd 强制或者释放高速 APB( APB2)外设复位
RCC_APB1PeriphResetCmd 强制或者释放低速 APB( APB1)外设复位
RCC_BackupResetCmd 强制或者释放后备域复位
RCC_ClockSecuritySystemCmd 使能或者失能时钟安全系统
RCC_MCOConfig 选择在 MCO 管脚上输出的时钟源
RCC_GetFlagStatus 检查指定的 RCC 标志位设置与否
RCC_ClearFlag 清除 RCC 的复位标志位
RCC_GetITStatus 检查指定的 RCC 中断发生与否
RCC_ClearITPendingBit 清除 RCC 的中断待处理位

5 时钟系统初始化

假设采用外部提供晶振(HSE)频率为8MHz,PLLCLK=SYSCLK=72MHz,PCLK2=72MHz,PCLK1=36MHz,则时钟系统初始化代码如下:

void RCC_config()
{ 
  ErrorStatus HSEStartUpStatus; // 定义错误状态变量

  /* 时钟系统初始化 */
  RCC_DeInit();//将RCC寄存器重新设置为默认值
  RCC_HSEConfig(RCC_HSE_ON); //打开外部高速时钟晶振
  HSEStartUpStatus = RCC_WaitForHSEStartUp();// 等待外部高速时钟晶振工作
  if(HSEStartUpStatus == SUCCESS) 
  { 
    RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置AHB不分频,HCLK=SYSCLK
    RCC_PCLK2Config(RCC_HCLK_Div1);//设置APB2不分频,P2CLK=HCLK
    RCC_PCLK1Config(RCC_HCLK_Div2); //设置APB1 为2分频,P1CLK=HCLK/2
    FLASH_SetLatency(FLASH_Latency_2);//设置FLASH代码延时
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//使能预取指缓存
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, //设置PLL时钟源,
      RCC_PLLMul_9);//外部时钟不分频,为HSE的9倍频8MHz * 9 = 72MHz
    RCC_PLLCmd(ENABLE);//使能PLL
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);//等待PLL准备就绪
    {
      RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//设置PLL为系统时钟源
      while(RCC_GetSYSCLKSource() != 0x08)//判断PLL是否是系统时钟
      {
      } 
    }
  }

  /* 以下示例部分外设时钟初始化 */
  /* 使能DMA1时钟*/
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  /* 使能CAN1时钟*/
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
  /* 使能GPIOD时钟*/
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); 
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容