STM32系統時鐘RCC詳解

轉載自:https://blog.csdn.net/as480133937/article/details/98845509

1什麼是時鐘

時鐘是單片機運行的基礎,時鐘信號推動單片機內各個部分執行相應的指令。時鐘系統就是CPU的脈搏,決定cpu速率,像人的心跳一樣 只有有了心跳,人才能做其他的事情,而單片機有了時鐘,才能夠運行執行指令,才能夠做其他的處理 (點燈,串口,ADC),時鐘的重要性不言而喻。

 

爲什麼 STM32 要有多個時鐘源呢?

STM32本身十分複雜,外設非常多  但我們實際使用的時候只會用到有限的幾個外設,使用任何外設都需要時鐘才能啓動,但並不是所有的外設都需要系統時鐘那麼高的頻率,爲了兼容不同速度的設備,有些高速,有些低速,如果都用高速時鐘,勢必造成浪費   並且,同一個電路,時鐘越快功耗越快,同時抗電磁干擾能力也就越弱,所以較爲複雜的MCU都是採用多時鐘源的方法來解決這些問題。所以便有了STM32的時鐘系統和時鐘樹

 

總括:

  • STM32時鐘系統主要的目的就是給相對獨立的外設模塊提供時鐘,也是爲了降低整個芯片的耗能
  • 系統時鐘,是處理器運行時間基準(每一條機器指令一個時鐘週期)
  • 時鐘是單片機運行的基礎,時鐘信號推動單片機內各個部分執行相應的指令。
  • 一個單片機內提供多個不同的系統時鐘,可以適應更多的應用場合。
  • 不同的功能模塊會有不同的時鐘上限,因此提供不同的時鐘,也能在一個單片機內放置更多的功能模塊。
    對不同模塊的時鐘增加開啓和關閉功能,可以降低單片機的功耗
  • STM32爲了低功耗,他將所有的外設時鐘都設置爲disable(不使能),用到什麼外設,只要打開對應外設的時鐘就可以, 其他的沒用到的可以還是disable(不使能),這樣耗能就會減少。  這就是爲什麼不管你配置什麼功能都需要先打開對應的時鐘的原因

 

STM32的時鐘系統框圖

 

乍一看很嚇人,但其實很好理解,我們看系統時鐘SYSCLK 的左邊  系統時鐘有很多種選擇,而左邊的部分就是設置系統時鐘使用那個時鐘源,   

系統時鐘SYSCLK 的右邊,則是系統時鐘通過AHB預分頻器,給相對應的外設設置相對應的時鐘頻率

 

從左到右可以簡單理解爲  各個時鐘源--->系統時鐘來源的設置--->各個外設時鐘的設置

時鐘系統

1各個時鐘源    (左邊的部分)

STM32 有4個獨立時鐘源:HSI、HSE、LSI、LSE。
①、HSI是高速內部時鐘,RC振盪器,頻率爲8MHz,精度不高。
②、HSE是高速外部時鐘,可接石英/陶瓷諧振器,或者接外部時鐘源,頻率範圍爲4MHz~16MHz
③、LSI是低速內部時鐘,RC振盪器,頻率爲40kHz,提供低功耗時鐘。  
④、LSE是低速外部時鐘,接頻率爲32.768kHz的石英晶體。

其中LSI是作爲IWDGCLK(獨立看門狗)時鐘源和RTC時鐘源 而獨立使用 

而HSI高速內部時鐘 HSE高速外部時鐘 LSI低速內部時鐘  這三個經過分頻或者倍頻 作爲系統時鐘來使用

 

PLL爲鎖相環倍頻輸出,其時鐘輸入源可選擇爲HSI/2、HSE或者HSE/2。倍頻可選擇爲2~16倍,但是其輸出頻率最大不得超過72MHz。  通過倍頻之後作爲系統時鐘的時鐘源

 

