STM32F207時鍾系統解析


在前幾天的文章《晶振原理解析》中介紹了晶振如何產生時鍾的,板子使用的是25M無源晶振,下文將介紹STM32F207的時鍾系統如何將25M晶振時鍾轉換為120M系統主頻時鍾的。

01、時鍾系統介紹

                                                                    ▲時鍾系統專業名詞縮寫

時鍾系統關鍵組成部分

01 內部高速時鍾(HSI)

HSI時鍾信號可以通過內部16MHZ的RC振盪器產生,可以直接用於系統時鍾或者用於PLL輸入。

HSI的RC振盪器的優勢是:在最小成本(沒有外部器件)情況下提供一個時鍾源。它的啟動速度要比HSE晶體振盪器更快,但是即使校准頻率后,它的精度仍然小於外部晶體振盪器或陶瓷諧振器。

02 外部高速時鍾(HSE)

外部高速時鍾信息(HSE)可以通過兩個時鍾源產生:

① 外部晶體/陶瓷諧振器

② 外部用戶時鍾

▲兩種時鍾源接入示意圖

 

03 主鎖相環時鍾(PLL)

STM32F2xx具有兩個PLL

① 主要的PLL通過HSE或HSI提供時鍾,並且有兩個輸出時鍾;

② 專用的PLL(PLLI2S)被用於產生一個精確的時鍾去實現高質量音頻效果在I2S接口;

 

 

HSE/M*N/P得到PLL時鍾

關於PLL鎖相環說明

 

 

從1處輸入,3處輸出是1的N倍。

3處除以N又作為輸入,當1和2的頻率一樣,就鎖定了。(之所以圖上是xN,因為從2看向3的)

 

04 低速外部時鍾(LSE)

LSE是一個32.768KHZ低速外部晶振或陶瓷諧振器。

它的優點:提供低速但是高精度時鍾給RTC外設,為時鍾/日歷或其他時間應用。

 

05低速內部時鍾(LSI)

LSI RC作為一個低速時鍾源,它可以運行在停止和待機模式中給獨立看門狗(IWDG)和自動喚醒(AWU)。它的時鍾頻率在32MHZ左右。

 

02、代碼分析

時鍾初始化代碼在system_stm32f2xx.c文件中,大部分時候我們不需要修改時鍾代碼的,各個總線的頻率我們可以在文件頭看到。

=============================================================================
  *=============================================================================
  *        Supported STM32F2xx device revision    | Rev B and Y
  *-----------------------------------------------------------------------------
  *        System Clock source                    | PLL (HSE)
  *-----------------------------------------------------------------------------
  *        SYSCLK(Hz)                             | 120000000
  *-----------------------------------------------------------------------------
  *        HCLK(Hz)                               | 120000000
  *-----------------------------------------------------------------------------
  *        AHB Prescaler                          | 1
  *-----------------------------------------------------------------------------
  *        APB1 Prescaler                         | 4
  *-----------------------------------------------------------------------------
  *        APB2 Prescaler                         | 2
  *-----------------------------------------------------------------------------
  *        HSE Frequency(Hz)                      | 25000000
  *-----------------------------------------------------------------------------
  *        PLL_M                                  | 25
  *-----------------------------------------------------------------------------
  *        PLL_N                                  | 240
  *-----------------------------------------------------------------------------
  *        PLL_P                                  | 2
  *-----------------------------------------------------------------------------
  *        PLL_Q                                  | 5
  *-----------------------------------------------------------------------------
  *        PLLI2S_N                               | NA
  *-----------------------------------------------------------------------------
  *        PLLI2S_R                               | NA
  *-----------------------------------------------------------------------------
  *        I2S input clock                        | NA
  *-----------------------------------------------------------------------------
  *        VDD(V)                                 | 3.3
  *-----------------------------------------------------------------------------
  *        Flash Latency(WS)                      | 3
  *-----------------------------------------------------------------------------
  *        Prefetch Buffer                        | ON
  *-----------------------------------------------------------------------------
  *        Instruction cache                      | ON
  *-----------------------------------------------------------------------------
  *        Data cache                             | ON
  *-----------------------------------------------------------------------------
  *        Require 48MHz for USB OTG FS,          | Enabled
  *        SDIO and RNG clock                     |
  *-----------------------------------------------------------------------------
  *=============================================================================
  ******************************************************************************

