STM32F2系列時鍾的配置


前一節詳細介紹了系統默認的時鍾配置,及各路時鍾輸出是多少,這是默認配置的,但實際使用的時鍾默認的時鍾並不符合要求,所以就得知道如何調用庫函數進行配置。

最好的資料就是查閱stm32f2xx_rcc.c文件,里面有各種功能函數,並有詳細的注釋,這讓我們這樣的新手上手是非常快的。

//VCO = PLL input clock(HSE or HSI)/PLLM
//倍頻電壓后值V =  VCO * PLLN
//sysclk = V / PLLP
//PLL48CK = V / PLLQ
#define PLLM                                 25  //分頻因子
#define PLLN                                 240 //倍頻因子
#define PLLP                                2   //分頻因子
#define PLLQ                                5   //分頻因子

vu16 ADC_ConvertedValue[2]; //定義數組,存放PA6和PA7的轉換后的數據
float PA6_AD_value; //壓力傳感器
float PA7_AD_value; //鋰電池電壓

void Delay(__IO uint32_t nCount);
void SetClock(void);
int CheckDatas(void);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
    unsigned  int  i = 0;
    RCC_ClocksTypeDef rcc_clocks;
    
    SetClock();
    USART_Config();
    RCC_GetClocksFreq(&rcc_clocks);
    
    printf("\r\nSYSCLK_Frequency = %d MHz\n",rcc_clocks.SYSCLK_Frequency/1000000);
    printf("\r\nHCLK_Frequency = %d MHz\n",rcc_clocks.HCLK_Frequency/1000000);
    printf("\r\nPCLK1_Frequency = %d MHz\n",rcc_clocks.PCLK1_Frequency/1000000);
    printf("\r\nPCLK2_Frequency = %d MHz\n",rcc_clocks.PCLK2_Frequency/1000000);
  

上面是main函數部分代碼,時鍾設置SetClock()函數,設置完后,可以調用庫函數RCC_GetClockFreq(&rcc_clocks)進行查閱配置的時鍾是否正確。在使用該函數前,定義一個RCC_ClockTypeDef rcc_clocks結構變量,通過參數傳遞,就可以訪問到RCC_ClockTypeDef里的結構成員變量。


接下來介紹SetClocks()函數,直接看中文注釋

void SetClock(void)
{
    RCC_DeInit();//復位系統所有配置時鍾
//    RCC_HSICmd(DISABLE); //RCC_DeInit()后,HSI作為系統時鍾,在這調用是不生效的
    RCC_LSICmd(DISABLE);//關閉內部低速時鍾
    RCC_PLLI2SCmd(DISABLE);//關閉PLLI2S Clock
    RCC_RTCCLKCmd(DISABLE);//disables the RTC clock
    
    RCC_HSEConfig(RCC_HSE_ON);//外部時鍾使能
    while(!RCC_WaitForHSEStartUp());//Waits for HSE start-up
    
    RCC_PLLConfig(RCC_PLLSource_HSE, PLLM, PLLN, PLLP, PLLQ);//配置PLL時鍾
    RCC_PLLCmd(ENABLE);  //PLL時鍾使能
    while((RCC->CR & RCC_CR_PLLRDY) == 0);//等待PLL 時鍾准備好
    
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//PLL CLK 作為系統時鍾 sysclk =120M
    RCC_HSICmd(DISABLE);//關閉內部高速時鍾,如果內部高速時鍾作為系統時鍾,此函數不生效
    RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB = SYSCLK 不分頻 120M
    RCC_PCLK1Config(RCC_HCLK_Div4);  //PCLK1 4分頻 = 30M
    RCC_PCLK2Config(RCC_HCLK_Div2);  //PCLK2 2分頻 = 60M
}

這里注意的是HSE時鍾使能不是用RCC_HSECmd(ENABLE)這樣的函數,而是使用的是RCC_HSEConfig(RCC_HSE_ON),使能后一定要等待HSE start-up,
同樣PLL使能后,也要等待一會,配置時鍾時最好按照時鍾樹結構進行設置,先什么在配置什么,然后PLL時鍾先配置在使能,注意一下順序。

還要注意一個地方,當不需要內部高速時鍾時,使用RCC_HSICmd(DISABLE),不能隨調用,可以查看該函數的注釋,就是說“如果內部高速時鍾作為系統時鍾時,該時鍾不能停止”也就是說當該時鍾作為系統時鍾時,調用該函數是無效的,而使用RCC_DeInit()后,內部高速時鍾就是作為了系統時鍾,所以該函數放置在RCC_SYSCLKConfig()函數后。

串口打印的數據符合理論算的值,如下圖:

新手的話可能不會在意那些不用的時鍾關掉,但是在做項目上,考慮到低功耗時就的把不必要的時鍾進行關掉,節省電,還有當處於休眠狀態時,也可以考慮降低主時鍾,因頻率越快,越耗電。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM