感觉硬件是固定的,软件才是千变万化的。现在几乎全部的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)- (RCC)中断优先级设置DMA 绑定(如 UART 使用 DMA)
这样可以让外设的逻辑初始化和硬件资源管理分开,提高代码的可维护性。不同的 STM32 芯片上,相同的外设实例可能连接到不同的引脚。例如:USART1- 在 STM32F103 可能是 PA9/PA10USART1
如果 HAL_UART_Init() 直接写死 GPIO 配置,移植到另一个芯片时,每次都要改外设的初始化代码,而分离 HAL_UART_MspInit() 后,只需要修改 MSP 层的 GPIO 配置即可。STM32 HAL 库的设计理念是 外设驱动尽可能独立于硬件接下来就是支持串口工作的更加底层的设置,HAL_UART_MspInit 函数是 STM32 HAL 库中的一个回调函数(Msp,即 MCU 支持包)。它用于初始化 UART 硬件相关的资源,如 GPIO、时钟、DMA 和 NVIC(中断控制器)。从这个图也可见一斑,所以外设要和外面沟通也是需要这里切换和复用的,小封装的MCU就是IO少,复用功能也少,只能做单一的功能,外设只是信号进来,至于电气层面的工作,还是要指定一下那是不是必须一个外设都要这样的设置呢?不一定,有些就不需要。ADC(模数转换器):只需将引脚配置为 GPIO_MODE_ANALOG(HAL 库会自动配置)(这里其实不对,应该是浮空输入的高阻模式)DAC(数模转换器):输出引脚通常配置为 GPIO_MODE_ANALOG- 如果是基本定时器(如 TIM6、TIM7),不需要 GPIO 配置
- 但如果是 PWM 输出(如 TIM1、TIM2),需要配置 PWM 引脚为 GPIO_MODE_AF_PP
- 但如果使用外部时钟源(LSE/LSI),则相关引脚可能需要配置
内部 Flash/EEPROM:访问存储器时不需要 GPIO 配置。
|