一、HAL命名规则

  在这里插入图片描述

   1、模块名称PPP

     PPP指的是外设的功能模式,而不是外设本身。
     例如,如果是USART,PPP可以是USART、IRDA、UART或SMARTCARD,取决于外设模式。
     一个文件中使用的常量在该文件中定义。多个文件中使用的常量在头文件中定义。
     所有常量都使用大写字母编写,除了外设驱动函数参数。

   2、TypeDef

     typedef变量名应该以_TypeDef结尾。寄存器被视为常量。
     外设寄存器在PPP_TypeDef结构中声明。例如ADC_TypeDef。
     外设句柄结构被命名为PPP_HandleTypedef。例如DMA_HandleTypeDef。
     包含PPP外设特定配置参数的结构被命名为PPP_xxxxConfTypeDef。例如ADC_ChannelConfTypeDef。
     包含PPP外设初始化参数的结构被命名为PPP_InitTypeDef。例如ADC_InitTypeDef。

   3、函数名称

     外设功能名称以HAL为前缀,然后是大写的相应外设首字母缩写,后跟下划线,每个单词的第一个字母大写。
       例如HAL UARTTransmit()。
     函数名中只允许一个下划线,用于将外设首字母缩写与函数名的其余部分分开。
     根据PPP_InitTypeDef中指定的参数初始化PPP外设的函数被命名为HAL PPP_Init。例如HAL_TIM_Init()。
     将PPP外设寄存器重置为默认值的函数被命名为HAL_PPP_Delnit。例如HAL_TIM_Delnit ()。

   4、MODE

     MODE后缀指的是处理模式,可以是轮询、中断或DMA。
     例如,当DMA与本机资源一起使用时,应调用该函数: HAL_PPP_Function_DMA()。

二、HAL通用命名规定

   1、外理中断和特性时钟配置的宏

    在这里插入图片描述

     NVIC和SYSTICK是ArmCortex@核心特性。
     与这些特性相关的API位于stm32f1xx_hal _cortex.c文件中。
     当从寄存器中读取状态位或标志位时,它由移位值组成,取决于读取值的数量和它们的大小。
     在这种情况下,返回的状态宽度为32位。
     例如:STATUS=XX|(YY<<16)或STATUS=XX|(YY <8)|(YY <16)1(YY<<24)"在使用HAL_PPP_Init()API之前,PPP句柄是有效的。
     初始化函数在修改句柄字段之前执行检查。

			HAL_PPP_Init (PPP_HandleTypeDef);
			if(hppp==NULL)
			{
			        return HAL_ERROR;
			}

     下面定义的宏用于:
     条件宏:

			#define ABS(x) (((x)>0)?(x):(-x))

     伪代码宏:

				#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD_, __DMA_HANDLE_) \
				do{ \
				(__HANDLE__)->__PPP_DMA_FIELD_ = &(__DMA_HANDLE_); \
				(__DMA_HANDLE_).Parent = (__HANDLE__); \
				} while(0)

   2、中断处理程序和回调函数

    在这里插入图片描述

     除了API之外,HAL外设驱动程序还包括:
       HAL_PPP_IRQHandler()外设中断处理程序,应该从stm32f1xx_it.c中调用用户回调函数。
     用户回调函数被定义为空函数,并带有“弱"属性。它们必须在用户代码中定义。
     有三种类型的用户回调函数:
       外设系统级初始化/去初始化回调:HAL_PPP_Msplnit()和HAL_PPP_MspDelnit
       处理完成回调:HAL_PPP_ProcessCpltCallback。
       错误回调:HAL_PPP_ErrorCallback。

   3、HAL通用API

     通用API提供适用于所有STM32设备的常见通用功能。
     它们由四个API组成:
       初始化和去初始化函数:HAL_PPP_Init(),HAL_PPP_Delnit()。
       IO操函数: HAL_PPP_Read(), HAL_PPP_Write(), HAL_PPP_Transmit(), HAL_PPP_Receive()。
       控制函数:HAL_PPP_Set(),HAL_PPP_Get()。
       状态和错误函数:HAL_PPP_GetState(),HAL_PPP_GetError()。
     示例基于ADC外设:
      在这里插入图片描述

   4、HAL扩展API

     扩展API提供特定功能或覆盖特定系列或同一系列内特定零件号的修改后的APl。
     扩展模型由一个额外的文件组成,即stm32f1xx_ha_ppp_ex.c,其中包含所有特定功能和定义语句(stm32f1xx_hal_ppp_ex.h)给定零件号的。
     以下是基于ADC外设的示例:
       HAL_ADCEx_CalibrationStart();//此函数用于启动自动ADC校准。
     Hal驱动程序可以通过五种不同的方式处理特定的IP功能。

     1、添加特定于部件号的功能

       当需要特定于给定设备的新功能时,新的Api将添加到stm32f1xx_hal_ppp_ex中。c扩展文件。它们被命名为HAL_PPPEx_Function()。
      在这里插入图片描述

     2、添加模块特定功能

       在这种情况下,API在扩展驱动程序C文件中添加并命名。
      在这里插入图片描述

     3、添加新外设(特定于属于给定系列的设备)

       当需要仅在特定设备中可用的外设时,将在stm32f1xx_hal_newppp中添加与此新外设模块对应的Api。
      c.但是在stm32lxx_hal_conf中选择包含此文件。
       h使用宏:
         #define HAL_NEWPPP_MODULE_ENABLED
      在这里插入图片描述

     4、更新现有常用Api

     在这种情况下,例程在stm32f1xx_hal_ppp_ex中使用相同的名称定义。c扩展文件,而泛型
     API被定义为弱,这样编译器就会被新定义的函数复盖原来的例程。
      在这里插入图片描述

     5、更新现有数据结构

       特定设备部件号(例如PPP_InitTypeDef)的数据结构可以具有不同的字段。
      在这种情况 下,数据结构在扩展头文件中定义,并由特定部件号define语句分隔。
       Example:

				#if defined (STM32F100xB) 
				typedef struct 
				{ 
				() 
				}PPP_InitTypeDef; 
				#endif /* STM32F100xB */