舉個例子:Keil編寫程序是默認的時鐘爲72Mhz,其實是這麼來的:外部晶振(HSE)提供的8MHz(與電路板上的晶振的相關)通過PLLXTPRE分頻器後,進入PLLSRC選擇開關,進而通過PLLMUL鎖相環進行倍頻(x9)後,爲系統提供72MHz的系統時鐘(SYSCLK)。之後是AHB預分頻器對時鐘信號進行分頻,然後爲低速外設提供時鐘。

或者內部RC振盪器(HSI) 爲8MHz  /2 爲4MHz 進入PLLSRC選擇開關,通過PLLMUL鎖相環進行倍頻(x18)後 爲72MHz

 

PS:  網上有很多人說是5個時鐘源,這種說法有點問題,學習之後就會發現PLL並不是自己產生的時鐘源,而是通過其他三個時鐘源倍頻得到的時鐘

2系統時鐘SYSCLK

系統時鐘SYSCLK可來源於三個時鐘源:
①、HSI振盪器時鐘
②、HSE振盪器時鐘
③、PLL時鐘
最大爲72Mhz

 

3USB時鐘

STM32中有一個全速功能的USB模塊,其串行接口引擎需要一個頻率爲48MHz的時鐘源。該時鐘源只能從PLL輸出端獲取(唯一的),,可以選擇爲1.5分頻或者1分頻,也就是,當需要使用USB模塊時,PLL必須使能,並且時鐘頻率配置爲48MHz或72MHz

4把時鐘信號輸出到外部

STM32可以選擇一個時鐘信號輸出到MCO腳(PA8)上,可以選擇爲PLL輸出的2分頻、HSI、HSE、或者系統時鐘。可以把時鐘信號輸出供外部使用

5系統時鐘通過AHB分頻器給外設提供時鐘(右邊的部分)  重點

 

從左到右可以簡單理解爲  系統時鐘--->AHB分頻器--->各個外設分頻倍頻器 --->   外設時鐘的設置

 

右邊部分爲:系統時鐘SYSCLK通過AHB分頻器分頻後送給各模塊使用,AHB分頻器可選擇1、2、4、8、16、64、128、256、512分頻。其中AHB分頻器輸出的時鐘送給5大模塊使用: 

 ①內核總線:送給AHB總線、內核、內存和DMA使用的HCLK時鐘。 

 ②Tick定時器:通過8分頻後送給Cortex的系統定時器時鐘。 

 ③I2S總線:直接送給Cortex的空閒運行時鐘FCLK。 

 ④APB1外設:送給APB1分頻器。APB1分頻器可選擇1、2、4、8、16分頻,其輸出一路供APB1外設使用(PCLK1,最大頻率36MHz),另一路送給通用定時器使用。該倍頻器可選擇1或者2倍頻,時鐘輸出供定時器2-7使用。 

 ⑤APB2外設:送給APB2分頻器。APB2分頻器可選擇1、2、4、8、16分頻,其輸出一路供APB2外設使用(PCLK2,最大頻率72MHz),另一路送給高級定時器。該倍頻器可選擇1或者2倍頻,時鐘輸出供定時器1和定時器8使用。

 

另外,APB2分頻器還有一路輸出供ADC分頻器使用,分頻後送給ADC模塊使用。ADC分頻器可選擇爲2、4、6、8分頻。 

需要注意的是,如果 APB 預分頻器分頻係數是 1,則定時器時鐘頻率 (TIMxCLK) 爲 PCLKx。否則,定      時器時鐘頻率將爲 APB 域的頻率的兩倍:TIMxCLK = 2xPCLKx。 

APB1和APB2的對應外設

F1系列

APB1上面連接的是低速外設,包括電源接口、備份接口、CAN、USB、I2C1、I2C2、USART2、USART3、UART4、UART5、SPI2、SP3等;

而APB2上面連接的是高速外設,包括UART1、SPI1、Timer1、ADC1、ADC2、ADC3、所有的普通I/O口(PA-PE)、第二功能I/O(AFIO)口等。


