STM32HAL库开发-了解HAL库(一)

发布时间 2024-01-11 11:32:13作者: 日暮途远7

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);