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
相关推荐
G***技几秒前
杰和IB3-272:以低功耗高性能打造新一代工业智能交互核心
单片机·嵌入式硬件·物联网
czhaii1 小时前
STC AI8052U单片机特点
单片机
MAR-Sky1 小时前
keil5中数据的不同定义和单片机(以stc8为例)里的对应关系(idata,xdata,data,code)
单片机·嵌入式硬件
项目題供诗3 小时前
51单片机入门(八)
单片机·嵌入式硬件·51单片机
羽获飞4 小时前
从零开始学嵌入式之STM32——9.STM32的时钟系统
stm32·单片机·嵌入式硬件
飞睿科技4 小时前
乐鑫智能开关方案解析:基于ESP32-C系列的低功耗、高集成设计
嵌入式硬件·物联网·esp32·智能家居·乐鑫科技
来自晴朗的明天5 小时前
13、NMOS 电源防反接电路
单片机·嵌入式硬件·硬件工程
17(无规则自律)6 小时前
深入浅出 Linux 内核模块,写一个内核版的 Hello World
linux·arm开发·嵌入式硬件
芯岭技术6 小时前
PY32MD310单片机:高性能、低功耗的32位电机控制微控制器
单片机·嵌入式硬件
wotaifuzao7 小时前
STM32 + FreeRTOS 的订阅通知组件架构
stm32·嵌入式硬件·架构·freertos·事件驱动·嵌入式架构