1、STM32配置系統時鐘的步驟
1、系統時鐘配置步驟
先配置系統時鐘,后面的總線才能使用時鐘頻率
2、外設時鐘使能和失能
STM32為了低功耗,一開始是關閉了所有的外設的時鐘,所以外設想要工作,首先就要打開時鐘,所以后面在使用外設的時候必須先用這個宏打開相應的時鐘,比如打開GPIOA、ADC等外設的時鐘
3、sys_stm32_clock_init 函數(F1)
系統時鐘初始化函數
2、系統時鐘配置步驟
3、外設時鐘使能和失能
4、sys_stm32_clock_init 函數(F1)
HAL_RCC_OscConfig() //選擇時鐘源、配置PLL
HAL_RCC_ClockConfig() //選擇系統時鐘源,配置總線分頻器
//主要使用這兩個HAL庫函數實現系統時鐘配置
1、HAL_RCC_OscConfig()函數
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
參數含義
typedef struct
{ uint32_t OscillatorType; /* 選擇需要配置的振蕩器,比如選擇HSE高速外部時鐘 */ uint32_t HSEState; /* HSE 狀態 */ uint32_t HSEPredivValue; /* HSE 預分頻值 */ uint32_t LSEState; /* LSE 狀態 */ uint32_t HSIState; /* HSI狀態 */ uint32_t HSICalibrationValue; /* HSI 校準值 */ uint32_t LSIState; /* LSI 狀態,看門狗需要使用 */ RCC_PLLInitTypeDef PLL; /* PLL 結構體 */
}RCC_OscInitTypeDef;
PLL配置結構體
typedef struct
{ uint32_t PLLState; /* PLL 狀態 */ uint32_t PLLSource; /* PLL 時鐘源 */ uint32_t PLLMUL; /* PLL 倍頻系數 2-16倍頻 */
}RCC_PLLInitTypeDef;
2、HAL_RCC_ClockConfig函數(F1)
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
typedef struct
{ uint32_t ClockType; /* 要配置的時鐘(SYSCLK/HCLK/PCLK1/PCLK2) */ uint32_t SYSCLKSource; /* 系統時鐘源 */ uint32_t AHBCLKDivider; /* AHB 時鐘預分頻系數 */ uint32_t APB1CLKDivider; /* APB1 時鐘預分頻系數 */ uint32_t APB2CLKDivider; /* APB2 時鐘預分頻系數 */
}RCC_ClkInitTypeDef;
uint32_t FLatency #define FLASH_LATENCY_0 0x00000000U /* FLASH 0個等待周期 */
#define FLASH_LATENCY_1 FLASH_ACR_LATENCY_0 /* FLASH 1個等待周期 */
#define FLASH_LATENCY_2 FLASH_ACR_LATENCY_1 /* FLASH 2個等待周期 */
實際設置FLASH_ACR寄存器LATENCY位域,請參考《 STM32F10xxx閃存編程參考手冊.pdf 》3.1小節
程序舉例
1、先配置HSE_VALUE,先告訴HAL庫實際高速外部晶振是多少MHz的
可以看到HSE_VALUE 8000000U
其實就是8MHz,就是在HAL庫中寫明了8MHz的外部晶振頻率
2、在啟動文件.s中,在復位函數Reset_Handler
部分調用SystemInit
函數
3、調用HAL庫函數正式設置時鐘
/*** @brief 系統時鐘初始化函數* @param plln: PLL倍頻系數(PLL倍頻), 取值范圍: 2~16中斷向量表位置在啟動時已經在SystemInit()中初始化* @retval 無*/
void sys_stm32_clock_init(uint32_t plln)
{HAL_StatusTypeDef ret = HAL_ERROR;RCC_OscInitTypeDef rcc_osc_init = {0};RCC_ClkInitTypeDef rcc_clk_init = {0};rcc_osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSE; /* 選擇要配置HSE,也就是選擇高速外部時鐘振蕩器 */rcc_osc_init.HSEState = RCC_HSE_ON; /* 打開HSE */rcc_osc_init.HSEPredivValue = RCC_HSE_PREDIV_DIV1; /* HSE預分頻系數 */rcc_osc_init.PLL.PLLState = RCC_PLL_ON; /* 打開PLL */rcc_osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSE; /* PLL時鐘源選擇HSE */rcc_osc_init.PLL.PLLMUL = plln; /* PLL倍頻系數 */ret = HAL_RCC_OscConfig(&rcc_osc_init); /* 初始化 */if (ret != HAL_OK){while (1); /* 時鐘初始化失敗,之后的程序將可能無法正常執行,可以在這里加入自己的處理 */}/* 選中PLL作為系統時鐘源并且配置HCLK,PCLK1和PCLK2*/rcc_clk_init.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);rcc_clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; /* 設置系統時鐘來自PLL */rcc_clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1; /* AHB分頻系數為1 */rcc_clk_init.APB1CLKDivider = RCC_HCLK_DIV2; /* APB1分頻系數為2 */rcc_clk_init.APB2CLKDivider = RCC_HCLK_DIV1; /* APB2分頻系數為1 */ret = HAL_RCC_ClockConfig(&rcc_clk_init, FLASH_LATENCY_2); /* 同時設置FLASH延時周期為2WS,也就是3個CPU周期。 */if (ret != HAL_OK){while (1); /* 時鐘初始化失敗,之后的程序將可能無法正常執行,可以在這里加入自己的處理 */}
}