時(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)生)

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

- 產(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
{
// 故障后處理程序
}
}

