在使用HAL库开发的过程中,必不可少的就是时钟的相关配置,通过STM32CubeMx可以看到,对于单片机来说,(至少在我看来)使用较多的为外部的高速时钟,可以让我们单片机内部的相关外设更加快速的运行。
下面开始配置时钟树
在存放驱动程序的文件夹中新建一个名为sys的文件夹,包含一个.c文件和一个.h文件,在工程中添加.c文件
包含所在的文件夹路径
在sys.c 文件中写入#include "sys.h",使其包含进去,编译一定会有错误,无需担心,只要sys.h文件被包含进去就行
在sys.h文件中写入以下代码
stm32f1xx.h是所有的f1系列的顶层头文件,通过条件编译来包含某个芯片的头文件,定义通用的枚举类型,定义通用的宏定义
下面的就是我们要编写的时钟数的函数名称(需要一个变量)
然后我们就在sys.c文件里面编写所需要的代码
先把标准代码放在下面
#include "sys.h"
void 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;
rcc_osc_init.HSEState = RCC_HSE_ON;
rcc_osc_init.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
rcc_osc_init.PLL.PLLState = RCC_PLL_ON;
rcc_osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSE;
rcc_osc_init.PLL.PLLMUL = plln;
ret = HAL_RCC_OscConfig(&rcc_osc_init);
if (ret != HAL_OK)
{
while(1);
}
rcc_clk_init.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
rcc_clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
rcc_clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1;
rcc_clk_init.APB1CLKDivider = RCC_HCLK_DIV2;
rcc_clk_init.APB2CLKDivider = RCC_HCLK_DIV1;
ret = HAL_RCC_ClockConfig(&rcc_clk_init, FLASH_LATENCY_2);
if (ret != HAL_OK)
{
while(1);
}
}
上面的函数配置的是外部时钟的开始部分
这个配置的是中间部分
第一个函数配置如下:
定义一个函数来接收HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)的返回值
返回值的取值范围:
再定义一个该变量(结构体)的初始值
RCC_OscInitTypeDef rcc_osc_init = {0};
这个变量是一个结构体
这个结构体的相关注释
typedef struct
{
// 要配置的振荡器类型,取值参考 @ref RCC_Oscillator_Type
uint32_t OscillatorType;
#if defined(STM32F105xC) || defined(STM32F107xC)
// Prediv1 的源值,取值参考 @ref RCCEx_Prediv1_Source
uint32_t Prediv1Source;
#endif /* STM32F105xC || STM32F107xC */
// 外部高速时钟(HSE)的新状态,取值参考 @ref RCC_HSE_Config
uint32_t HSEState;
// 外部高速时钟的预分频因子值,在参考手册中可能被命名为 PREDIV1 或 PLLXTPRE,取值参考 @ref RCCEx_Prediv1_Factor
uint32_t HSEPredivValue;
// 外部低速时钟(LSE)的新状态,取值参考 @ref RCC_LSE_Config
uint32_t LSEState;
// 内部高速时钟(HSI)的新状态,取值参考 @ref RCC_HSI_Config
uint32_t HSIState;
// 内部高速时钟的校准微调值,默认值可能是 RCC_HSICALIBRATION_DEFAULT,取值范围在 0x00 到 0x1F 之间
uint32_t HSICalibrationValue;
// 内部低速时钟(LSI)的新状态,取值参考 @ref RCC_LSI_Config
uint32_t LSIState;
// 用于配置锁相环(PLL)的相关参数
RCC_PLLInitTypeDef PLL;
#if defined(STM32F105xC) || defined(STM32F107xC)
// 用于配置第二个锁相环(如果存在的话)的参数
RCC_PLL2InitTypeDef PLL2;
#endif /* STM32F105xC || STM32F107xC */
} RCC_OscInitTypeDef;
这表我们只给HSE(外部高速时钟)进行相关配置
各个配置的取值:
我就不一一列举了
同样的操作,我们再配置另外一个函数:
再进行相同的配置就行
上面的两个if函数都是if(ret!=HAL_OK),是因为我们上面对HAL_StatusTypeDef ret赋予了HAL_ERROR的初值,所以在这边用!=HAL_OK
这些函数的配置很好理解,都是围绕着配置外部高速时钟来进行的,我们不需要去配置其他的时钟函数