STM32學(xué)習(xí)筆記(五)RCC(Reset and Clock Control)

時(shí)鐘

時(shí)鐘樹(shù)

外部時(shí)鐘

外部時(shí)鐘更為精確

高速外部時(shí)鐘信號(hào) --- HSE(High-Speed External Clock Signal)
  • 復(fù)用端口:OSC_OUT 和 OSC_IN
    管腳信息可在 數(shù)據(jù)手冊(cè) 中查看
    OSC_OUT 和 OSC_IN 對(duì)應(yīng)管腳
  • 頻率:4~16 MHz(一般連接 8MHz 晶振)
低速外部時(shí)鐘信號(hào)# --- LSE(Low-Speed External Clock Signal)
  • 復(fù)用端口:OSC32_OUT 和 OSC32_IN
    管腳信息可在 數(shù)據(jù)手冊(cè) 中查看
    OSC32_OUT 和 OSC32_IN 對(duì)應(yīng)管腳
  • 頻率:32.768 kHz(只能連接 32.768kHz 晶振)

內(nèi)部時(shí)鐘

高速內(nèi)部時(shí)鐘信號(hào) --- HSI(High-Speed Internal Clock Signal)
  • 頻率:8 MHz(由內(nèi)部 RC振蕩器 產(chǎn)生)
低速內(nèi)部時(shí)鐘信號(hào) --- LSI(Low-Speed Internal Clock Signal)
  • 頻率:40 kHz 左右(由內(nèi)部 RC振蕩器 產(chǎn)生)
LSI振蕩器頻率特性 (數(shù)據(jù)手冊(cè)---電氣特性)

鎖相環(huán)時(shí)鐘 --- PLLCLK(Phase Locked Loop Clock)

時(shí)鐘樹(shù)放大圖中的PLLCLK
  • 產(chǎn)生:由圖中可以看出,PLLCLK有兩種來(lái)源—— HSI 和 HSE,經(jīng)過(guò)倍頻(PLLMUL)后輸出。
  • 頻率:在默認(rèn)情況下,輸入時(shí)鐘為 HSE = 8MHz ,倍頻因子為 x9,系統(tǒng)時(shí)鐘選擇 PLLCLK 達(dá)到最大頻率 72MHz。如果使用內(nèi)部時(shí)鐘,輸入時(shí)鐘為 HSI / 2 = 4MHz,倍頻因子最大為 x16,最高只能輸出 64MHz時(shí)鐘。
  • 注意
    • PLL的設(shè)置(選擇HIS振蕩器除2或HSE振蕩器為PLL的輸入時(shí)鐘,和選擇倍頻因子)必須在其被激活前完成。一旦PLL被激活,這些參數(shù)就不能被改動(dòng)(自行配置時(shí)鐘時(shí)一定要先設(shè)置再激活!)。
    • 如果需要在應(yīng)用中使用USB接口,PLL必須被設(shè)置為輸出48或72MHZ時(shí)鐘,用于提供48MHz的USBCLK時(shí)鐘。

