HAL库借鉴了面向对象的设计思想,将外设驱动封装为对象,屏蔽了底层硬件,提高了开发效率,但程序执行效率较低。
HAL库的文件类型可认为分为以下两类
库文件: stm32f4xx_hal_ppp.c/.h // 主要的外设或者模块的驱动源文件,包含了该外设的通用API stm32f4xx_hal_ppp_ex.c/.h // 外围设备或模块驱动程序的扩展文件。这组文件中包含特定型号或者系列的芯片的特殊API。以及如果该特定的芯片内部有不同的实现方式,则该文件中的特殊API将覆盖_ppp中的通用API。 stm32f4xx_hal.c/.h // 此文件用于HAL初始化,并且包含DBGMCU、重映射和基于systick的时间延迟等相关的API 其他库文件 用户级别文件: stm32f4xx_hal_msp_template.c // 只有.c没有.h。它包含用户应用程序中使用的外设的MSP初始化和反初始化(主程序和回调函数)。使用者复制到自己目录下使用模板。 stm32f4xx_hal_conf_template.h // 用户级别的库配置文件模板。使用者复制到自己目录下使用 system_stm32f4xx.c // 此文件主要包含SystemInit()函数,该函数在刚复位及跳到main之前的启动过程中被调用。 **它不在启动时配置系统时钟(与标准库相反)**。 时钟的配置在用户文件中使用HAL API来完成。 startup_stm32f4xx.s // 芯片启动文件,主要包含堆栈定义,中断向量表等 stm32f4xx_it.c/.h // 中断服务函数的相关实现 main.c/.h //main
HAL库对底层进行了封装,HAL库下用户代码处理可分为以下三部分
①句柄(ppp_HandleTypeDef)
②MSP(MCU Specific Package)
③回调函数(xxx_Callback)
1.句柄
为了实现各型号芯片HAL库的通用性,HAL库设计了统一的外设句柄类型:ppp_HandleTypeDef.(ppp代表外设名称)
与标准库中利用固件结构体变量+固件库Init函数实现初始化外设不同,HAL库通过定义ppp_HandleTypeDef的全局变量,针对需求配置结构体中成员即可
以USART1初始化为例,在库函数中:
//USART1端口配置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10 //USART1 初始化设置 USART_InitStructure.USART_BaudRate = bound;//波特率设置 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位 USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; //收发模式 USART_Init(USART1, &USART_InitStructure); //初始化串口1 USART_Cmd(USART1, ENABLE); //使能串口1 //USART_ClearFlag(USART1, USART_FLAG_TC); #if EN_USART1_RX USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断 //Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 #endif }
使用GPIO、USART、NVIC结构体变量完成了收发功能的串口初始化
而在HAL库中
UART_HandleTypeDef Usart1Handle; // 定义串口句柄 UartHandle.Instance = USART1; // 初始化串口实例 USART1 UartHandle.Init.BaudRate = 9600; // 设置波特率 UartHandle.Init.WordLength = UART_WORDLENGTH_8B; // 8位数据位 UartHandle.Init.StopBits = UART_STOPBITS_1; // 一个停止位 UartHandle.Init.Parity = UART_PARITY_NONE; // 奇偶校验位无 UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 硬件控制流无 UartHandle.Init.Mode = UART_MODE_TX_RX; // RX和TX模式 if(HAL_UART_Init(&UartHandle) != HAL_OK) //使能结构体变量 { Error_Handler(); }
同样是USART初始化结构体变量,需要定义为全局变量,其中 Usart1Handle就被称为串口的句柄,我们可以查看HAL库中串口结构体的成员
typedef struct { USART_TypeDef *Instance; /*!< UART registers base address */ UART_InitTypeDef Init; /*!< UART communication parameters */ uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */ uint16_t TxXferSize; /*!< UART Tx Transfer size */ uint16_t TxXferCount; /*!< UART Tx Transfer Counter */ uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */ uint16_t RxXferSize; /*!< UART Rx Transfer size */ uint16_t RxXferCount; /*!< UART Rx Transfer Counter */ DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */ DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */ HAL_LockTypeDef Lock; /*!< Locking object */ __IO HAL_UART_StateTypeDef State; /*!< UART communication state */ __IO uint32_t ErrorCode; /*!< UART Error code */ }UART_HandleTypeDef;
HAL库结构体中提供了所有串口可以配置的参数。
句柄贯穿了整个USART收发的流程,如开启串口中断
HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);
标签:HAL,USART,STM32HAL,NVIC,UART,开发,InitStructure,GPIO From: https://www.cnblogs.com/xujingxing/p/17958072