STM32L475基于HAL库封装时钟管理模块

创建基于HAL库的空项目

为了更贴近实际生产的项目结构, 修改项目目录结构

创建目录结构如下:

复制代码
├─Drivers ----------------------------- 官方HAL库, SMSIS启动文件等
│  ├─CMSIS
│  │  └─Include
│  └─STM32L4xx_HAL_Driver ------------- HAL库
│      ├─Inc
│      └─Src
├─Inc  -------------------------------- 应用头文件
├─MDK-ARM ----------------------------- Keil工程及编译中间文件
└─Src --------------------------------- 应用源文件
拷贝文件

From:
stm32cubel4_v1-18-0\STM32Cube_FW_L4_V1.18.0\Drivers\CMSIS\Include

拷贝整个Include文件夹

To:
Test04\Drivers\CMSIS\Include


From:
stm32cubel4_v1-18-0\STM32Cube_FW_L4_V1.18.0\Drivers\CMSIS\Device\ST\STM32L4xx\Include

在这个目录下拷贝如下3个文件

复制代码
stm32l4xx.h
stm32l475xx.h
system_stm32l4xx.h

To:
Test04\Drivers\CMSIS\Include


From:
stm32cubel4_v1-18-0\STM32Cube_FW_L4_V1.18.0\Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\arm\startup_stm32l475xx.s

To:
Test04\Drivers\CMSIS\Include


From:
stm32cubel4_v1-18-0\STM32Cube_FW_L4_V1.18.0\Drivers\STM32L4xx_HAL_Driver\Inc
stm32cubel4_v1-18-0\STM32Cube_FW_L4_V1.18.0\Drivers\STM32L4xx_HAL_Driver\Src

Inc和Src目录整体拷贝

To:
Test04\Drivers\STM32L4xx_HAL_Driver


From:
stm32cubel4_v1-18-0\STM32Cube_FW_L4_V1.18.0\Drivers\CMSIS\Device\ST\STM32L4xx\Source\Templates\system_stm32l4xx.c

To:

重命名为 stm32l4xx_hal_conf.h
Test05\Inc\stm32l4xx_hal_conf.h


From:
stm32cubel4_v1-18-0\STM32Cube_FW_L4_V1.18.0\Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_conf_template.h

To:
Test05\Inc\stm32l4xx_hal_conf.h

编写代码

stm32-world\Test04\Inc\main.h

c 复制代码
#ifndef MAIN_H
#define MAIN_H

#ifdef __cplusplus
extern "C" {
#endif

#include "stm32l4xx_hal.h"


#ifdef __cplusplus
}
#endif

#endif

stm32-world\Test04\Src\main.c

c 复制代码
#include "main.h"

int main(void) {
    HAL_Init();           // 1. 初始化HAL库(配置SysTick等)
    
    while (1) {
        
    }
}

stm32-world\Test04\Inc\stm32l4xx_it.h

c 复制代码
#ifndef __STM32L4xx_IT_H
#define __STM32L4xx_IT_H

#ifdef __cplusplus
 extern "C" {
#endif

/* 核心:SysTick 中断,每 1ms 触发一次,用于 HAL_Delay() */
void SysTick_Handler(void);

#ifdef __cplusplus
}
#endif

#endif /* __STM32L4xx_IT_H */

stm32-world\Test04\Src\stm32l4xx_it.c

c 复制代码
#include "stm32l4xx_it.h"
#include "stm32l4xx_hal.h"

void SysTick_Handler(void) {
    HAL_IncTick(); // 每1ms触发一次,增加HAL计数值
}

系统时钟初始化

使用HAL库实现前文:
STM32L475基于完全空白的项目,完成时钟树初始化配置并验证

同样的操作.

bsp_clock.c

c 复制代码
#include "bsp_clock.h"
#include "stm32l4xx_hal.h"
#include "stm32l4xx_hal_rcc.h"
#include "stm32l4xx_hal_pwr.h"
#include "stm32l4xx_hal_flash.h"

/**
 * @brief 系统时钟 HSE (8MHz) -> PLL -> 80MHz
 */
void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    /* 1. 配置主调压器输出电压以支持 80MHz 频率 (Range 1) */
    __HAL_RCC_PWR_CLK_ENABLE();
    
    if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) {
        // TODO:: 错误处理
        // Error_Handler();
    }

    /* 2. 配置 HSE 并初始化 PLL */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; // 选择晶振类型为外部高速晶振
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;                   // 开启外部晶振
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;               // 开启PLL锁相环
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;       // PLL时钟源为外部晶振

    /* 8MHz(HSE) / 1(M) * 20(N) / 2(R) = 80MHz */
    RCC_OscInitStruct.PLL.PLLM = 1;
    RCC_OscInitStruct.PLL.PLLN = 20;
    RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
    RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;

    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
        // TODO:: 错误处理
        // Error_Handler();
    }

    /* 3. 配置系统时钟源 (SYSCLK) 及总线分频 */
    RCC_ClkInitStruct.ClockType =   RCC_CLOCKTYPE_HCLK
                                  | RCC_CLOCKTYPE_SYSCLK
                                  | RCC_CLOCKTYPE_PCLK1
                                  | RCC_CLOCKTYPE_PCLK2;      // 指定分频操作所覆盖的总线类型
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 选择PLL为主时钟

    // 显式地设置AHB和APB预分频器对应的总线频率
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;   // 80MHz
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;    // 80MHz
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;    // 80MHz

    /* 4. 设置 Flash 等待周期 */
    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
    {
        // TODO:: 错误处理
        // Error_Handler();
    }
    
}

上述代码需要注意的是, 引入头文件时有顺序要求, 先引入stm32l4xx_hal.h, 然后再引入其他, 否则会报编译错误.

bsp_clock.h

c 复制代码
#ifndef __BSP_CLOCK_H
#define __BSP_CLOCK_H

void SystemClock_Config(void);

#endif
相关推荐
惶了个恐16 分钟前
嵌入式硬件第一弹——51单片机(1)
单片机·嵌入式硬件·51单片机
电子工程师成长日记-C511 小时前
51单片机语音实时采集系统
单片机·嵌入式硬件·51单片机
csaaa20051 小时前
STM32F103 开发USB设备端点超过ENDP4以上时崩溃问题的解决
stm32·单片机·嵌入式硬件
liefyuan1 小时前
【设备树】SDIO节点属性
单片机·嵌入式硬件
LCG元2 小时前
故障预测与健康管理:STM32G4监控自身参数,早期预警
stm32·单片机·嵌入式硬件
ipod7412 小时前
STM32 GPIO控制器及其应用
stm32·单片机·嵌入式硬件
逐步前行2 小时前
STM32_USART_串口通信
stm32·单片机·嵌入式硬件
我不是程序猿儿2 小时前
【嵌入式】趣味理解“volatile”
stm32·单片机·嵌入式硬件·学习
謓泽2 小时前
【51单片机】DS18B20温度传感器(1-Wire)
单片机·嵌入式硬件·51单片机
F137298015572 小时前
220V降5V,100MA非隔离离线恒压稳压器WD5202A
stm32·单片机·嵌入式硬件·51单片机