在文件開始定義的有系統時鍾頻率的全局變量SystemCoreClock,其他地方需要時鍾頻率,可以直接使用該變量。

uint32_t SystemCoreClock = 120000000;

時鍾配置從SystemInit函數執行,調用SystemInit的在匯編文件中startup_stm32f2xx.s(Keil編譯環境)。

IMPORT  __main
    LDR     R0, =SystemInit
    BLX     R0
    LDR     R0, =__main
    BX      R0
    ENDP

在這里說明一下文檔版本的問題:

 

 

▲STM32F20X_User_manual的V7版和V8版對比圖

 

上述兩圖的區別是系統最大時鍾從120MHZ變成了168MHZ,我的理解是同樣是STM32F20X,ST由於技術進步或其他,使得新版STM32F207芯片超頻支持168MHZ。

文檔下載地址:

https://www.st.com/en/microcontrollers-microprocessors/stm32f2x7.html#resource

在線預覽地址:

https://www.st.com/content/ccc/resource/technical/document/reference_manual/51/f7/f3/06/cd/b6/46/ec/CD00225773.pdf/files/CD00225773.pdf/jcr:content/translations/en.CD00225773.pdf

下面我們主要分析SystemCoreClock的120M時鍾怎么從一個外部25MHZ的HSE得到的。

我們要從25MHZ的外部時鍾得到120M的系統時鍾,需要上圖中標注的重要4點:

1、使能HSE

2、選擇HSE作為主PLL的輸入時鍾

3、主PLL倍頻后得到120MHZ時鍾

4、系統時鍾選擇主PLL時鍾輸出作為系統時鍾

 

我們找到對應的代碼

  1、使能HSE

/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);

在RCC_CR寄存器(RCCclock control register RCC時鍾控制器)中,有打開HSE的控制位

 

 輸入時鍾

/* Configure the main PLL */
RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

RCC_PLLCFGR_PLLSRC_HSE就是配置HSE作為主PLL的輸入時鍾

  3、主PLL倍頻后得到120MHZ時鍾

/* Configure the main PLL */
RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

4、配置主PLL作為系統時鍾的輸入時鍾

/* Select the main PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_PL

對於主PLL的配置寄存器,在RCC_PLLCFGR寄存器中有說明

整理后得知f(out)=f(in)* N / M / P

/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M      25
#define PLL_N      240
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      2

這樣就獲得了120M時鍾

注意:

PLL_M大於等於2且小於等於63

PLL_N大於等於64且小於等於432

PLL_P只能是2、4、6、或8

但2對應0,4對應1,6對應2,8對應3。

ST並沒有使用if或case語句判斷,因為對應的數據除以2減去1就是寄存器這兩位的值,所以可以按照下面這樣寫,這種寫法值得我們學習。

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

其他外設的時鍾配置時

/* HCLK = SYSCLK / 1*/
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK / 2*/
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
/* PCLK1 = HCLK / 4*/
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

03、備 注 

時鍾中斷

可以配置外部晶振出錯時的中斷,還有RCC中斷,因此我們可以在外部時鍾出問題時,切換為內部時鍾,不至於整個系統掛掉。具體見ST給的官方代碼。

 無源晶振不起振

沒有程序,無源晶振是不起振的,需要配置RCC時鍾控制寄存器的HSEON位打開或關閉HSE振盪器。具體可以看之前的文章《晶振原理解析》。

 關於APB和PCLK

F207是時鍾圖沒有顯示PCLK1和PCLK2,應該就是APB1和APB2

應該指的是一個PCLK應該是PeripheralClock的簡稱,看F105手冊

 

 

點擊查看本文所在的專輯,STM32F207教程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM