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