媒介撸踏踏
比拟较早几年使用法度库开发来讲,最近几年HAL库的使用是越来越多,那么咱们开发应当使用哪一种呢,本文提防先容常用的几种开发神志及互相之间的区别,白猫也好、黑猫也好,持到耗子即是好猫。
STM32三种开发神志
无为生手在初学STM32的时候,领先都要先遴荐一种要用的开发神志,不同的开发神志会导致你编程的架构是系数不一样的。一般大多数都会选择法度库和HAL库,而少许部分东谈主和会过平直成就寄存器进行开发。
网上对于法度库、HAL库的形容确信是罪责显明。但是一个对于好多刚初学的一又友照旧没法很直不雅的去真确了解这些不同开发发神志相互之间的区别,是以笔者念念以一种相等直白的神志,用我方的畅达去将这些东西表述出来,要是有形容的不合的场所或者是不同成见的也不错全国提议。
1、平直成就寄存器
不少先学了51的一又友可能会知谈,会有一小部分东谈主或是教程是通过汇编话语平直操作寄存器兑现功能的,这种方法到了STM32就变得不太容易行得通了,因为STM32的寄存器数目是51单片机的十数倍,如斯多的寄存器压根无法一王人缅念念,开发时需要频频的翻查芯片的数据手册,此时平直操作寄存器就变得相等的忙碌了。但照旧会有很小一部分东谈主,心爱去平直操作寄存器,因为这样更接近旨趣,知其然也知其是以然。
2、法度库
上头也提到了,STM32有相等多的寄存器,而导致了开发勤快,是以为此ST公司就为每款芯片都编写了一份库文献,也即是工程文献里stm32F1xx…之类的。在这些 .c .h文献中,包括一些常用量的宏界说,把一些外设也通过结构体变量封装起来,如GPIO口时钟等。是以咱们只需要成就结构体变量成员就不错修改外设的成就寄存器,从而遴荐不同的功能。亦然现时最多东谈主使用的神志,亦然学习STM32战争最多的一种开发神志,我也就未几领路了。
3、HAL库
HAL库是ST公司现时主力推的开发神志,全称即是Hardware Abstraction Layer(空洞印象层)。库如其名,很空洞,一眼看上去不太容易知谈他的作用是什么。
它的出现比法度库要晚,但其实和法度库一样,都是为了检朴行为开发的时代,而且HAL库尤其的有用,要是说法度库把兑现功能需要成就的寄存器集成了,那么HAL库的一些函数以致不错作念到某些特定功能的集成。也即是说,雷同的功能,法度库可能要用几句话,HAL库只需用一句话就够了。
况且HAL库也很好的贬责了行为移植的问题,不同型号的stm32芯片它的法度库是不一样的,举例在F4上开发的行为移植到F3上是不行通用的,而使用HAL库,只须使用的是重叠的外设,行为基本不错系数复制粘贴,细心是重叠外设,有趣有趣也即是不行系风捕景,举例F7比F3要多几个定时器,不行明明莫得这个定时器却非要成就,但其实这种情况未几,绝大多数都不错平直复制粘贴。是而且使用ST公司研发的STMcube软件,不错通过图形化的成就功能,平直生成扫数这个词使用HAL库的工程文献,不错说是浅薄止境,但是浅薄的同期也形成了它奉积恶果的低下,在各式论坛帖子确凿是被吐槽的罪责显明。
HAL库固件库安设与用户手册
1、领先确立让Cube不错自动联网下载关联固件库遴荐updater Settings
确立如下
2、把柄芯片遴荐所需固件
版块是向下兼容的,不错平直遴荐最新版。但要是认为最新版太大,不错阅读底下的Main Changes.大约救济你现时的芯片就好。
选好了,点击Install Now就行,过程可能有点长。建议平直官网下载到腹地,再安设文献会被下载到如下位置,建议改变此目次,不要选在C盘!!!
3、寻找用户匡助手册
参加固件所在文献夹,里面包含好多内容。
比如说 官方提供的开发板行为,每个型号底下都有对应功能的兑现,用户手册就在Drivers文献夹底下。
用户手册就在Drivers文献夹底下。
STM32 HAL库与法度库的区别
1、句柄
句柄(handle),有多种意旨,其中第一种是指行为有计划,第二种是指Windows编程。现时大部分都是指行为有计划/行为开发这类。
第一种解说:句柄是一种罕见的智能指针 。当一个应用行为要援用其他系统(如数据库、操作系统)所不停的内存块或对象时,就要使用句柄。第二种解说:扫数这个词Windows编程的基础。一个句柄是指使用的一个独一的整数值,即一个4字节(64位行为中为8字节)长的数值,来标记应用行为中的不同对象和同类中的不同的实例,诸如,一个窗口,按钮,图标,迤逦条,输出开辟,控件或者文献等。应用行为大约通过句柄打听相应的对象的信息,但是句柄不是指针,行为不行诈欺句柄来平直阅读文献中的信息。要是句柄不在I/O文献中,它是毫无须处的。句柄是Windows用来象征应用行为中建设的或是使用的独一整数,Windows大批使用了句柄来标记对象。
STM32的法度库中,句柄是一种罕见的指针,无为指向结构体!
在STM32的法度库中,假定咱们要运行化一个外设(这里以USART为例),咱们领先要运行化他们的各个寄存器。在法度库中,这些操作都是诈欺固件库结构体变量+固件库Init函数兑现的:
USART_InitTypeDef USART_InitStructure;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(USART3, &USART_InitStructure); //运行化串口1
不错看到,要运行化一个串口,需要:
1、对六个位置进行赋值2、然后盾用Init函数
USART_InitStructure并不是一个全局结构体变量,而是只在函数里面的局部变量,运行化完成之后,USART_InitStructure就失去了作用。而在HAL库中,雷同是USART运行化结构体变量,淫荡妈妈咱们要界说为全局变量。
UART_HandleTypeDef UART1_Handler;
结构体成员
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;
咱们发现,与法度库不同的是,该成员不仅:
1、包含了之前法度库就有的六个成员(波特率,数据景色等),2、还包含过采样、(发送或接管的)数据缓存、数据指针、串口 DMA 关联的变量、各式象征位等等要在扫数这个词名堂经由中都要确立的各个成员。该 UART1_Handler就被称为串口的句柄,它被畅达扫数这个词USART收发的经由,比如开启中断:
HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);
比如后头要讲到的MSP与Callback回调函数:
void HAL_UART_MspInit(UART_HandleTypeDef *huart);void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
在这些函数中,只需要调用运行化时界说的句柄UART1_Handler就好。
2、MSP函数
MSP: MCU Specific Package 单片机的具体决议
MSP是指和MCU关联的运行化,援用一下正点原子的解说,个东谈主认为说的很理解:
咱们要运行化一个串口,领先要确立和 MCU 无关的东西,举例波特率,奇偶校验,罢手位等,这些参数确立和 MCU 莫得任何相干,不错使用 STM32F1,也不错是 STM32F2/F3/F4/F7上的串口。而一个串口开辟它需要一个 MCU 来承载,举例用 STM32F4 来作念承载,PA9 作念为发送,PA10 作念为接管,MSP 即是要运行化 STM32F4 的 PA9,PA10,成就这两个引脚。是以 HAL驱动神志的运行化经由即是:
HAL_USART_Init()—>HAL_USART_MspInit() ,先运行化与 MCU无关的串口契约,再运行化与 MCU 关联的串口引脚。在 STM32 的 HAL 驱动中HAL_PPP_MspInit()看成回调,被 HAL_PPP_Init()函数所调用。当咱们需要移植行为到 STM32F1平台的时候,咱们只需要修改 HAL_PPP_MspInit 函数内容而不需要修改 HAL_PPP_Init 进口参数内容。
在HAL库中,险些每运行化一个外设就需要确立该外设与单片机之间的计议,比如IO口,是否复用等等,可见,HAL库相对于法度库多了MSP函数之后,移植性相等强,但与此同期却加多了代码量和代码的嵌套层级。不错说各故意弊。
雷同,MSP函数又不错相助句柄,达到相等强的移植性:
void HAL_UART_MspInit(UART_HandleTypeDef *huart);
3、Callback函数
肖似于MSP函数,个东谈主认为Callback函数主要匡助用户应用层的代码编写。
照旧以USART为例,在法度库中,串口中断了以后,咱们要先在中断中判断是否是接管中断,然后读出数据,趁机拔除中断象征位,然后再是对数据的处理,这样要是咱们在一个中断函数中写这样多代码,就会显得很错乱:
void USART3_IRQHandler(void) //串口1中断做事行为{ u8 Res;if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接管中断(接管到的数据必须是0x0d 0x0a扫尾) { Res =USART_ReceiveData(USART3); //读取接管到的数据/*数据处理区*/ } } }
而在HAL库中,参加串口中断后,平直由HAL库中断函数进行托管:
void USART1_IRQHandler(void) { HAL_UART_IRQHandler(&UART1_Handler); //调用HAL库中断处理公用函数 /***************概略无关代码****************/ }
HAL_UART_IRQHandler这个函数完成了判断是哪个中断(接管?发送?或者其他?),然后读出数据,保存至缓存区,趁机拔除中断象征位等等操作。
比如我提前确立了,串口每接管五个字节,我就要对这五个字节进行处理。在一脱手我界说了一个串口接管缓存区:
/*HAL库使用的串口接管缓冲,处理逻辑由HAL库罢了,接管完这个数组就会调用HAL_UART_RxCpltCallback进行处理这个数组*//*RXBUFFERSIZE=5*/u8 aRxBuffer[RXBUFFERSIZE];
在运行化中,我在句柄里确立好了缓存区的地址,缓存大小(五个字节)
/*该代码在HAL_UART_Receive_IT函数中,运行化时会援用*/ huart->pRxBuffPtr = pData;//aRxBuffer huart->RxXferSize = Size;//RXBUFFERSIZE huart->RxXferCount = Size;//RXBUFFERSIZE
则在接管数据中,每接管完五个字节,HAL_UART_IRQHandler才会奉行一次Callback函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
在这个Callback回调函数中,咱们只需要对这接管到的五个字节(保存在aRxBuffer[]中)进行处理就好了,系数不消再去手动拔除象征位等操作。
是以说Callback函数是一个应用层代码的函数,咱们在一脱手只确立句柄里面的各个参数,然后就等着HAL库把我方安排好的代码送得手中就不错了~
综上,即是HAL库的三个与法度库不同的场所之个东谈目标解。个东谈主认为从这三个小点就不错看出HAL库的可移植性之远大,况且用户不错系数不去搭理底层各个寄存器的操作,代码也更有逻辑性。但与此带来的是复杂的代码量,极慢的编译速率,稍微低下的恶果。看奈何弃取了。
STM32 HAL库结构
说到STM32的HAL库,就不得不提STM32CubeMX,其看成一个可视化的成就器具,对于开发者来说,照实大大检朴了开发手艺。关联保举:STM32CubeMX安设教程。STM32CubeMX即是以HAL库为基础的,且现时仅救济HAL库及LL库!领先看一下,官方给出的HAL库的包含结构:
阅读:jianhu.sfangba.com阅读:jingjiang.sfangba.com阅读:peixian.sfangba.com阅读:yangzhong.sfangba.com阅读:qidong2.sfangba.com阅读:dafeng.sfangba.com阅读:shuyang.sfangba.com阅读:zhenjiang.sfangba.com阅读:lianyungang.sfangba.com阅读:yancheng.sfangba.com阅读:yangzhou.sfangba.com阅读:changzhou.sfangba.com阅读:suzhou2.sfangba.com阅读:jiangsu.sfangba.com阅读:luannan.sfangba.com阅读:guan.sfangba.com阅读:cangxian.sfangba.com
1、stm32f4xx.h主要包含STM32同系列芯片的不同具体型号的界说,是否使用HAL库等的界说,接着,其会把柄界说的芯片信号包含具体的芯片型号的头文献:
#if defined(STM32F405xx)#include "stm32f405xx.h"#elif defined(STM32F415xx)#include "stm32f415xx.h"#elif defined(STM32F407xx)#include "stm32f407xx.h"#elif defined(STM32F417xx)#include "stm32f417xx.h"#else#error "Please select first the target STM32F4xx device used in your application (in stm32f2xx.h file)"#endif
紧接着,其会包含stm32f4xx_hal.h。
2、stm32f4xx_hal.h:stm32f4xx_hal.c/h 主要兑现HAL库的运行化、系统滴答关联函数、及CPU的调试模式成就3、stm32f4xx_hal_conf.h :该文献是一个用户级别的成就文献,用来兑现对HAL库的剪辑,其位于用户文献目次,不要放在库目次中。
接下来对于HAL库的源码文献进行一下领路,HAL库文献名均以stm32f4xx_hal起头,后头加上_外设或者模块名(如:stm32f4xx_hal_adc.c):
4、库文献:stm32f4xx_hal_ppp.c/.h // 主要的外设或者模块的驱动源文献,包含了该外设的通用APIstm32f4xx_hal_ppp_ex.c/.h // 外围开辟或模块驱动行为的膨胀文献。这组文献中包含特定型号或者系列的芯片的罕见API。以及要是该特定的芯片里面有不同的兑现神志,则该文献中的罕见API将掩饰_ppp中的通用API。stm32f4xx_hal.c/.h // 此文献用于HAL运行化,况且包含DBGMCU、重映射和基于systick的手艺延长等关联的API5、其他库文献用户级别文献: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 // 中断处理函数的关联兑现6 main.c/.h //
把柄HAL库的定名法则,其API不错分为以下三大类:
运行化/反运行化函数:
HAL_PPP_Init(), HAL_PPP_DeInit()
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 ().
细心:
现时LL库是和HAL库绑缚发布的,是以在HAL库源码中,还有一些名为 stm32f2xx_ll_ppp的源码文献,这些文献即是新增的LL库文献。使用CubeMX坐蓐名堂时,不错遴荐LL库。
HAL库最大的特色即是对底层进行了空洞。在此结构下,用户代码的处理主要分为三部分:
处理外设句柄(兑现用户功能)处理MSP处理各式回调函数
关联常识如下:
1、外设句柄界说
用户代码的第一大部分:对于外设句柄的处理。HAL库在结构上,对每个外设空洞成了一个称为ppp_HandleTypeDef的结构体,其中ppp即是每个外设的名字。*扫数的函数都是责任在ppp_HandleTypeDef指针之下。
多实例救济:每个外设/模块实例都有我方的句柄。因此,实例资源是寥落的
底下,以ADC为例
裸舞twitter外围进度互交流讯:该句柄用于不停进度例程之间的分享数据资源。
/** * @brief ADC handle Structure definition */typedef struct{ ADC_TypeDef *Instance; /*!< Register base address */ ADC_InitTypeDef Init; /*!< ADC required parameters */ __IO uint32_t NbrOfCurrentConversionRank; /*!< ADC number of current conversion rank */ DMA_HandleTypeDef *DMA_Handle; /*!< Pointer DMA Handler */ HAL_LockTypeDef Lock; /*!< ADC locking object */ __IO uint32_t State; /*!< ADC communication state */ __IO uint32_t ErrorCode; /*!< ADC Error code */}ADC_HandleTypeDef;
从上头的界说不错看出,ADC_HandleTypeDef中包含了ADC可能出现的扫数界说,对于用户念念要使用ADC只须界说一个ADC_HandleTypeDef的变量,给每个变量赋好值,对应的外设就空洞结束。接下来即是具体使用了。
诚然,对于那些分享型外设或者说系统外设来说,他们不需要进行以上这样的空洞,这些部分与正本的法度外设库函数基本一样。举例以下外设:
GPIOSYSTICKNVICRCCFLASH
以GPIO为例,对于HAL_GPIO_Init() 函数,其只需要GPIO 地址以过头运行化参数即可。
2、 三种编程神志
HAL库对扫数的函数模子也进行了长入。在HAL库中,救济三种编程模式:轮询模式、中断模式、DMA模式(要是外设救济)。其差别对应如下三种类型的函数(以ADC为例):
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc); HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc);HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc);HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc);HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc);
其中,带_IT的暗意责任在中断模式下;带_DMA的责任在DMA模式下(细心:DMA模式下亦然开中断的);什么都没带的即是轮询模式(莫得开启中断的)。至于使用者使用何种神志,就看我方的遴荐了。
此外,新的HAL库架构下长入经受宏的景色对各式中断等进行成就(正本法度外设库一般都是各式函数)。针对每种外设主要由以下宏:
__HAL_PPP_ENABLE_IT(HANDLE, INTERRUPT):使能一个指定的外设中断__HAL_PPP_DISABLE_IT(HANDLE, INTERRUPT):失能一个指定的外设中断__HAL_PPP_GET_IT (HANDLE, __ INTERRUPT __):获取一个指定的外设中断景色__HAL_PPP_CLEAR_IT (HANDLE, __ INTERRUPT __):拔除一个指定的外设的中断景色__HAL_PPP_GET_FLAG (HANDLE, FLAG):获取一个指定的外设的象征景色__HAL_PPP_CLEAR_FLAG (HANDLE, FLAG):拔除一个指定的外设的象征景色__HAL_PPP_ENABLE(HANDLE) :使能外设__HAL_PPP_DISABLE(HANDLE) :失能外设__HAL_PPP_XXXX (HANDLE, PARAM) :指定外设的宏界说_HAL_PPP_GET IT_SOURCE (HANDLE, __ INTERRUPT __):查验中断源
3、 三大回调函数
在HAL库的源码中,到处可见一些以__weak起头的函数,而且这些函数,有些仍是被兑现了,比如:
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority){/*Configure the SysTick to have interrupt in 1ms time basis*/ HAL_SYSTICK_Config(SystemCoreClock/1000U);/*Configure the SysTick IRQ priority */ HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0U);/* Return function status */return HAL_OK;}
有些则莫得被兑现,举例:
__weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi){/* Prevent unused argument(s) compilation warning */ UNUSED(hspi);/* NOTE : This function should not be modified, when the callback is needed,the HAL_SPI_TxCpltCallback should be implemented in the user file */}
扫数带有__weak关节字的函数暗意,就不错由用户我方来兑现。要是出现了同名函数,且不带__weak关节字,那么结伴器就会经受外部兑现的同名函数。
无为来说,HAL库厚爱扫数这个词处理和MCU外设的处理逻辑,并将必要部分以回调函数的景色给出到用户,用户只需要在对应的回调函数中作念修改即可。HAL库包含如下三种用户级别回调函数(PPP为外设名):
1、外设系统级运行化/消灭运行化回调函数(用户代码的第二大部分:对于MSP的处理):
HAL_PPP_MspInit()和 HAL_PPP_MspDeInit**
举例:
__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)。
在HAL_PPP_Init() 函数中被调用,用来运行化底层关联的开辟(GPIOs, clock, DMA, interrupt)
2、处理完成回调函数:HAL_PPP_ProcessCpltCallback*(Process指具体某种处理,如UART的Tx),
举例:
__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
当外设或者DMA责任完成后时,触发中断,该回调函数会在外设中断处理函数或者DMA的中断处理函数中被调用诞妄处理回调函数:
HAL_PPP_ErrorCallback
举例:
__weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef hspi)*
3、当外设或者DMA出现诞妄时,触发末端,该回调函数会在外设中断处理函数或者DMA的中断处理函数中被调用
诞妄处理回调函数:
HAL_PPP_ErrorCallback
举例:
__weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef hspi)*
当外设或者DMA出现诞妄时,触发末端,该回调函数会在外设中断处理函数或者DMA的中断处理函数中被调用。
绝大多数用户代码均在以上三大回调函数中兑现。
HAL库结构中,在每次运行化前(尤其是在屡次调用运行化前),先调用对应的反运行化(DeInit)函数长短常有必要的。
某些外设屡次运行化时不调用复返会导致运行化失败。完成回调函数有多中,举例串口的完成回调函数有
HAL_UART_TxCpltCallbackHAL_UART_TxHalfCpltCallback
(用户代码的第三大部分:对于上头第二点和第三点的各式回调函数的处理)在本色使用中,发现HAL仍有不少问题,举例在使用USB时,其库成就存在问题。
HAL库移植使用
基本景色:
1、复制stm32f2xx_hal_msp_template.c,参照该模板,按次兑现用到的外设的HAL_PPP_MspInit()和 HAL_PPP_MspDeInit。2、复制stm32f2xx_hal_conf_template.h,用户不错在此文献中解放剪辑,成就HAL库。3、在使用HAL库时,必须先调用函数:HAL_StatusTypeDef HAL_Init(void)(该函数在stm32f2xx_hal.c中界说,也就意味着第一丝中,必须领先兑现HAL_MspInit(void)和HAL_MspDeInit(void))4、HAL库与STD库不同,HAL库使用RCC中的函数来成就系统时钟,用户需要单独写时钟成就函数(STD库默许在system_stm32f2xx.c中)5、对于中断,HAL提供了中断处理函数,只需要调用HAL提供的中断处理函数。用户我方的代码,不建议先写到中断中,而应该写到HAL提供的回调函数中。6、对于每一个外设,HAL都提供了回调函数,回调函数用来兑现用户我方的代码。扫数这个词调用结构由HAL库我方完成。
举例:
Uart中,HAL提供了
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
函数,用户只需要触发中断后,用户只需要调用该函数即可,同期,我方的代码写在对应的回调函数中即可!如下:
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
使用了哪种就用哪个回调函数即可!
基本结构
要而论之,使用HAL库编写行为(针对某个外设)的基本结构(以串口为例)如下:
1、 成就外设句柄 举例,建设UartConfig.c,在其中界说串口句柄 UART_HandleTypeDef huart;接着使用运行化句柄(HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef huart))2、编写Msp 举例,建设UartMsp.c,在其中兑现void HAL_UART_MspInit(UART_HandleTypeDef huart) 和 void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)3、兑现对应的回调函数 举例撸踏踏,建设UartCallBack.c,在其中兑现上文所领路的三大回调函数中的完成回调函数和诞妄回调函数