F4系列

這個和F1系列類似,我們就舉幾個特殊的

 APB2總線:高級定時器timer1, timer8以及通用定時器timer9, timer10, timer11   UTART1,USART6

 APB1總線:通用定時器timer2~timer5,通用定時器timer12~timer14以及基本定時器timer6,timer7  UTART2~UTART5

F4系列的系統時鐘頻率最高能到168M

 

具體  可以在 stm32f10x_rcc.h  和stm32f40x_rcc.h   中查看

或者通過 STM32參考手冊搜索“系統架構”或者“系統結構”  查看外設掛在哪個時鐘下

 

RCC相關寄存器:

這裏我們以F1系列爲例

  1. RCC 寄存器結構,RCC_TypeDeff,在文件“stm32f10x.h”中定義如下:
  2. 1059行->1081行。:
  3. typedef struct
  4. {
  5. vu32 CR; //HSI,HSE,CSS,PLL等的使能
  6. vu32 CFGR; //PLL等的時鐘源選擇以及分頻係數設定
  7. vu32 CIR; // 清除/使能 時鐘就緒中斷
  8. vu32 APB2RSTR; //APB2線上外設復位寄存器
  9. vu32 APB1RSTR; //APB1線上外設復位寄存器
  10. vu32 AHBENR; //DMA,SDIO等時鐘使能
  11. vu32 APB2ENR; //APB2線上外設時鐘使能
  12. vu32 APB1ENR; //APB1線上外設時鐘使能
  13. vu32 BDCR; //備份域控制寄存器
  14. vu32 CSR;
  15. } RCC_TypeDef;

可以對上上面的時鐘框圖和RCC寄存器來學習,對STM32的時鐘系統有個大概的瞭解   其實也就是我們上面介紹的流程,理解了自然也就能寫出來

RCC初始化:

這裏我們使用HSE(外部時鐘),正常使用的時候也都是使用外部時鐘

使用HSE時鐘,程序設置時鐘參數流程:
1、將RCC寄存器重新設置爲默認值   RCC_DeInit;
2、打開外部高速時鐘晶振HSE       RCC_HSEConfig(RCC_HSE_ON);
3、等待外部高速時鐘晶振工作      HSEStartUpStatus = RCC_WaitForHSEStartUp();
4、設置AHB時鐘         RCC_HCLKConfig;
5、設置高速AHB時鐘     RCC_PCLK2Config;
6、設置低速速AHB時鐘   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的配置函數(使用外部8MHz晶振)  

系統時鐘72MHz,APH 72MHz,APB2 72MHz,APB1 32MHz,USB 48MHz TIMCLK=72M

  1. void RCC_Configuration(void)
  2. {
  3. //----------使用外部RC晶振-----------
  4. RCC_DeInit(); //初始化爲缺省值
  5. RCC_HSEConfig(RCC_HSE_ON); //使能外部的高速時鐘
  6. while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等待外部高速時鐘使能就緒
  7. FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer
  8. FLASH_SetLatency(FLASH_Latency_2); //Flash 2 wait state
  9. RCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK = SYSCLK
  10. RCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2 = HCLK
  11. RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK1 = HCLK/2
  12. RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //PLLCLK = 8MHZ * 9 =72MHZ
  13. RCC_PLLCmd(ENABLE); //Enable PLLCLK
  14. while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLLCLK is ready
  15. RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock
  16. while(RCC_GetSYSCLKSource()!=0x08); //Wait till PLL is used as system clock source
  17. //---------打開相應外設時鐘--------------------
  18. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能APB2外設的GPIOA的時鐘
  19. }

也就是我們時鐘樹框圖從左到右的配置,

時鐘監視系統(CSS)

STM32還提供了一個時鐘監視系統(CSS),用於監視高速外部時鐘(HSE)的工作狀態。倘若HSE失效,會自動切換(高速內部時鐘)HSI作爲系統時鐘的輸入,保證系統的正常運行。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章