分享

ARM Cortex-M处理器HAL库的初始化设计

 云深无际 2025-03-02 发布于内蒙古
感觉硬件是固定的,软件才是千变万化的。现在几乎全部的M系列芯片都是模仿了STM32系列的HAL库设计方式。
在对待这个MCU的初始化上面,我突然有了一点新的感悟。
其实我们MCU在硬件的层面来说是分为两个部分,一个是对应的外设,一个是外设之下更加基础的IP。比如时钟,中断,IO的映射。
STM32 的 HAL(Hardware Abstraction Layer) 库采用分层设计:HAL 层(HAL_UART_Init, HAL_I2C_Init, HAL_TIM_PWM_Init 等)
负责配置外设的寄存器,如波特率、时钟源、数据格式等。
MSP 层(MCU Support Package,即 HAL_xxx_MspInit)
负责外设相关的 硬件资源管理,包括:
  1. GPIO 复用模式
  2. (AF 模式)时钟管理
  3. (RCC)中断优先级设置DMA 绑定(如 UART 使用 DMA)

这样可以让外设的逻辑初始化和硬件资源管理分开,提高代码的可维护性。
不同的 STM32 芯片上,相同的外设实例可能连接到不同的引脚。例如:USART1
  1.  在 STM32F103 可能是 PA9/PA10USART1
  2.  在 STM32F407 可能是 PB6/PB7

如果 HAL_UART_Init() 直接写死 GPIO 配置,移植到另一个芯片时,每次都要改外设的初始化代码,而分离 HAL_UART_MspInit() 后,只需要修改 MSP 层的 GPIO 配置即可。
STM32 HAL 库的设计理念是 外设驱动尽可能独立于硬件
所以我们的初始化其实就是这两个部分。
可以看到这就是外设的设置
接下来就是支持串口工作的更加底层的设置,HAL_UART_MspInit 函数是 STM32 HAL 库中的一个回调函数(Msp,即 MCU 支持包)。
它用于初始化 UART 硬件相关的资源,如 GPIO、时钟、DMA 和 NVIC(中断控制器)。
可以看到,里面其实只有串口的中断设置。
我们的GPIO就是和外界打交道的重要GATE,
从这个图也可见一斑,所以外设要和外面沟通也是需要这里切换和复用的,小封装的MCU就是IO少,复用功能也少,只能做单一的功能,
外设只是信号进来,至于电气层面的工作,还是要指定一下
这是IIC的
SPI的
那是不是必须一个外设都要这样的设置呢?不一定,有些就不需要。
ADC(模数转换器):只需将引脚配置为 GPIO_MODE_ANALOG(HAL 库会自动配置)(这里其实不对,应该是浮空输入的高阻模式
DAC(数模转换器):输出引脚通常配置为 GPIO_MODE_ANALOG
内部定时器(TIM)
  1. 如果是基本定时器(如 TIM6、TIM7),不需要 GPIO 配置
  2. 但如果是 PWM 输出(如 TIM1、TIM2),需要配置 PWM 引脚为 GPIO_MODE_AF_PP

RTC(实时时钟)
  1. 直接使用内部时钟,不需要 GPIO 配置
  2. 但如果使用外部时钟源(LSE/LSI),则相关引脚可能需要配置

内部 Flash/EEPROM:访问存储器时不需要 GPIO 配置。
关键还是看这个外设对物理信号的要求。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多