|
从寄存器操作到硬件抽象层:STM32开发库的演进。 演进历程STM32微控制器自2007年推出以来,STMicroelectronics为其提供了多套软件开发库,经历了从直接寄存器操作到高度抽象化的演进过程: 发展时间线
抽象层次中等高低 代码体积中等大小 执行效率高中等高 学习难度中等低高 可移植性低高中等/ Q, R+ _! ?9 p 维护状态已停止活跃活跃 工具支持无CubeMXCubeMX标准外设库(SPL)设计理念 SPL采用"一个外设一个文件"的设计理念,每个外设都有对应的.c和.h文件,提供中等层次的抽象。 核心特点// SPL典型用法示例$ v5 H/ `) H3 h" }- a# xvoid GPIO_Config(void)9 Q- H# G" r7 h, p { GPIO_InitTypeDef GPIO_InitStructure; // 使能GPIO时钟. V& _5 f+ J$ @9 ~. `6 j X* s7 D, D RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);+ {9 X2 A3 T' u0 X, m* W // 配置GPIO/ E/ E' ]8 i( j' O# s GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;0 {2 k% w1 G* J2 D" W; _2 p GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;) S) {, o0 \9 t9 Q% m) x GPIO_Init(GPIOA, &GPIO_InitStructure); }优势
HAL库采用"硬件抽象层"设计,旨在提供跨系列的统一API接口,隐藏硬件细节。 核心特点// HAL库典型用法示例void GPIO_Config(void) {# i5 S- H- k! \* f; f GPIO_InitTypeDef GPIO_InitStruct = {0}; ! Y- a5 |# T3 w5 }, W# g% w // 使能GPIO时钟 __HAL_RCC_GPIOA_CLK_ENABLE();" b: h$ ?+ D: i1 ~! t & D# B, E7 `* e' z* F3 S // 配置GPIO GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;7 {3 q! O8 z* `# U5 Q& H GPIO_InitStruct.Pull = GPIO_NOPULL;: V" H3 b- n. X8 |/ S8 x GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);0 H: ^' a9 X, p& z; p* B/ g2 U }架构优势
LL库是HAL库的补充,提供更接近硬件的接口,同时保持一定的可移植性。 核心特点// LL库典型用法示例void GPIO_Config(void)8 R( [* U; m" B( r8 u( f3 J { // 使能GPIO时钟9 Q1 f# f" @0 A LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);+ p# ~/ t; |4 f4 o + {* P L; c% C // 配置GPIO* Z# A7 ~ G! C4 R LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_5, LL_GPIO_MODE_OUTPUT); LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_5, LL_GPIO_OUTPUT_PUSHPULL);. j8 {5 E2 D ?8 z5 y LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_5, LL_GPIO_SPEED_FREQ_HIGH); }优势
{ USART_InitTypeDef USART_InitStructure;) k, q6 }. C& M# W GPIO_InitTypeDef GPIO_InitStructure;$ R! z$ {& M, |( [8 C( ?; u # t- D! O" Q( @ // 使能时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);7 O* w" s$ l0 D/ j% ^ " A$ \+ i' b! R( E- P! W V( ? // 配置GPIO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // TX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;' R ?2 w: _- i) e) K3 O GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // RX* ]' L: D4 `( }* |3 a* g GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure);/ [( H8 Y9 G0 f& q5 O $ b" [7 S8 T7 o2 ?0 ? { // 配置UART USART_InitStructure.USART_BaudRate = 115200;7 t: O# H6 }4 ?3 J8 l- H% Z( Z USART_InitStructure.USART_WordLength = USART_WordLength_8b;0 e, m- ~& M& \* o- f3 R USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No;3 X5 L, R( n1 _% O0 @ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;9 w2 P% x+ Z' u USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;- M. k/ t7 x' r" X2 A% M USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE);+ y- s1 {6 \ q) x! _# O: w2 ^6 J }& f9 n1 c% p! d! ?7 O" G voidUART_SendString(char* str) { while(*str) { while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); USART_SendData(USART1, *str++);4 s( ]/ Z; F% I) ^$ [( Z j }5 r' R, ~9 i$ b6 T8 z+ M( t; S" h }HAL方式void UART_Config(void) { GPIO_InitTypeDef GPIO_InitStruct = {0};/ N& }: ~( ?& q8 q/ p- B% }- W, N ) J. u& T1 u& B6 R // 使能时钟 __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); // 配置GPIO3 q8 a$ k) T2 Z! G* R8 [2 E GPIO_InitStruct.Pin = GPIO_PIN_9;4 T9 g0 I& q# w' v! O% X2 \. D' g GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);7 X! z4 ~- r- u/ U7 T( N # O, ^' _3 P) R6 z) I8 A" N GPIO_InitStruct.Pin = GPIO_PIN_10;8 ]! d2 S& p7 r K5 K0 G, A' g GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);$ u+ q9 N0 y) M* i$ k4 d // 配置UART+ `- b: J4 t: T. E4 @- ]; G" O. W huart1.Instance = USART1; huart1.Init.BaudRate = 115200;, ?5 W9 F% f4 A6 Z2 U( _1 ]4 N huart1.Init.WordLength = UART_WORDLENGTH_8B;" B; M+ H' M7 f5 [. f huart1.Init.StopBits = UART_STOPBITS_1;. `! J( @6 c8 Z$ D; i1 V# k huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX;' w& Z/ v/ D- q9 I huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart1); } voidUART_SendString(char* str) {" B* s( P$ R: b HAL_UART_Transmit(&huart1, (uint8_t*)str, strlen(str), HAL_MAX_DELAY); }LL方式void UART_Config(void) {/ S- K+ r5 S8 [ X8 }; A/ w3 T j // 使能时钟& F( V: d/ V+ M: r7 \6 A LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);) k1 B+ y. p$ g LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);# c8 e9 W% c8 Q: y* U$ i1 x. c) f // 配置GPIO1 p) U* H- t. C! r LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_9, LL_GPIO_MODE_ALTERNATE);! R( B/ M/ q6 {4 w3 n8 }, |3 c LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_9, LL_GPIO_AF_7); LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_9, LL_GPIO_SPEED_FREQ_HIGH);; ?. I' F! E J8 | LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_10, LL_GPIO_MODE_ALTERNATE);' {/ Y% b! }+ g5 a# X9 o1 K7 t LL_GPIO_SetAFPin_8_15(GPIOA, LL_GPIO_PIN_10, LL_GPIO_AF_7);+ r/ `, h2 j/ ~; K // 配置UART LL_USART_SetBaudRate(USART1, 115200);9 [# g8 `( w6 p& _, r8 s LL_USART_SetDataWidth(USART1, LL_USART_DATAWIDTH_8B); LL_USART_SetStopBitsLength(USART1, LL_USART_STOPBITS_1);, d% G1 v% ]3 t( y/ h9 C: K' n7 l LL_USART_SetParity(USART1, LL_USART_PARITY_NONE);! N7 m, C! h, l LL_USART_SetTransferDirection(USART1, LL_USART_DIRECTION_TX_RX); LL_USART_Enable(USART1); }2 ~9 ~! A. `6 ~5 x: t- g voidUART_SendString(char* str)0 T- ^. j0 J6 z {9 n, W2 E/ o+ e- M9 C ` while(*str) {5 E+ q3 }6 W' Y- O5 V' r while(!LL_USART_IsActiveFlag_TXE(USART1)); LL_USART_TransmitData8(USART1, *str++); }! e- s. F. Q% y4 d6 g } 7 p: o3 C) t- N: C |
从 CubeMX 到 MX2:这些关键变化必须知道
【STM32H5 评测】ADC 电压表
STM32Cube嵌入式软件更新(2026年8月)
【STM32H5 评测】基础硬件加密与随机数性能 - STM32H5E5实测硬件AES加解密、HASH运算、TRNG真随机数输出速率与稳定性
【STM32H5 评测】NUCLEO-H5E5ZJ 使用 TrustZone 安全分区系统实践测试
【STM32H5 评测】CPU核心性能 - STM32H5E5跑 RTOS,观察任务切换速度、中断响应快慢
【STM32H5 评测】介绍、环境搭建、工程测试
#双节活动 1.在CubeMX中引用touchGFX出现的问题与解决
如何将STM32CubeMX生成的CMake工程导入STM32CubeIDE
【 逢7发帖赢大礼】1、利用CubeMX生成正点原子H7R7开发板的STM32CubeIDE工程
微信公众号
手机版