在 STM32F429 中,有 5 個最重要的時鍾源,為 HSI、 HSE、 LSI、 LSE、 PLL。
LSI 是低速內部時鍾, RC 振盪器,頻率為 32kHz 左右。供獨立看門狗和自動喚醒單元使用。
LSE 是低速外部時鍾,接頻率為 32.768kHz 的石英晶體。 這個主要是 RTC 的時鍾源。
HSE 是高速外部時鍾,可接石英/陶瓷諧振器,或者接外部時鍾源,頻率范圍為 4MHz~26MHz。
HSI 是高速內部時鍾, RC 振盪器, 頻率為 16MHz。 可以直接作為系統時鍾或者用作 PLL輸入。
如果外部晶振選擇 25MHz。同時我們設置相應的分頻器 M=25,倍頻器倍頻系數 N=360,分頻器分頻系數 P=2,那么主 PLL 生成的第一個輸出高速時鍾 PLLP 為:
PLL=25MHz * N/ (M*P)=25MHz* 360 /(25*2) = 180MHz 。
如果我們選擇 HSE 為 PLL 時鍾源,同時 SYSCLK 時鍾源為 PLL,那么 SYSCLK 時鍾為 180MHz。
1. 在“Template_0”文件夾下建立“Drivers”文件夾,用於存放驅動代碼
2. 在“Drivers”文件夾下新建“M429_SysTick.h”和"M429_SysTick.c" ,將"M429_SysTick.c"文件添加到“Drivers”分組中
3. 打開“Options for Target ‘Target 1’” => C/C++,添加“..\Drivers”為包含目錄
4. SystickInit函數定義:
1 int M429_SystickInit(uint32_t plln,uint32_t pllm,uint32_t pllp,uint32_t pllq) 2 { 3 HAL_StatusTypeDef ret = HAL_OK; 4 RCC_OscInitTypeDef RCC_OscInitStructure; 5 RCC_ClkInitTypeDef RCC_ClkInitStructure; 6 7 __HAL_RCC_PWR_CLK_ENABLE(); //使能PWR時鍾 8 9 //下面這個設置用來設置調壓器輸出電壓級別,以便在器件未以最大頻率工作 10 //時使性能與功耗實現平衡,此功能只有STM32F42xx和STM32F43xx器件有, 11 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);//設置調壓器輸出電壓級別1 12 13 RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_HSE; //時鍾源為HSE 14 RCC_OscInitStructure.HSEState=RCC_HSE_ON; //打開HSE 15 RCC_OscInitStructure.PLL.PLLState=RCC_PLL_ON;//打開PLL 16 RCC_OscInitStructure.PLL.PLLSource=RCC_PLLSOURCE_HSE;//PLL時鍾源選擇HSE 17 RCC_OscInitStructure.PLL.PLLM=pllm; //主PLL和音頻PLL分頻系數(PLL之前的分頻),取值范圍:2~63. 18 RCC_OscInitStructure.PLL.PLLN=plln; //主PLL倍頻系數(PLL倍頻),取值范圍:64~432. 19 RCC_OscInitStructure.PLL.PLLP=pllp; //系統時鍾的主PLL分頻系數(PLL之后的分頻),取值范圍:2,4,6,8.(僅限這4個值!) 20 RCC_OscInitStructure.PLL.PLLQ=pllq; //USB/SDIO/隨機數產生器等的主PLL分頻系數(PLL之后的分頻),取值范圍:2~15. 21 ret=HAL_RCC_OscConfig(&RCC_OscInitStructure);//初始化 22 23 if(ret!=HAL_OK) while(1); 24 25 ret=HAL_PWREx_EnableOverDrive(); //開啟Over-Driver功能 26 if(ret!=HAL_OK) while(1); 27 28 //選中PLL作為系統時鍾源並且配置HCLK,PCLK1和PCLK2 29 RCC_ClkInitStructure.ClockType=(RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2); 30 RCC_ClkInitStructure.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;//設置系統時鍾時鍾源為PLL 31 RCC_ClkInitStructure.AHBCLKDivider=RCC_SYSCLK_DIV1;//AHB分頻系數為1 32 RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV4; //APB1分頻系數為4 33 RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV2; //APB2分頻系數為2 34 ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_5);//同時設置FLASH延時周期為5WS,也就是6個CPU周期。 35 36 if(ret!=HAL_OK) while(1); 37 38 return ret; 39 }
5. 使用 HAL 庫配置 STM32F429 時鍾系統的一般步驟:
5.1 使能 PWR 時鍾
1 __HAL_RCC_PWR_CLK_ENABLE(); //使能PWR時鍾
之所以要使能 PWR 時鍾,是因為后面的步驟中“設置調節器輸出電壓級別”以及“開啟 Over-Driver 功能”都是電源控制相關配置,所以必須開啟 PWR 時鍾 。
5.2 設置調壓器輸出電壓級別
1 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);//設置調壓器輸出電壓級別1
調壓器輸出電壓級別 VOS,它是由 PWR->CR 的位 15:14 來確定的:
如果希望系統時鍾為180M,則需要設置電壓級別1,且開啟 Over-Driver 功能。
5.3 初始化RCC振盪器
1 RCC_OscInitStructure.OscillatorType=RCC_OSCILLATORTYPE_HSE; //時鍾源為HSE 2 RCC_OscInitStructure.HSEState=RCC_HSE_ON; //打開HSE 3 RCC_OscInitStructure.PLL.PLLState=RCC_PLL_ON;//打開PLL 4 RCC_OscInitStructure.PLL.PLLSource=RCC_PLLSOURCE_HSE;//PLL時鍾源選擇HSE 5 RCC_OscInitStructure.PLL.PLLM=pllm; //主PLL和音頻PLL分頻系數(PLL之前的分頻),取值范圍:2~63. 6 RCC_OscInitStructure.PLL.PLLN=plln; //主PLL倍頻系數(PLL倍頻),取值范圍:64~432. 7 RCC_OscInitStructure.PLL.PLLP=pllp; //系統時鍾的主PLL分頻系數(PLL之后的分頻),取值范圍:2,4,6,8.(僅限這4個值!) 8 RCC_OscInitStructure.PLL.PLLQ=pllq; //USB/SDIO/隨機數產生器等的主PLL分頻系數(PLL之后的分頻),取值范圍:2~15. 9 ret=HAL_RCC_OscConfig(&RCC_OscInitStructure);//初始化 10 11 if(ret!=HAL_OK) while(1);
5.4 選擇開啟 Over-Driver 功能。
1 ret=HAL_PWREx_EnableOverDrive(); //開啟Over-Driver功能 2 if(ret!=HAL_OK) while(1);
5.5 初始化CPU,AHB和APB總線時鍾。
1 //選中PLL作為系統時鍾源並且配置HCLK,PCLK1和PCLK2 2 RCC_ClkInitStructure.ClockType=(RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2); 3 RCC_ClkInitStructure.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;//設置系統時鍾時鍾源為PLL 4 RCC_ClkInitStructure.AHBCLKDivider=RCC_SYSCLK_DIV1;//AHB分頻系數為1 5 RCC_ClkInitStructure.APB1CLKDivider=RCC_HCLK_DIV4; //APB1分頻系數為4 6 RCC_ClkInitStructure.APB2CLKDivider=RCC_HCLK_DIV2; //APB2分頻系數為2 7 ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_5);//同時設置FLASH延時周期為5WS,也就是6個CPU周期。 8 9 if(ret!=HAL_OK) while(1);