RCC寄存器

  • 時(shí)鐘控制寄存器 --- CR(Clock control register):使能 和 調(diào)整 HSI、HSE、PLL 時(shí)鐘;

    • 作用---使能:位0為 HSI 使能;位16為 HSE 使能;位24為 PLL 使能;
    • 作用---時(shí)鐘就緒標(biāo)志:位1為 HSI 就緒;位17為 HSE 就緒;位25為 PLL 就緒;
    • 復(fù)位值:0x000 XX83
  • 時(shí)鐘配置寄存器 --- CFGR(Clock configuration register):配置 分頻和倍頻、系統(tǒng)時(shí)鐘和PLL時(shí)鐘選擇、時(shí)鐘外部輸出(至示波器等);

    • 作用---選擇系統(tǒng)時(shí)鐘:位1:0,00為HSI,01為HSE,10為PLL;
    • 作用---選擇 PLL 時(shí)鐘( HSE 或 HSI / 2 或 HSE / 2);
    • 作用---(預(yù))分頻和倍頻,并設(shè)置分頻因子和倍頻因子;
    • 作用---輸出時(shí)鐘至IO口(IO口最高頻率為50MHz,即輸出時(shí)鐘頻率最大為50MHz);(其實(shí)高于50MHz也可以,但是會(huì)失真)
    • 復(fù)位值:0x0000 0000
  • 時(shí)鐘中斷寄存器 --- CIR(Clock interrupt register):使能時(shí)鐘就緒的中斷,清楚時(shí)鐘就緒標(biāo)志位;

    • 作用---使能時(shí)鐘就緒的中斷:時(shí)鐘準(zhǔn)備就緒,標(biāo)志位置位,如果使能了該中斷則會(huì)產(chǎn)生一個(gè)中斷;
    • 作用---清除(復(fù)位)時(shí)鐘準(zhǔn)備就緒后產(chǎn)生的標(biāo)志位;
    • 作用---判斷 HSE 是否故障,若失效則 位7"CSCC" 置1;
    • 復(fù)位值:0x0000 0000
  • APB2外設(shè)復(fù)位寄存器 --- APB2RSTR(APB2 peripheral reset register):將APB2總線(xiàn)上的外設(shè)恢復(fù)至復(fù)位值;

    • 復(fù)位值:0x0000 0000
  • APB1外設(shè)復(fù)位寄存器 --- APB1RSTR(APB1 peripheral reset register):將APB1總線(xiàn)上的外設(shè)恢復(fù)至復(fù)位值;

    • 復(fù)位值:0x0000 0000
  • AHB外設(shè)時(shí)鐘使能寄存器 --- AHBENR(AHB peripheral clock enable register):使能AHB總線(xiàn)上的外設(shè);

    • 復(fù)位值:0x0000 0014
    • 注意:該寄存器只有DMA1、DMA2、SRAM、FLITF、CRC(循環(huán)冗余校驗(yàn))、FSMC(可變靜態(tài)存儲(chǔ)控制器)、SDIO的時(shí)鐘使能,其中DMA1、DMA2、SRAM、FLITF的時(shí)鐘默認(rèn)已經(jīng)被使能;
  • APB2外設(shè)時(shí)鐘使能寄存器 --- APB2ENR(APB2 peripheral clock enable register):使能APB2總線(xiàn)上的外設(shè);

    • 復(fù)位值:0x0000 0000
    • 注意:除 EXTI(外部中斷)外所有掛載在 APB2總線(xiàn) 上的外設(shè)均能通過(guò)該寄存器使能;
  • APB1外設(shè)時(shí)鐘使能寄存器 --- APB1ENR(APB1 peripheral clock enable register):使能APB1總線(xiàn)上的外設(shè);

    • 復(fù)位值:0x0000 0000
    • 注意:除 RTC(Real-Time Clock)(實(shí)時(shí)時(shí)鐘)外所有掛載在 APB1總線(xiàn)上的外設(shè)均可通過(guò)該寄存器使能;
  • 備份域控制寄存器 --- BDCR(Backup domain control register):RTC(Real-Time Clock)(實(shí)時(shí)時(shí)鐘)的使能和配置,LSE 的使能和配置;

    • 復(fù)位值:0x0000 0000
    • 注意:RTC是一個(gè)掉電后還繼續(xù)運(yùn)行的定時(shí)器
  • 控制/狀態(tài)寄存器 --- CSR(Control/status register):儲(chǔ)存/消除 復(fù)位標(biāo)志,LSI 的就緒標(biāo)志位;

    • 復(fù)位值:0x0000 0000

常用RCC固件庫(kù)函數(shù) (stm32f10x_rcc.h)

固件庫(kù)中 HSE默認(rèn)為 8M, 默認(rèn)使用 HSE 9倍頻 的 PLL時(shí)鐘 作為系統(tǒng)時(shí)鐘,若要更改時(shí)鐘配置,推薦使用固件庫(kù)函數(shù)更改而非直接更改固件庫(kù)

AHB上外設(shè)使能函數(shù) --- RCC_AHBPeriphClockCmd

void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
  • RCC_AHBPeriph:對(duì)應(yīng)外設(shè);
  • NewState:ENABLE 為使能,DISABLE 為關(guān)閉;
  • 示例:
//使能 FMSC
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE)

APB2高速總線(xiàn)上外設(shè)使能函數(shù) --- RCC_APB2PeriphClockCmd

void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
  • RCC_APB2Periph:對(duì)應(yīng)外設(shè);
  • NewState:ENABLE 為使能,DISABLE 為關(guān)閉;
  • 示例:
