目录
1.认识时钟树
1.1什么时钟
1.2认识时钟树
2.配置系统时钟
2.1系统适中的配置过程
2.2外设时钟使能和失能
2.3sys_stm32_clock_init函数(F407)
2.4SystemClock_Config函数(F407)
[F1]
[F4]
1.认识时钟树
1.1什么时钟
简单来说,时钟就是具有周期性的脉冲信号,最常用的是占空比为50%的方波。
时钟是单片机的脉搏,搞懂时钟走向及其关系,对单片机使用至关重要。
1.2认识时钟树
[F103]
[F407]
2.配置系统时钟
2.1系统适中的配置过程
- 配置HSE_VALUE,告诉HAL库外部晶振频率,stm32xxxx_hal_conf.h
- 调用SystemInit()函数(可选),在启动文件中调用,在system_stm32xxxx.c定义
- 选择时钟源,配置PLL,通过HAL_RCC_OscConfig()函数设置
- 选择系统时钟源,配置总线分频器,通过HAL_RCC_ClockConfig()函数设置
- 配置扩展外设时钟(可选),通过HAL_RCCx_PeriphCLKConfig()函数
3 + 4 + 5 = sys_stm32_clock_init()
2.2外设时钟使能和失能
我们要使用某个外设时,必须先要使能该外设时钟!!!!
HAL库使能某个外设时钟的方法,如:
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟 __HAL_RCC_GPIOA_CLK_DISABLE(); //禁止GPIOA时钟
2.3sys_stm32_clock_init函数(F4)
1.HAL_RCC_OscConfig()函数
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); typedef struct { uint32_t OscillatorType; //选择需要配置的振荡器 uint32_t HSEState; //HSE状态 uint32_t LSEState; //HSE预分频值 uint32_t HSIState; //LSE状态 uint32_t HSICalibrationValue; //LSE校准微调值,范围0x0~0x1F uint32_t LSIState; //LSI状态 RCC_PLLInitTypeDef PLL; //PLL结构体 }RCC_OscInitTypeDef; typedef struct { uint32_t PLLState; //PLL状态 uint32_t PLLSource; //PLL时钟源 uint32_t PLLM; //PLL倍频系数 uint32_t PLLN; //PLL倍频系数N uint32_t PLLP; //PLL分频系数P uint32_t PLLQ; //PLL分频系数系数 }RCC_PLLInitTypeDef;
2.HAL_RCC_ClockConfig函数
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 FLASH_ACR_LATENCY_0WS /* FLASH 0个等待周期 */ #define FLASH_LATENCY_1 FLASH_ACR_LATENCY_1WS /* FLASH 1个等待周期 */ #define FLASH_LATENCY_2 FLASH_ACR_LATENCY_2WS /* FLASH 2个等待周期 */ ... #define FLASH_LATENCY_15 FLASH_ACR_LATENCY_15WS /* FLASH 15个等待周期 */
2.3SystemClock_Config函数(F407)
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}