秉火429笔记之八 RCC时钟
目錄
1. RCC 作用概述
2. RCC框圖剖析—時鐘樹
3. 編程要點
4. 源碼實例
1. RCC 作用概述
RCC :reset clock control 復位和時鐘控制器。
設置系統時鐘SYSCLK、設置AHB分頻因子(決定HCLK等于多少)、設置APB2分頻因子(決定PCLK2等于多少)、設置APB1分頻因子(決定PCLK1等于多少)、設置各個外設的分頻因子;控制AHB、APB2和APB1這三條總線時鐘的開啟、控制每個外設的時鐘的開啟。對于SYSCLK、HCLK、PCLK2、PCLK1這四個時鐘的配置一般是:HCLK = SYSCLK=PLLCLK = 180M,PCLK1=HCLK/2 = 90M,PCLK1=HCLK/4 = 45M。如果需要使用USB,HCLK=168M為宜。
2. RCC框圖剖析—時鐘樹
????????????????????????????????????????????????????????? 數據手冊F429 時鐘樹
- HSE 高速外部時鐘信號
外部時鐘信號,可由有源晶振或無源晶振提供,頻率范圍 4-26MHZ。若使用HSE作為時鐘源,當HSE故障時,將會切換到HSI,直到HSE恢復正常,HSI=16MHZ.
- 鎖相環PLL
PLL的主要作用是對時鐘進行倍頻,然后把時鐘輸出到各個功能部件。PLL有兩個,一個是主PLL,另外一個是專用的PLLI2S,他們均由HSE或者HSI提供時鐘輸入信號.
主PLL有兩路的時鐘輸出,第一個輸出時鐘PLLCLK用于系統時鐘,F429里面最高是180M,第二個輸出用于USB OTG FS的時鐘(48M)、RNG和SDIO時鐘(<=48M)。專用的PLLI2S用于生成精確時鐘,給I2S提供時鐘。
HSE或者HSI經過PLL時鐘輸入分頻因子M(2~63)分頻后,成為VCO的時鐘輸入,VCO的時鐘必須在1~2M之間,我們選擇HSE=25M作為PLL的時鐘輸入,M設置為25,那么VCO輸入時鐘就等于1M.
VCO輸入時鐘經過VCO倍頻因子N倍頻之后,成為VCO時鐘輸出,VCO時鐘必須在192~432M之間。我們配置N為360,則VCO的輸出時鐘等于360M。如果要把系統時鐘超頻,就得在VCO倍頻系數N這里做手腳。PLLCLK_OUTMAX = VCOCLK_OUTMAX/P_MIN = 432/2=216M,即F429最高可超頻到216M。
VCO輸出時鐘之后有三個分頻因子:PLLCLK分頻因子p,USB OTG FS/RNG/SDIO時鐘分頻因子Q,分頻因子R(F446才有,F429沒有)。p可以取值2、4、6、8,我們配置為2,則得到PLLCLK=180M。Q可以取值4~15,但是USB OTG FS必須使用48M,Q=VCO輸出時鐘360/48=7.5,出現了小數這明顯是錯誤,權衡之策是是重新配置VCO的倍頻因子N=336,VCOCLK=1M*336=336M,PLLCLK=VCOCLK/2=168M,USBCLK=336/7=48M,細心的讀者應該發現了,在使用USB的時候,PLLCLK被降低到了168M,不能使用180M,這實乃ST的一個奇葩設計。因此,通常對時鐘無高速需求的情況下,配置為168M為宜。
- 系統時鐘SYSCLK
系統時鐘來源可以是:HSI、PLLCLK、HSE,具體的由時鐘配置寄存器RCC_CFGR的SW位配置.
- AHB總線時鐘HCLK
系統時鐘SYSCLK經過AHB預分頻器分頻之后得到時鐘叫APB總線時鐘,即HCLK,分頻因子可以是:[1,2,4,8,16,64,128,256,512],具體的由時鐘配置寄存器RCC_CFGR的HPRE位設置。
通常情況下,設置為1分頻,即HCLK=SYSCLK。
- APB2總線時鐘HCLK2
APB2總線時鐘PCLK2由HCLK經過高速APB2預分頻器得到,分頻因子可以是:[1,2,4,8,16],具體由時鐘配置寄存器RCC_CFGR的PPRE2位設置。。HCLK2屬于高速的總線時鐘,片上高速的外設就掛載到這條總線上.
通常情況下,設置為2分頻,即PCLK2 = HCLK /2。
- APB1總線時鐘HCLK1
APB1總線時鐘PCLK1由HCLK經過低速APB預分頻器得到,分頻因子可以是:[1,2,4,8,16],具體由時鐘配置寄存器RCC_CFGR的PPRE1位設置。HCLK1屬于低速的總線時鐘,最高為45M,片上低速的外設就掛載到這條總線上.
通常情況下,設置為4分頻,即PCLK1 = HCLK/4。
- 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由外接的晶體諧振器產生,所配的諧振電容精度要求高,不然很容易不起震。
- 獨立看門狗時鐘
獨立看門狗時鐘由內部的低速時鐘LSI提供,大小為32KHZ
- I2S時鐘
I2S時鐘可由外部的時鐘引腳I2S_CKIN輸入,也可由專用的PLLI2SCLK提供,具體的由RCC 時鐘配置寄存器 (RCC_CFGR)的I2SSCR位配置。我們在使用I2S外設驅動W8978的時候,使用的時鐘是PLLI2SCLK,這樣就可以省掉一個有源晶振。
- ETH PHY以太網時鐘
429要想實現以太網功能,除了有本身內置的MAC之外,還需要外接一個PHY芯片,常見的PHY芯片有DP83848和LAN8720,其中DP83848支持MII和RMII接口,LAN8720只支持RMII接口。秉火F429開發板用的是RMII接口,選擇的PHY芯片是LAB8720。使用RMII接口的好處是使用的IO減少了一半,速度還是跟MII接口一樣。當使用RMII接口時,PHY芯片只需輸出一路時鐘給MCU即可,如果是MII接口,PHY芯片則需要提供兩路時鐘給MCU。
- USB PHY時鐘
F429的USB沒有集成PHY,要想實現USB高速傳輸的話,必須外置USB PHY芯片,常用的芯片是USB3300。當外接USB PHY芯片時,PHY芯片需要給MCU提供一個時鐘。外擴USB3300會占用非常多的IO,跟SDRAM和RGB888的IO會復用的很厲害。
- 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位選擇。
3. 編程要點
- 開啟HSE/HSI ,并等待 HSE/HSI 穩定
- 設置 AHB、APB2、APB1的預分頻因子
- 設置PLL的時鐘來源,設置VCO輸入時鐘 分頻因子PLL_M,設置VCO輸出時鐘
- 倍頻因子PLL_N,設置PLLCLK時鐘分頻因子PLL_P,設置OTG FS,SDIO,RNG
- 時鐘分頻因子 PLL_Q
- 開啟PLL,并等待PLL穩定
- 把PLLCK切換為系統時鐘SYSCLK
- 讀取時鐘切換狀態位,確保PLLCLK被選為系統時鐘
- 官方有快捷配置工具
4. 源碼實例
#include "./rcc/bsp_clkconfig.h" #include "stm32f4xx_rcc.h"/** 使用HSE時,設置系統時鐘的步驟* 1、開啟HSE ,并等待 HSE 穩定* 2、設置 AHB、APB2、APB1的預分頻因子* 3、設置PLL的時鐘來源* 設置VCO輸入時鐘 分頻因子 m* 設置VCO輸出時鐘 倍頻因子 n* 設置PLLCLK時鐘分頻因子 p* 設置OTG FS,SDIO,RNG時鐘分頻因子 q* 4、開啟PLL,并等待PLL穩定* 5、把PLLCK切換為系統時鐘SYSCLK* 6、讀取時鐘切換狀態位,確保PLLCLK被選為系統時鐘*//** m: VCO輸入時鐘 分頻因子,取值2~63* n: VCO輸出時鐘 倍頻因子,取值192~432* p: PLLCLK時鐘分頻因子 ,取值2,4,6,8* q: OTG FS,SDIO,RNG時鐘分頻因子,取值4~15* 函數調用舉例,使用HSE設置時鐘* SYSCLK=HCLK=180M,PCLK2=HCLK/2=90M,PCLK1=HCLK/4=45M* HSE_SetSysClock(25, 360, 2, 7);* HSE作為時鐘來源,經過PLL倍頻作為系統時鐘,這是通常的做法* 系統時鐘超頻到216M爽一下* HSE_SetSysClock(25, 432, 2, 9);*/ void HSE_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q) {__IO uint32_t HSEStartUpStatus = 0;// 使能HSE,開啟外部晶振,秉火F429使用 HSE=25MRCC_HSEConfig(RCC_HSE_ON);// 等待HSE啟動穩定HSEStartUpStatus = RCC_WaitForHSEStartUp();if (HSEStartUpStatus == SUCCESS){// 調壓器電壓輸出級別配置為1,以便在器件為最大頻率// 工作時使性能和功耗實現平衡RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;// HCLK = SYSCLK / 1RCC_HCLKConfig(RCC_SYSCLK_Div1);// PCLK2 = HCLK / 2RCC_PCLK2Config(RCC_HCLK_Div2);// PCLK1 = HCLK / 4RCC_PCLK1Config(RCC_HCLK_Div4);// 如果要超頻就得在這里下手啦// 設置PLL來源時鐘,設置VCO分頻因子m,設置VCO倍頻因子n,// 設置系統時鐘分頻因子p,設置OTG FS,SDIO,RNG分頻因子qRCC_PLLConfig(RCC_PLLSource_HSE, m, n, p, q);// 使能PLLRCC_PLLCmd(ENABLE);// 等待 PLL穩定while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){} /*-----------------------------------------------------*///開啟 OVER-RIDE模式,以能達到更高頻率PWR->CR |= PWR_CR_ODEN;while((PWR->CSR & PWR_CSR_ODRDY) == 0){}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穩定之后,把PLL時鐘切換為系統時鐘SYSCLKRCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);// 讀取時鐘切換狀態位,確保PLLCLK被選為系統時鐘while (RCC_GetSYSCLKSource() != 0x08){}}else{ // HSE啟動出錯處理while (1){}} }/** 使用HSI時,設置系統時鐘的步驟* 1、開啟HSI ,并等待 HSI 穩定* 2、設置 AHB、APB2、APB1的預分頻因子* 3、設置PLL的時鐘來源* 設置VCO輸入時鐘 分頻因子 m* 設置VCO輸出時鐘 倍頻因子 n* 設置SYSCLK時鐘分頻因子 p* 設置OTG FS,SDIO,RNG時鐘分頻因子 q* 4、開啟PLL,并等待PLL穩定* 5、把PLLCK切換為系統時鐘SYSCLK* 6、讀取時鐘切換狀態位,確保PLLCLK被選為系統時鐘*//** m: VCO輸入時鐘 分頻因子,取值2~63* n: VCO輸出時鐘 倍頻因子,取值192~432* p: PLLCLK時鐘分頻因子 ,取值2,4,6,8* q: OTG FS,SDIO,RNG時鐘分頻因子,取值4~15* 函數調用舉例,使用HSI設置時鐘* SYSCLK=HCLK=180M,PCLK2=HCLK/2=90M,PCLK1=HCLK/4=45M* HSI_SetSysClock(16, 360, 2, 7);* HSE作為時鐘來源,經過PLL倍頻作為系統時鐘,這是通常的做法* 系統時鐘超頻到216M爽一下* HSI_SetSysClock(16, 432, 2, 9);*/void HSI_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q) {__IO uint32_t HSIStartUpStatus = 0;// 把RCC外設初始化成復位狀態RCC_DeInit();//使能HSI, HSI=16MRCC_HSICmd(ENABLE);// 等待 HSI 就緒HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY;// 只有 HSI就緒之后則繼續往下執行if (HSIStartUpStatus == RCC_CR_HSIRDY){// 調壓器電壓輸出級別配置為1,以便在器件為最大頻率// 工作時使性能和功耗實現平衡RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;// HCLK = SYSCLK / 1RCC_HCLKConfig(RCC_SYSCLK_Div1);// PCLK2 = HCLK / 2RCC_PCLK2Config(RCC_HCLK_Div2);// PCLK1 = HCLK / 4RCC_PCLK1Config(RCC_HCLK_Div4);// 如果要超頻就得在這里下手啦// 設置PLL來源時鐘,設置VCO分頻因子m,設置VCO倍頻因子n,// 設置系統時鐘分頻因子p,設置OTG FS,SDIO,RNG分頻因子qRCC_PLLConfig(RCC_PLLSource_HSI, m, n, p, q);// 使能PLLRCC_PLLCmd(ENABLE);// 等待 PLL穩定while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){} /*-----------------------------------------------------*///開啟 OVER-RIDE模式,以能達到更高頻率PWR->CR |= PWR_CR_ODEN;while((PWR->CSR & PWR_CSR_ODRDY) == 0){}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穩定之后,把PLL時鐘切換為系統時鐘SYSCLKRCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);// 讀取時鐘切換狀態位,確保PLLCLK被選為系統時鐘while (RCC_GetSYSCLKSource() != 0x08){}}else{ // HSI啟動出錯處理while (1){}} }// MCO1 PA8 GPIO 初始化 void MCO1_GPIO_Config(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);// MCO1 GPIO 配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); }// MCO2 PC9 GPIO 初始化 void MCO2_GPIO_Config(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);// MCO2 GPIO 配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOC, &GPIO_InitStructure); }?
總結
以上是生活随笔為你收集整理的秉火429笔记之八 RCC时钟的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自签 https 证书
- 下一篇: 3.6 51单片机-动态数码管