//使能 GPIOA口
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE)

APB1低速總線(xiàn)上外設(shè)使能函數(shù) --- RCC_APB1PeriphClockCmd

void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
  • RCC_APB1Periph:對(duì)應(yīng)外設(shè);
  • NewState:ENABLE 為使能,DISABLE 為關(guān)閉;
  • 示例:
//使能 USART2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

RCC清理函數(shù) --- RCC_DeInit

void RCC_DeInit(void);
  • 作用:只打開(kāi) HSI 時(shí)鐘,其余所有時(shí)鐘包括系統(tǒng)時(shí)鐘均關(guān)閉,清楚所有時(shí)鐘就緒中斷標(biāo)志位,關(guān)閉時(shí)鐘對(duì)外輸出;
  • 示例:
RCC_DeInit();

HSE時(shí)鐘使能函數(shù) --- RCC_HSEConfig

void RCC_HSEConfig(uint32_t RCC_HSE);
  • RCC_HSE:可以為 OFF,ON,Bypass;
  • 作用:參數(shù) RCC_HSE 為 RCC_HSE_OFF 時(shí)關(guān)閉 HSE 時(shí)鐘,為 RCC_HSE_ON 時(shí)打開(kāi) HSE 時(shí)鐘,為RCC_HSE_Bypass 時(shí)打開(kāi) HSE 時(shí)鐘的同時(shí)還打開(kāi) 時(shí)鐘安全系統(tǒng)(CSS) 的時(shí)鐘;
  • 注明:時(shí)鐘安全系統(tǒng)(CSS) 開(kāi)啟后,如果HSE時(shí)鐘發(fā)生故障,HSE振蕩器被自動(dòng)關(guān)閉,時(shí)鐘失效事件將被送到高級(jí)定時(shí)器(TIM1和TIM8)的剎車(chē)輸入端,并產(chǎn)生時(shí)鐘安全中斷CSSI,此CSSI中斷連接到Cortex?-M3的NMI中斷;
  • 示例:
//使能HSE
RCC_HSEConfig(RCC_HSE_ON);

HSE判斷時(shí)鐘啟動(dòng)就緒函數(shù)--- RCC_WaitForHSEStartUp

typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
ErrorStatus RCC_WaitForHSEStartUp(void);
  • 返回值:SUCCESS 表示啟動(dòng)成功, ERROR 表示啟動(dòng)失??;
  • 示例:
ErrorStatus HSEStatus;
HSEStatus = RCC_WaitForHSEStartUp();
//等待 HSE 就緒
if(HSEStatus == SUCCESS)
{
  // HSE 就緒后實(shí)現(xiàn)后需要運(yùn)行的程序
}

HSI時(shí)鐘使能函數(shù) --- RCC_HSICmd

typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
void RCC_HSICmd(FunctionalState NewState);
  • NewState:可以為 ENABLE,DISABLE;
  • 示例:
//使能HSI
RCC_HSICmd(ENABLE);

PLL時(shí)鐘配置函數(shù) --- RCC_PLLConfig

void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul);
  • RCC_PLLSource:PLL的時(shí)鐘源,可選擇 HSI二分頻(RCC_PLLSource_HSI_Div2)、HSE(RCC_PLLSource_HSE_Div1)、HSE二分頻(RCC_PLLSource_HSE_Div2);
  • RCC_PLLMul_x:倍頻因子,互聯(lián)型 x 可為 (2~9),其他則可為 (2~16);
  • 示例:
//配置鎖相環(huán)時(shí)鐘 PLLCLK = HSE * 9
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

PLL時(shí)鐘使能函數(shù) --- RCC_PLLCmd

void RCC_PLLCmd(FunctionalState NewState);
  • NewState:可以為 ENABLE,DISABLE;
  • 注意:必須先配置PLL,再使能;
  • 示例:
//使能 PLL
RCC_PLLCmd(ENABLE);

系統(tǒng)時(shí)鐘配置函數(shù) --- RCC_SYSCLKConfig

void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
  • RCC_SYSCLKSource:系統(tǒng)的時(shí)鐘源,可選擇 HSI(RCC_SYSCLKSource_HSI)、HSE(RCC_SYSCLKSource_HSE)、PLL(RCC_SYSCLKSource_PLLCLK);
  • 示例:
