時鐘
外部時鐘
外部時鐘更為精確
高速外部時鐘信號 --- HSE(High-Speed External Clock Signal)
-
復(fù)用端口:OSC_OUT 和 OSC_IN
管腳信息可在 數(shù)據(jù)手冊 中查看
OSC_OUT 和 OSC_IN 對應(yīng)管腳 - 頻率:4~16 MHz(一般連接 8MHz 晶振)
低速外部時鐘信號# --- LSE(Low-Speed External Clock Signal)
-
復(fù)用端口:OSC32_OUT 和 OSC32_IN
管腳信息可在 數(shù)據(jù)手冊 中查看
OSC32_OUT 和 OSC32_IN 對應(yīng)管腳 - 頻率:32.768 kHz(只能連接 32.768kHz 晶振)
內(nèi)部時鐘
高速內(nèi)部時鐘信號 --- HSI(High-Speed Internal Clock Signal)
- 頻率:8 MHz(由內(nèi)部 RC振蕩器 產(chǎn)生)
低速內(nèi)部時鐘信號 --- LSI(Low-Speed Internal Clock Signal)
- 頻率:40 kHz 左右(由內(nèi)部 RC振蕩器 產(chǎn)生)
鎖相環(huán)時鐘 --- PLLCLK(Phase Locked Loop Clock)
- 產(chǎn)生:由圖中可以看出服傍,PLLCLK有兩種來源—— HSI 和 HSE挠他,經(jīng)過倍頻(PLLMUL)后輸出。
- 頻率:在默認情況下跳仿,輸入時鐘為 HSE = 8MHz 屑迂,倍頻因子為 x9浸策,系統(tǒng)時鐘選擇 PLLCLK 達到最大頻率 72MHz。如果使用內(nèi)部時鐘屈糊,輸入時鐘為 HSI / 2 = 4MHz的榛,倍頻因子最大為 x16琼了,最高只能輸出 64MHz時鐘逻锐。
-
注意:
- PLL的設(shè)置(選擇HIS振蕩器除2或HSE振蕩器為PLL的輸入時鐘,和選擇倍頻因子)必須在其被激活前完成雕薪。一旦PLL被激活昧诱,這些參數(shù)就不能被改動(自行配置時鐘時一定要先設(shè)置再激活!)所袁。
- 如果需要在應(yīng)用中使用USB接口盏档,PLL必須被設(shè)置為輸出48或72MHZ時鐘,用于提供48MHz的USBCLK時鐘燥爷。
RCC寄存器
-
時鐘控制寄存器 --- CR(Clock control register):使能 和 調(diào)整 HSI蜈亩、HSE、PLL 時鐘前翎;
- 作用---使能:位0為 HSI 使能稚配;位16為 HSE 使能;位24為 PLL 使能港华;
- 作用---時鐘就緒標志:位1為 HSI 就緒道川;位17為 HSE 就緒;位25為 PLL 就緒立宜;
- 復(fù)位值:0x000 XX83
-
時鐘配置寄存器 --- CFGR(Clock configuration register):配置 分頻和倍頻冒萄、系統(tǒng)時鐘和PLL時鐘選擇、時鐘外部輸出(至示波器等)橙数;
- 作用---選擇系統(tǒng)時鐘:位1:0尊流,00為HSI,01為HSE灯帮,10為PLL崖技;
- 作用---選擇 PLL 時鐘( HSE 或 HSI / 2 或 HSE / 2)蜘澜;
- 作用---(預(yù))分頻和倍頻,并設(shè)置分頻因子和倍頻因子响疚;
- 作用---輸出時鐘至IO口(IO口最高頻率為50MHz鄙信,即輸出時鐘頻率最大為50MHz);(其實高于50MHz也可以,但是會失真)
- 復(fù)位值:0x0000 0000
-
時鐘中斷寄存器 --- CIR(Clock interrupt register):使能時鐘就緒的中斷忿晕,清楚時鐘就緒標志位装诡;
- 作用---使能時鐘就緒的中斷:時鐘準備就緒,標志位置位践盼,如果使能了該中斷則會產(chǎn)生一個中斷鸦采;
- 作用---清除(復(fù)位)時鐘準備就緒后產(chǎn)生的標志位;
- 作用---判斷 HSE 是否故障咕幻,若失效則 位7"CSCC" 置1渔伯;
- 復(fù)位值:0x0000 0000
-
APB2外設(shè)復(fù)位寄存器 --- APB2RSTR(APB2 peripheral reset register):將APB2總線上的外設(shè)恢復(fù)至復(fù)位值;
- 復(fù)位值:0x0000 0000
-
APB1外設(shè)復(fù)位寄存器 --- APB1RSTR(APB1 peripheral reset register):將APB1總線上的外設(shè)恢復(fù)至復(fù)位值肄程;
- 復(fù)位值:0x0000 0000
-
AHB外設(shè)時鐘使能寄存器 --- AHBENR(AHB peripheral clock enable register):使能AHB總線上的外設(shè)锣吼;
- 復(fù)位值:0x0000 0014
- 注意:該寄存器只有DMA1、DMA2蓝厌、SRAM玄叠、FLITF、CRC(循環(huán)冗余校驗)拓提、FSMC(可變靜態(tài)存儲控制器)读恃、SDIO的時鐘使能,其中DMA1代态、DMA2寺惫、SRAM、FLITF的時鐘默認已經(jīng)被使能蹦疑;
-
APB2外設(shè)時鐘使能寄存器 --- APB2ENR(APB2 peripheral clock enable register):使能APB2總線上的外設(shè)西雀;
- 復(fù)位值:0x0000 0000
- 注意:除 EXTI(外部中斷)外所有掛載在 APB2總線 上的外設(shè)均能通過該寄存器使能;
-
APB1外設(shè)時鐘使能寄存器 --- APB1ENR(APB1 peripheral clock enable register):使能APB1總線上的外設(shè)必尼;
- 復(fù)位值:0x0000 0000
- 注意:除 RTC(Real-Time Clock)(實時時鐘)外所有掛載在 APB1總線上的外設(shè)均可通過該寄存器使能蒋搜;
-
備份域控制寄存器 --- BDCR(Backup domain control register):RTC(Real-Time Clock)(實時時鐘)的使能和配置,LSE 的使能和配置判莉;
- 復(fù)位值:0x0000 0000
- 注意:RTC是一個掉電后還繼續(xù)運行的定時器
-
控制/狀態(tài)寄存器 --- CSR(Control/status register):儲存/消除 復(fù)位標志豆挽,LSI 的就緒標志位;
- 復(fù)位值:0x0000 0000
常用RCC固件庫函數(shù) (stm32f10x_rcc.h)
固件庫中 HSE默認為 8M, 默認使用 HSE 9倍頻 的 PLL時鐘 作為系統(tǒng)時鐘券盅,若要更改時鐘配置帮哈,推薦使用固件庫函數(shù)更改而非直接更改固件庫
AHB上外設(shè)使能函數(shù) --- RCC_AHBPeriphClockCmd
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
- RCC_AHBPeriph:對應(yīng)外設(shè);
- NewState:ENABLE 為使能锰镀,DISABLE 為關(guān)閉娘侍;
- 示例:
//使能 FMSC
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE)
APB2高速總線上外設(shè)使能函數(shù) --- RCC_APB2PeriphClockCmd
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
- RCC_APB2Periph:對應(yīng)外設(shè)咖刃;
- NewState:ENABLE 為使能,DISABLE 為關(guān)閉憾筏;
- 示例:
//使能 GPIOA口
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE)
APB1低速總線上外設(shè)使能函數(shù) --- RCC_APB1PeriphClockCmd
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
- RCC_APB1Periph:對應(yīng)外設(shè)嚎杨;
- NewState:ENABLE 為使能,DISABLE 為關(guān)閉氧腰;
- 示例:
//使能 USART2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC清理函數(shù) --- RCC_DeInit
void RCC_DeInit(void);
- 作用:只打開 HSI 時鐘枫浙,其余所有時鐘包括系統(tǒng)時鐘均關(guān)閉,清楚所有時鐘就緒中斷標志位古拴,關(guān)閉時鐘對外輸出箩帚;
- 示例:
RCC_DeInit();
HSE時鐘使能函數(shù) --- RCC_HSEConfig
void RCC_HSEConfig(uint32_t RCC_HSE);
- RCC_HSE:可以為 OFF,ON黄痪,Bypass紧帕;
- 作用:參數(shù) RCC_HSE 為 RCC_HSE_OFF 時關(guān)閉 HSE 時鐘,為 RCC_HSE_ON 時打開 HSE 時鐘桅打,為RCC_HSE_Bypass 時打開 HSE 時鐘的同時還打開 時鐘安全系統(tǒng)(CSS) 的時鐘是嗜;
- 注明:時鐘安全系統(tǒng)(CSS) 開啟后,如果HSE時鐘發(fā)生故障油额,HSE振蕩器被自動關(guān)閉叠纷,時鐘失效事件將被送到高級定時器(TIM1和TIM8)的剎車輸入端,并產(chǎn)生時鐘安全中斷CSSI潦嘶,此CSSI中斷連接到Cortex?-M3的NMI中斷;
- 示例:
//使能HSE
RCC_HSEConfig(RCC_HSE_ON);
HSE判斷時鐘啟動就緒函數(shù)--- RCC_WaitForHSEStartUp
typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
ErrorStatus RCC_WaitForHSEStartUp(void);
- 返回值:SUCCESS 表示啟動成功崇众, ERROR 表示啟動失數嘟;
- 示例:
ErrorStatus HSEStatus;
HSEStatus = RCC_WaitForHSEStartUp();
//等待 HSE 就緒
if(HSEStatus == SUCCESS)
{
// HSE 就緒后實現(xiàn)后需要運行的程序
}
HSI時鐘使能函數(shù) --- RCC_HSICmd
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
void RCC_HSICmd(FunctionalState NewState);
- NewState:可以為 ENABLE顷歌,DISABLE锰蓬;
- 示例:
//使能HSI
RCC_HSICmd(ENABLE);
PLL時鐘配置函數(shù) --- RCC_PLLConfig
void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul);
- RCC_PLLSource:PLL的時鐘源,可選擇 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)時鐘 PLLCLK = HSE * 9
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
PLL時鐘使能函數(shù) --- RCC_PLLCmd
void RCC_PLLCmd(FunctionalState NewState);
- NewState:可以為 ENABLE队萤,DISABLE轮锥;
- 注意:必須先配置PLL,再使能要尔;
- 示例:
//使能 PLL
RCC_PLLCmd(ENABLE);
系統(tǒng)時鐘配置函數(shù) --- RCC_SYSCLKConfig
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
- RCC_SYSCLKSource:系統(tǒng)的時鐘源舍杜,可選擇 HSI(RCC_SYSCLKSource_HSI)新娜、HSE(RCC_SYSCLKSource_HSE)、PLL(RCC_SYSCLKSource_PLLCLK)既绩;
- 示例:
//選擇系統(tǒng)時鐘 為PLL時鐘
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
自行配置系統(tǒng)時鐘
程序思路
- RCC清除概龄,便于自行配置胃惜;
- 使能 HSE 或 HSI(系統(tǒng)時鐘為高速時鐘)飞醉;
- 等待使能完成;
- 使能FLASH預(yù)取緩沖器师枣,并設(shè)置為2個等待周期互拾;
- 設(shè)置 AHB歪今、APB1、APB2的預(yù)分頻因子颜矿;
- 配置鎖相環(huán)時鐘:選擇鎖相環(huán)時鐘源和倍頻因子寄猩;
- 使能鎖相環(huán)時鐘(再次強調(diào)要先配置鎖相環(huán)再使能);
- 等待PLL時鐘穩(wěn)定骑疆;
- 選擇系統(tǒng)時鐘為PLL時鐘田篇;
- 等待系統(tǒng)時鐘穩(wěn)定;
(若不選擇PLL為系統(tǒng)時鐘箍铭,且不需USB泊柬,可不開啟PLL)
以下程序為復(fù)制粘貼火哥源碼。
HSE作為系統(tǒng)時鐘
// 默認 HSE 晶振頻率為 8M
void HSE_SetSysClk(uint32_t RCC_PLLMul_x) //時鐘為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);
//配置兩個等待周期
FLASH_SetLatency(FLASH_Latency_2);
//設(shè)置分頻因子
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
//配置鎖相環(huán)時鐘 PLLCLK = HSE * RCC_PLLMul_x
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_x);
//使能PLL
RCC_PLLCmd(ENABLE);
//等待PLL時鐘穩(wěn)定
while( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET );
//選擇系統(tǒng)時鐘 為PLL時鐘
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while( RCC_GetSYSCLKSource() != 0x08 );
}
else
{
// 故障后處理程序
}
}
HSI作為系統(tǒng)時鐘
void HSI_SetSysClk(uint32_t RCC_PLLMul_x) //時鐘為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);
//配置兩個等待周期
FLASH_SetLatency(FLASH_Latency_2);
//設(shè)置分頻因子
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
//配置鎖相環(huán)時鐘 PLLCLK = HSE * RCC_PLLMul_x
RCC_PLLConfig(RCC_PLLSource_HSI_Div2,RCC_PLLMul_x);
//使能PLL
RCC_PLLCmd(ENABLE);
//等待PLL時鐘穩(wěn)定
while( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET );
//選擇系統(tǒng)時鐘 為PLL時鐘
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while( RCC_GetSYSCLKSource() != 0x08 );
}
else
{
// 故障后處理程序
}
}