前一節詳細介紹了系統默認的時鍾配置,及各路時鍾輸出是多少,這是默認配置的,但實際使用的時鍾默認的時鍾並不符合要求,所以就得知道如何調用庫函數進行配置。
最好的資料就是查閱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()函數后。
串口打印的數據符合理論算的值,如下圖:
新手的話可能不會在意那些不用的時鍾關掉,但是在做項目上,考慮到低功耗時就的把不必要的時鍾進行關掉,節省電,還有當處於休眠狀態時,也可以考慮降低主時鍾,因頻率越快,越耗電。