//選擇系統(tǒng)時(shí)鐘 為PLL時(shí)鐘
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

自行配置系統(tǒng)時(shí)鐘

程序思路

  • RCC清除,便于自行配置;
  • 使能 HSE 或 HSI(系統(tǒng)時(shí)鐘為高速時(shí)鐘);
  • 等待使能完成;
  • 使能FLASH預(yù)取緩沖器,并設(shè)置為2個(gè)等待周期
  • 設(shè)置 AHB、APB1、APB2的預(yù)分頻因子;
  • 配置鎖相環(huán)時(shí)鐘:選擇鎖相環(huán)時(shí)鐘源和倍頻因子;
  • 使能鎖相環(huán)時(shí)鐘(再次強(qiáng)調(diào)要先配置鎖相環(huán)再使能);
  • 等待PLL時(shí)鐘穩(wěn)定;
  • 選擇系統(tǒng)時(shí)鐘為PLL時(shí)鐘;
  • 等待系統(tǒng)時(shí)鐘穩(wěn)定;
    (若不選擇PLL為系統(tǒng)時(shí)鐘,且不需USB,可不開(kāi)啟PLL)

以下程序?yàn)閺?fù)制粘貼火哥源碼。

HSE作為系統(tǒng)時(shí)鐘

// 默認(rèn) HSE 晶振頻率為 8M
void HSE_SetSysClk(uint32_t RCC_PLLMul_x)               //時(shí)鐘為8M*x
{
    ErrorStatus HSEStatus;
    
    //RCC寄存器復(fù)位
    RCC_DeInit();
    
    //使能HSE
    RCC_HSEConfig(RCC_HSE_ON);
    
    //等待HSE就緒
    HSEStatus = RCC_WaitForHSEStartUp();
    if(HSEStatus == SUCCESS)
    {
        //使能預(yù)取緩沖器(預(yù)取指)
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
        //配置兩個(gè)等待周期
        FLASH_SetLatency(FLASH_Latency_2);
        
        //設(shè)置分頻因子
        RCC_HCLKConfig(RCC_SYSCLK_Div1);
        RCC_PCLK1Config(RCC_HCLK_Div2);
        RCC_PCLK2Config(RCC_HCLK_Div1);
        
        //配置鎖相環(huán)時(shí)鐘 PLLCLK = HSE * RCC_PLLMul_x
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_x);
        //使能PLL
        RCC_PLLCmd(ENABLE);
        //等待PLL時(shí)鐘穩(wěn)定
        while( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET );
        
        //選擇系統(tǒng)時(shí)鐘 為PLL時(shí)鐘
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
        
        while( RCC_GetSYSCLKSource() != 0x08 );
    }
    else
    {
        // 故障后處理程序
    }
}

HSI作為系統(tǒng)時(shí)鐘

void HSI_SetSysClk(uint32_t RCC_PLLMul_x)               //時(shí)鐘為4M*x
{
    __IO uint32_t HSIStatus = 0;
    
    //RCC寄存器復(fù)位
    RCC_DeInit();
    
    //使能HSI
    RCC_HSICmd(ENABLE);
    
    //等待HSI就緒
    HSIStatus = RCC->CR & RCC_CR_HSIRDY;
    if(HSIStatus == RCC_CR_HSIRDY)
    {
        //使能預(yù)取緩沖器(預(yù)取指)
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
        //配置兩個(gè)等待周期
        FLASH_SetLatency(FLASH_Latency_2);
        
        //設(shè)置分頻因子
        RCC_HCLKConfig(RCC_SYSCLK_Div1);
        RCC_PCLK1Config(RCC_HCLK_Div2);
        RCC_PCLK2Config(RCC_HCLK_Div1);
        
        //配置鎖相環(huán)時(shí)鐘 PLLCLK = HSE * RCC_PLLMul_x
        RCC_PLLConfig(RCC_PLLSource_HSI_Div2,RCC_PLLMul_x);
        //使能PLL
        RCC_PLLCmd(ENABLE);
        //等待PLL時(shí)鐘穩(wěn)定
        while( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET );
        
        //選擇系統(tǒng)時(shí)鐘 為PLL時(shí)鐘
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
        
        while( RCC_GetSYSCLKSource() != 0x08 );
    }
    else
    {
        // 故障后處理程序
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容