STM32系統時鐘配置及時鐘樹

參考資料:《 STM32F4xx 中文參考手冊》 RCC 章節。

STM32時鐘可大致分爲系統時鐘和其它時鐘兩大類,總共包含5個時鐘源 HSI(High Speed Internal Clock)HSE(High Speed External Clock)LSI(low Speed Internal Clock)LSE(Low Speed External Clock )PLL(Phase Locked Loop Clock)。

下圖即爲STM32時鐘樹,黃色標識部分即爲系統時鐘部分,橙色即爲其它時鐘部分。

一、系統時鐘

①HSE(High Speed External Clock)高速外部時鐘信號

 HSE 是高速的外部時鐘信號,可以由有源晶振或者無源晶振提供,頻率從 4-26MHZ不等。當使用有源晶振時,時鐘從 OSC_IN

引腳進入,OSC_OUT 引腳懸空,當選用無源晶振時,時鐘從 OSC_IN 和 OSC_OUT 進入,並且要配諧振電容。HSE 我們使用

25M 的無源晶振。如果我們使用 HSE 或者 HSE 經過 PLL倍頻之後的時鐘作爲系統時鐘 SYSCLK,當 HSE 故障時候,不僅

HSE 會被關閉,PLL也會被關閉,此時高速的內部時鐘時鐘信號HSI 會作爲備用的系統時鐘,直到 HSE 恢復正常,HSI=16M。

HSI(High Speed Internal Clock)高速內部時鐘信號

由芯片內部RC振盪器提供,大小爲16MHZ,當HSE故障時,系統時鐘會自動切換到HSI,直到HSE 啓動成功。

②鎖相環 PLL(Phase Locked Loop )

PLL的主要作用是對時鐘進行倍頻,然後把時鐘輸出到各個功能部件。PLL有兩個,一個是主 PLL(黃色部分,爲系統時鐘部

分),另外一個是專用的 PLLI2S(橙色部分),他們均由 HSE 或者 HSI 提供時鐘輸入信號。

主 PLL有兩路的時鐘輸出,第一個輸出時鐘 PLLCLK用於系統時鐘,第二個輸出用於 USB OTG FS 的時鐘、RNG 和 SDIO 時

鍾。專用的 PLLI2S 用於生成精確時鐘,給 I2S 提供時鐘。

HSE 或者 HSI 經過 PLL 時鐘輸入分頻因子 M分頻後,成爲 VCO 的時鐘輸入,VCO 的時鐘必須在 1~2M 之間,我們選擇

HSE=25M 作爲 PLL 的時鐘輸入,M 設置爲 25,那麼 VCO輸入時鐘就等於 1M。VCO 輸入時鐘經過 VCO倍頻因子 N 倍頻之

後,成爲 VCO時鐘輸出,VCO時鐘必須在 192~432M 之間。我們配置 N 爲 360,則 VCO的輸出時鐘等於 360M。VCO 輸出時

鍾之後有三個分頻因子:PLLCLK分頻因子 p,USB OTG FS/RNG/SDIO時鐘分頻因子 Q,分頻因子R

具體公式如下

                                                             PLLCLK = HSE(HSI) / M *N /P 

                                                             PLL48CK =  HSE(HSI) / M *N /Q

③系統時鐘 SYSCLK

系統時鐘來源可以是:HSI、PLLCLK、HSE,具體的由時鐘配置寄存器 RCC_CFGR的 SW位配置。如果系統時鐘是由HSE 經

過 PLL倍頻之後的 PLLCLK 得到,當 HSE 出現故障的時候,系統時鐘會切換爲HSI=16M,直到 HSE 恢復正常爲止。

④AHB 總線時鐘 HCLK

系統時鐘 SYSCLK 經過 AHB 預分頻器分頻之後得到時鐘叫 AHB 總線時鐘,即 HCLK,分頻因子可以是:[1,2,4,8,16,64,

128,256,512],具體的由時鐘配置寄存器RCC_CFGR 的 HPRE 位設置。片上大部分外設的時鐘都是經過 HCLK 分頻得到,

至於 AHB總線上的外設的時鐘設置爲多少,得等到我們使用該外設的時候才設置。這裏只需粗線條的設置好AHB的時鐘即可。

⑤APB2總線時鐘 PCLK2

APB2總線時鐘 PCLK2 由 HCLK經過高速 APB2預分頻器得到,分頻因子可以是:[1,2,4,8,16],具體由時鐘配置寄存器

RCC_CFGR 的 PPRE2位設置。HCLK2屬於高速的總線時鐘,片上高速的外設就掛載到這條總線上,比如全部的 GPIO、

USART1、SPI等。至於 APB2總線上的外設的時鐘設置爲多少,得等到我們使用該外設的時候才設置。這裏只需粗線條的設置好

APB2的時鐘即可。

