STM32的時鐘簡介和配置方法

STM32的時鐘簡介:

STM32中使用任何一個外設都必須打開相應的時鐘。在STM32中有5個時鐘源可供用戶選擇:

1.HSI高速內部時鐘,RC震盪器,頻率爲8MHz。

2.HSE高速外部時鐘,右英/陶瓷諧振器,或着外部時鐘源,4MHz-16MHz.

3.LSI內部低速時鐘,RC震盪器頻率爲40Hz。

4.LSE外部低速時鐘,接頻率爲32.768KHz的石英晶體。

5.PLL鎖相環頻輸出,時鐘源可選爲HIS/2、HSE或HSE/2。倍頻可選2-16倍,但其輸出頻率最大不能超過72MHz。

系統時鐘SYSCLK,它是供STM32中絕大部分器件工作的時鐘源,系統時鐘可選擇爲PLL輸出、HSI或者HSE。系統時鐘的做大頻率爲72MHz,它通過AHB分頻器分頻後送給個模塊使用,AHB分頻器可選擇1、2...512分頻。AHB分頻器輸出的時鐘送給5大模塊使用:

1.送給AHB總線、內核、內存、DMA使用的HCLK時鐘。

2.通過8分頻送給系統定時器的定時時鐘(嘀嗒定時器)。

3.直接送給Cortex的空閒時鐘PCLK。

4.送給APB1分頻器可選擇1、2、4、8、16分頻,其輸出一路供APB1外設使用(PCLK1,最大頻率36M)另一路送給定時器(Timer)2、3、4倍頻器使用。該倍頻器可選擇1或着2倍頻,時鐘輸出供定時器2、3、4使用。

5.送給APB2分頻器可選擇1、2、4、8、16分頻,其輸出一路供APB2外設使用(PCLK2,最大頻率72M)另一路送給定時器(Timer)1倍頻器使用。該倍頻器可選擇1或着2倍頻。時鐘輸出供定時器1使用。另外,APB2分頻器還有一路輸出供ADC分頻器使用,分頻後送給ADC模塊使用。ADC分頻器可選 擇爲2、4、6、8分頻。

連接在APB1(低速外設)上設備有:電源接口、備份接口、CAN、USB、I2C1、I2C2、UART2、UART3、SPI2、窗口看門狗、TIMER2、TIMER3、TIMER4。

連接在APB2(高速外設)上設備有:UART1、SPI1、Timer1、ADC1、ADC2、所有普通IO口、第二功能IO口。


涉及的寄存器:
RCC 寄存器結構,RCC_TypeDeff,在文件“stm32f10x_map.h”中定義如下: 
typedef struct 

vu32 CR;                  //HSI,HSE,CSS,PLL等的使能 
vu32 CFGR;              //PLL等的時鐘源選擇以及分頻係數設定
vu32 CIR;                // 清除/使能 時鐘就緒中斷
vu32 APB2RSTR;      //APB2線上外設復位寄存器
vu32 APB1RSTR;      //APB1線上外設復位寄存器
vu32 AHBENR;         //DMA,SDIO等時鐘使能
vu32 APB2ENR;       //APB2線上外設時鐘使能
vu32 APB1ENR;      //APB1線上外設時鐘使能
vu32 BDCR;           //備份域控制寄存器
vu32 CSR;            
} RCC_TypeDef;


在ST公司的外設固件庫的示例裏,對於工程項目文件,ST並沒有在啓動函數main()裏初始化PLL,因爲其已經在硬件初始化階段完成對系統時鐘的配置。這樣也就帶了一個問題,ST庫裏的均使用了外設8MHz的晶振,而我們平時的項目就一定採用的是這個頻率,實際配置的低於8MHz,MCU不能全速運行,高於8MHz,外設時鐘即配置失敗,甚至無法運行。那麼如何重新配置時鐘就需要我們重新設計了。


以下爲使用庫函數重新編寫了STM32F系統時鐘PLL初始化過程:

以下的函數需要添加#include "stm32f10x.h"的頭文件來調用ST固件庫。
static void SysClockInit(void)
{
RCC_DeInit();/* RCC重置 */
RCC_HSEConfig(RCC_HSE_ON); /*(使能HSE)*/
HSEStartUpStatus = RCC_WaitForHSEStartUp();/*(等待HSE使能結束)*/
if (HSEStartUpStatus == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1); /* 配置HCLK = SYSCLK */
RCC_PCLK2Config(RCC_HCLK_Div1); /* 配置PCLK2 = HCLK */
RCC_PCLK1Config(RCC_HCLK_Div2); /* 配置PCLK1 = HCLK/2 */
/* 超級重要的、需要配置的地方在這裏 */
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); /* RCC_PLLSource_HSE_Div1爲外置晶振的分頻係數;RCC_PLLMul_9爲倍頻數 */
RCC_PLLCmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* 選定PLL爲系統主時鐘 */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
else
{ /* 配置失敗將程序停留在這裏 */
while (1)
{
}
}
}

發佈了20 篇原創文章 · 獲贊 22 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章