三、CubeMX与HAL库的对应关系

  在这里插入图片描述

   1、在HAL库中每个外设都有两个关键的部分:

       Private:(私有的),是HAL库内部自己调用的
       Exported:(对外的),我们的应用程序中去调用。

   2、Exported分为四个部分

       types:各种Struct结构体,用于外设功能配置。对应了CubeMax软件的配置项
       constants:上方各种Struct结构体中的成员的可以配置的选项
       macro:宏定义,相当于直接对寄存器操作。因为在某些时候调用api反而效率不高
       functions:API函数。
   我们对CubeMax的操作,实际上就是与这些结构体、成员变量一一对应的。
   一个外设的相关结构体会被定义在一个总的结构体中。

四、HAL编程模型

   1、句柄

     PPP_HandleTypeDef hxxx;
     保存外设基地址、配置、状态、错误、DMA、中断。
     每个外设一个句柄,例如:
       UART_HandleTypeDef huart1;
       TIM_HandleTypeDef htim2;
       ADC_HandleTypeDef hadc1;

   2、初始化 Init

     HAL_PPP_Init(&hxxx);
     根据句柄里的配置,初始化硬件寄存器。
     CubeMX 自动生成。

   3、操作模式

     阻塞模式(Blocking)(轮询模式)
       HAL_PPP_Transmit(&hxxx, buf, len, 1000);
       等待完成才返回。
     中断模式(Interrupt)
       HAL_PPP_Transmit_IT(&hxxx, buf, len);
       启动后立刻返回,完成后触发中断→回调。
     DMA 模式(DMA)
       HAL_PPP_Transmit_DMA(&hxxx, buf, len);
       硬件搬运,不占 CPU。

   4、HAL库统一回调机制

     所有中断完成后,都会调用 Callback 回调函数:
       void HAL_PPP_Callback(XXX_HandleTypeDef *hxxx)
       {
       // 操作完成
       }
     例如:
       HAL_UART_RxCpltCallback
       HAL_ADC_ConvCpltCallback
       HAL_TIM_PeriodElapsedCallback
     这是 HAL 库的标准异步处理模型。

   5、HAL 状态模型

     每个句柄都有状态:
     HAL_StatusTypeDef status = hxxx.State;
       HAL_OK
       HAL_BUSY
       HAL_ERROR
       HAL_TIMEOUT
    所有外设状态判断方式完全一样。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