⑥APB1總線時鐘 PCLK1

APB1 總線時鐘 PCLK1 由 HCLK經過低速 APB預分頻器得到,分頻因子可以是:[1,2,4,8,16],具體由時鐘配置寄存器

RCC_CFGR的 PPRE1位設置。HCLK1屬於低速的總線時鐘,最高爲 45M,片上低速的外設就掛載到這條總線上,比如

USART2/3/4/5、SPI2/3,I2C1/2等。至於 APB1總線上的外設的時鐘設置爲多少,得等到我們使用該外設的時候才設置。

這裏只需粗線條的設置好APB的時鐘即可。

系統初始化時鐘過程如下

Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main

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

這是一個啓動文件,當我們單片機上電後,首先執行的啓動文件,會進入SystemInit函數

void SystemInit(void)
{
  /* FPU設置 ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif
  /* 復位RCC時鐘配置到默認的初始化狀態 ------------*/
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;

  /* Reset CFGR register */
  RCC->CFGR = 0x00000000;

  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;

  /* Reset PLLCFGR register */
  RCC->PLLCFGR = 0x24003010;

  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;

  /* Disable all interrupts */
  RCC->CIR = 0x00000000;

#if defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM)
  SystemInit_ExtMemCtl(); 
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
         
  /* 配置系統時鐘 ----------------------------------*/
  SetSysClock();

  /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}

在SystemInit中會配置系統時鐘

配置系統時鐘的代碼如下

下面是CMSIS Cortex-M4設備外圍設備訪問層系統源文件中的設置系統時鐘函數SetSysClock(void)

static void SetSysClock(void)
{

/******************************************************************************/
/*            使用HSE作爲PLL的輸入來配置系統時鐘                                */
/******************************************************************************/
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* 一、使能HSE */
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
  /* 等待HSE使能穩定,如果時間超時,則跳出 */
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    HSEStatus = (uint32_t)0x00;
  }
/*二、HSE穩定後,開始配置HCLK、PCLK2、PCLK1、PLL各自的預分頻因子與倍頻因子 */
  if (HSEStatus == (uint32_t)0x01)
  {
	
	
		 /* 配置HCLK爲1分頻,即HCLK = 系統時鐘 HCLK = SYSCLK / 1 */
		RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
    
		/*配置APB2總線時鐘爲2分頻  PCLK2 = HCLK / 2 */
		RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
				
		/*配置APB1總線時鐘爲4分頻PCLK1 = HCLK / 4 */
		RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
   
		/* 配置主PLL */
		RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
										(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
   
    /* 三、使能主PLL */
    RCC->CR |= RCC_CR_PLLON;

    /*等待主PLL穩定 */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
/*------------------------------------------------------------------------------------------*/		   
		/* 使能Over-drive 模式來達到更高的時鐘頻率 */
		PWR->CR |= PWR_CR_ODEN;
		while((PWR->CSR & PWR_CSR_ODRDY) == 0)        //判斷Over-drive模式是否已經成功啓動
		{
		}
		PWR->CR |= PWR_CR_ODSWEN;
		while((PWR->CSR & PWR_CSR_ODSWRDY) == 0)
		{
		}      
		/*選擇FLASH預取指緩存的模式, 指令緩存, 數據緩存和等待緩存 */
		FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
/*------------------------------------------------------------------------------------------*/		
				
    /* 四、選擇主PLL作爲系統時鐘源 */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= RCC_CFGR_SW_PLL;

    /*判斷系統時鐘是否已經穩定 */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
    {
    }
  }
  else
  { /* 如果HSE啓動失敗,那麼時鐘就會被錯誤的配置,用戶可以在這裏添加一些代碼來處理錯誤 */
  }
 
}

系統時鐘配置主要就是以上部分,系統時鐘初始化就進行的是上述操作.

 

二、其它時鐘

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由外接的晶體諧振器產生,

所配的諧振電容精度要求高,不然很容易不起震。

B、獨立看門狗時鐘

獨立看門狗時鐘由內部的低速時鐘 LSI 提供,大小爲 32KHZ。

C、I2S 時鐘

I2S 時鐘可由外部的時鐘引腳 I2S_CKIN 輸入,也可由專用的 PLLI2SCLK提供,具體的由 RCC 時鐘配置寄存器 (RCC_CFGR)

的 I2SSCR位配置。

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。

E、USB PHY 時鐘

F429 的 USB 沒有集成 PHY,要想實現 USB 高速傳輸的話,必須外置 USB PHY 芯片,常用的芯片是 USB3300。當外接 USB

PHY 芯片時,PHY 芯片需要給 MCU 提供一個時鐘。

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位選擇。

以上就是STM32f429的時鐘樹講解,理解之後,以此類推,對於學習STM32其它時鐘樹有很大的幫助。

 

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