在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀(guān)看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32標(biāo)準(zhǔn)庫(kù)和HAL庫(kù)有什么不同 我們?cè)趺从?/h1>
摘要:通常新手在入門(mén)STM32的時(shí)候,首先都要先選擇一種要用的開(kāi)發(fā)方式,不同的開(kāi)發(fā)方式會(huì)導(dǎo)致你編程的架構(gòu)是完全不一樣的。一般大多數(shù)都會(huì)選用標(biāo)準(zhǔn)庫(kù)和HAL庫(kù),而極少部分人會(huì)通過(guò)直接配置寄存器進(jìn)行開(kāi)發(fā)。

網(wǎng)上關(guān)于標(biāo)準(zhǔn)庫(kù)、HAL庫(kù)的描述相信是數(shù)不勝數(shù)。可是一個(gè)對(duì)于很多剛?cè)腴T(mén)的朋友還是沒(méi)法很直觀(guān)的去真正了解這些不同開(kāi)發(fā)發(fā)方式彼此之間的區(qū)別,所以筆者想以一種非常直白的方式,用自己的理解去將這些東西表述出來(lái),如果有描述的不對(duì)的地方或者是不同意見(jiàn)的也可以大家提出。

一、配置寄存器不少先學(xué)了51的朋友可能會(huì)知道,會(huì)有一小部分人或是教程是通過(guò)匯編語(yǔ)言直接操作寄存器實(shí)現(xiàn)功能的,這種方法到了STM32就變得不太容易行得通了。

因?yàn)镾TM32的寄存器數(shù)量是51單片機(jī)的十?dāng)?shù)倍,如此多的寄存器根本無(wú)法全部記憶,開(kāi)發(fā)時(shí)需要經(jīng)常的翻查芯片的數(shù)據(jù)手冊(cè),此時(shí)直接操作寄存器就變得非常的費(fèi)力了。但還是會(huì)有很小一部分人,喜歡去直接操作寄存器,因?yàn)檫@樣更接近原理,知其然也知其所以然。

二、標(biāo)準(zhǔn)庫(kù)上面也提到了,STM32有非常多的寄存器,而導(dǎo)致了開(kāi)發(fā)困難,所以為此ST公司就為每款芯片都編寫(xiě)了一份庫(kù)文件,也就是工程文件里stm32F1xx.。。.。之類(lèi)的。在這些.c .h文件中,包括一些常用量的宏定義,把一些外設(shè)也通過(guò)結(jié)構(gòu)體變量封裝起來(lái),如GPIO口時(shí)鐘等。

所以我們只需要配置結(jié)構(gòu)體變量成員就可以修改外設(shè)的配置寄存器,從而選擇不同的功能。也是目前最多人使用的方式,也是學(xué)習(xí)STM32接觸最多的一種開(kāi)發(fā)方式,我也就不多闡述了。

三、HAL庫(kù)HAL庫(kù)是ST公司目前主力推的開(kāi)發(fā)方式,全稱(chēng)就是Hardware Abstraction Layer(抽象印象層)。

庫(kù)如其名,很抽象,一眼看上去不太容易知道他的作用是什么。它的出現(xiàn)比標(biāo)準(zhǔn)庫(kù)要晚,但其實(shí)和標(biāo)準(zhǔn)庫(kù)一樣,都是為了節(jié)省程序開(kāi)發(fā)的時(shí)期,而且HAL庫(kù)尤其的有效,如果說(shuō)標(biāo)準(zhǔn)庫(kù)把實(shí)現(xiàn)功能需要配置的寄存器集成了,那么HAL庫(kù)的一些函數(shù)甚至可以做到某些特定功能的集成。

也就是說(shuō),同樣的功能,標(biāo)準(zhǔn)庫(kù)可能要用幾句話(huà),HAL庫(kù)只需用一句話(huà)就夠了。并且HAL庫(kù)也很好的解決了程序移植的問(wèn)題,不同型號(hào)的stm32芯片它的標(biāo)準(zhǔn)庫(kù)是不一樣的,例如在F4上開(kāi)發(fā)的程序移植到F3上是不能通用的,而使用HAL庫(kù),只要使用的是相通的外設(shè),程序基本可以完全復(fù)制粘貼,注意是相通外設(shè),意思也就是不能無(wú)中生有。

例如F7比F3要多幾個(gè)定時(shí)器,不能明明沒(méi)有這個(gè)定時(shí)器卻非要配置,但其實(shí)這種情況不多,絕大多數(shù)都可以直接復(fù)制粘貼。是而且使用ST公司研發(fā)的STMcube軟件,可以通過(guò)圖形化的配置功能,直接生成整個(gè)使用HAL庫(kù)的工程文件,可以說(shuō)是方便至極,但是方便的同時(shí)也造成了它執(zhí)行效率的低下,在各種論壇帖子真的是被吐槽的數(shù)不勝數(shù)。

四、總結(jié)綜合上面說(shuō)的,其實(shí)筆者還是強(qiáng)烈推薦HAL庫(kù)的,理由有二:

第一、 F7系列開(kāi)始 ST公司就已近開(kāi)始停止更新標(biāo)準(zhǔn)庫(kù),也就是F7開(kāi)始包括F7已經(jīng)不能用標(biāo)準(zhǔn)庫(kù)了,公司對(duì)于主打HAL庫(kù)的目的已經(jīng)非常明顯了。

二、追求更方便、追求模塊化向來(lái)是世界的潮流,更方便的HAL庫(kù)一定會(huì)迅速發(fā)展,低效的短板遲早會(huì)被硬件高度集成化所彌補(bǔ)。

當(dāng)然啦,不能只學(xué)習(xí)HAL庫(kù),底層的原理必需是要懂的,這是每個(gè)學(xué)有所成的人都公認(rèn)的事實(shí),HAL庫(kù)也不是萬(wàn)能的,結(jié)合對(duì)底層的理解相信一定會(huì)讓你的開(kāi)發(fā)水準(zhǔn)大大提高。

五、STM32 HAL庫(kù)與標(biāo)準(zhǔn)庫(kù)的區(qū)別1.句柄在STM32的標(biāo)準(zhǔn)庫(kù)中,假設(shè)我們要初始化一個(gè)外設(shè)(這里以USART為例) 我們首先要初始化他們的各個(gè)寄存器。

在標(biāo)準(zhǔn)庫(kù)中,這些操作都是利用固件庫(kù)結(jié)構(gòu)體變量+固件庫(kù)Init函數(shù)實(shí)現(xiàn)的:

USART_InitTypeDefUSART_InitStructure;

USART_InitStructure.USART_BaudRate=bound;//串口波特率
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字長(zhǎng)為8位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits=USART_StopBits_1;//一個(gè)停止位
USART_InitStructure.USART_Parity=USART_Parity_No;//無(wú)奇偶校驗(yàn)位
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//無(wú)硬件數(shù)據(jù)流控制
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//收發(fā)模式

USART_Init(USART3,&USART_InitStructure);//初始化串口1

可以看到,要初始化一個(gè)串口,需要對(duì)六個(gè)位置進(jìn)行賦值,然后引用Init函數(shù),并且USART_InitStructure并不是一個(gè)全局結(jié)構(gòu)體變量,而是只在函數(shù)內(nèi)部的局部變量,初始化完成之后,USART_InitStructure就失去了作用。

而在HAL庫(kù)中,同樣是USART初始化結(jié)構(gòu)體變量,我們要定義為全局變量。

UART_HandleTypeDefUART1_Handler;

右鍵查看結(jié)構(gòu)體成員:

typedefstruct
{
USART_TypeDef*Instance;/*!
UART_InitTypeDefInit;/*!
uint8_t*pTxBuffPtr;/*!
uint16_tTxXferSize;/*!
uint16_tTxXferCount;/*!
uint8_t*pRxBuffPtr;/*!
uint16_tRxXferSize;/*!
uint16_tRxXferCount;/*!
DMA_HandleTypeDef*hdmatx;/*!
DMA_HandleTypeDef*hdmarx;/*!
HAL_LockTypeDefLock;/*!
__IOHAL_UART_StateTypeDefState;/*!
__IOuint32_tErrorCode;/*!
}UART_HandleTypeDef;

我們發(fā)現(xiàn),與標(biāo)準(zhǔn)庫(kù)不同的是,該成員不僅包含了之前標(biāo)準(zhǔn)庫(kù)就有的六個(gè)成員(波特率,數(shù)據(jù)格式等),還包含過(guò)采樣、(發(fā)送或接收的)數(shù)據(jù)緩存、數(shù)據(jù)指針、串口 DMA 相關(guān)的變量、各種標(biāo)志位等等要在整個(gè)項(xiàng)目流程中都要設(shè)置的各個(gè)成員。

該UART1_Handler就被稱(chēng)為串口的句柄 它被貫穿整個(gè)USART收發(fā)的流程,比如開(kāi)啟中斷:

HAL_UART_Receive_IT(&UART1_Handler,(u8*)aRxBuffer,RXBUFFERSIZE);

比如后面要講到的MSPCallback回調(diào)函數(shù):

voidHAL_UART_MspInit(UART_HandleTypeDef*huart);
voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart);

在這些函數(shù)中,只需要調(diào)用初始化時(shí)定義的句柄UART1_Handler就好。

2.MSP函數(shù)

MCU Specific Package單片機(jī)的具體方案

MSP是指和MCU相關(guān)的初始化,引用一下正點(diǎn)原子的解釋?zhuān)瑐€(gè)人覺(jué)得說(shuō)的很明白:

我們要初始化一個(gè)串口,首先要設(shè)置和 MCU 無(wú)關(guān)的東西,例如波特率,奇偶校驗(yàn),停止位等,這些參數(shù)設(shè)置和 MCU 沒(méi)有任何關(guān)系,可以使用 STM32F1,也可以是STM32F2/F3/F4/F7上的串口。而一個(gè)串口設(shè)備它需要一個(gè) MCU 來(lái)承載,例如用 STM32F4 來(lái)做承載,PA9 做為發(fā)送,PA10 做為接收,MSP 就是要初始化 STM32F4 的 PA9,PA10,配置這兩個(gè)引腳。所以 HAL驅(qū)動(dòng)方式的初始化流程就是:HAL_USART_Init()—>HAL_USART_MspInit(),先初始化與 MCU無(wú)關(guān)的串口協(xié)議,再初始化與 MCU 相關(guān)的串口引腳。在 STM32 的 HAL 驅(qū)動(dòng)中HAL_PPP_MspInit()作為回調(diào),被HAL_PPP_Init()函數(shù)所調(diào)用。當(dāng)我們需要移植程序到 STM32F1平臺(tái)的時(shí)候,我們只需要修改 HAL_PPP_MspInit 函數(shù)內(nèi)容而不需要修改 HAL_PPP_Init 入口參數(shù)內(nèi)容。

在HAL庫(kù)中,幾乎每初始化一個(gè)外設(shè)就需要設(shè)置該外設(shè)與單片機(jī)之間的聯(lián)系,比如IO口,是否復(fù)用等等,可見(jiàn),HAL庫(kù)相對(duì)于標(biāo)準(zhǔn)庫(kù)多了MSP函數(shù)之后,移植性非常強(qiáng),但與此同時(shí)卻增加了代碼量和代碼的嵌套層級(jí)??梢哉f(shuō)各有利弊。

同樣,MSP函數(shù)又可以配合句柄,達(dá)到非常強(qiáng)的移植性:

voidHAL_UART_MspInit(UART_HandleTypeDef*huart);

3.Callback函數(shù)

類(lèi)似于MSP函數(shù),個(gè)人認(rèn)為Callback函數(shù)主要幫助用戶(hù)應(yīng)用層的代碼編寫(xiě)。還是以USART為例,在標(biāo)準(zhǔn)庫(kù)中,串口中斷了以后,我們要先在中斷中判斷是否是接收中斷,然后讀出數(shù)據(jù),順便清除中斷標(biāo)志位,然后再是對(duì)數(shù)據(jù)的處理,這樣如果我們?cè)谝粋€(gè)中斷函數(shù)中寫(xiě)這么多代碼,就會(huì)顯得很混亂:

voidUSART3_IRQHandler(void)//串口1中斷服務(wù)程序
{
u8Res;
if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET)//接收中斷(接收到的數(shù)據(jù)必須是0x0d0x0a結(jié)尾)
{
Res=USART_ReceiveData(USART3);//讀取接收到的數(shù)據(jù)
/*數(shù)據(jù)處理區(qū)*/
}
}

而在HAL庫(kù)中,進(jìn)入串口中斷后,直接由HAL庫(kù)中斷函數(shù)進(jìn)行托管:

voidUSART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&UART1_Handler);//調(diào)用HAL庫(kù)中斷處理公用函數(shù)
/***************省略無(wú)關(guān)代碼****************/
}

HAL_UART_IRQHandler這個(gè)函數(shù)完成了判斷是哪個(gè)中斷(接收?發(fā)送?或者其他?),然后讀出數(shù)據(jù),保存至緩存區(qū),順便清除中斷標(biāo)志位等等操作。比如我提前設(shè)置了,串口每接收五個(gè)字節(jié),我就要對(duì)這五個(gè)字節(jié)進(jìn)行處理。在一開(kāi)始我定義了一個(gè)串口接收緩存區(qū):

/*HAL庫(kù)使用的串口接收緩沖,處理邏輯由HAL庫(kù)控制,接收完這個(gè)數(shù)組就會(huì)調(diào)用HAL_UART_RxCpltCallback進(jìn)行處理這個(gè)數(shù)組*/
/*RXBUFFERSIZE=5*/
u8aRxBuffer[RXBUFFERSIZE];

在初始化中,我在句柄里設(shè)置好了緩存區(qū)的地址,緩存大?。ㄎ鍌€(gè)字節(jié))

/*該代碼在HAL_UART_Receive_IT函數(shù)中,初始化時(shí)會(huì)引用*/
huart->pRxBuffPtr=pData;//aRxBuffer
huart->RxXferSize=Size;//RXBUFFERSIZE
huart->RxXferCount=Size;//RXBUFFERSIZE

則在接收數(shù)據(jù)中,每接收完五個(gè)字節(jié),HAL_UART_IRQHandler才會(huì)執(zhí)行一次Callback函數(shù):

voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart);

在這個(gè)Callback回調(diào)函數(shù)中,我們只需要對(duì)這接收到的五個(gè)字節(jié)(保存在aRxBuffer[]中)進(jìn)行處理就好了,完全不用再去手動(dòng)清除標(biāo)志位等操作。

所以說(shuō)Callback函數(shù)是一個(gè)應(yīng)用層代碼的函數(shù),我們?cè)谝婚_(kāi)始只設(shè)置句柄里面的各個(gè)參數(shù),然后就等著HAL庫(kù)把自己安排好的代碼送到手中就可以了~

綜上,就是HAL庫(kù)的三個(gè)與標(biāo)準(zhǔn)庫(kù)不同的地方之個(gè)人見(jiàn)解。

個(gè)人覺(jué)得從這三個(gè)小點(diǎn)就可以看出HAL庫(kù)的可移植性之強(qiáng)大,并且用戶(hù)可以完全不去理會(huì)底層各個(gè)寄存器的操作,代碼也更有邏輯性。但與此帶來(lái)的是復(fù)雜的代碼量,極慢的編譯速度,略微低下的效率??丛趺慈∩崃?/strong>。

五、HAL庫(kù)結(jié)構(gòu)

說(shuō)到STM32 的HAL庫(kù),就不得不提STM32CubeMX,其作為一個(gè)可視化的配置工具,對(duì)于開(kāi)發(fā)者來(lái)說(shuō),確實(shí)大大節(jié)省了開(kāi)發(fā)時(shí)間。

STM32CubeMX 就是以 HAL 庫(kù)為基礎(chǔ)的,且目前僅支持 HAL 庫(kù)及 LL 庫(kù)!首先看一下,官方給出的 HAL 庫(kù)的包含結(jié)構(gòu):

76286ca0-37c0-11ec-82a8-dac502259ad0.png

7672a518-37c0-11ec-82a8-dac502259ad0.png

stm32f2xx.h 主要包含STM32同系列芯片的不同具體型號(hào)的定義,是否使用HAL庫(kù)等的定義,接著,其會(huì)根據(jù)定義的芯片信號(hào)包含具體的芯片型號(hào)的頭文件:

#ifdefined(STM32F205xx)
#include"stm32f205xx.h"
#elifdefined(STM32F215xx)
#include"stm32f215xx.h"
#elifdefined(STM32F207xx)
#include"stm32f207xx.h"
#elifdefined(STM32F217xx)
#include"stm32f217xx.h"
#else
#error"PleaseselectfirstthetargetSTM32F2xxdeviceusedinyourapplication(instm32f2xx.hfile)"
#endif

緊接著,其會(huì)包含 stm32f2xx_hal.h。

  • stm32f2xx_hal.h:stm32f2xx_hal.c/h 主要實(shí)現(xiàn)HAL庫(kù)的初始化、系統(tǒng)滴答相關(guān)函數(shù)、及CPU的調(diào)試模式配置

  • stm32f2xx_hal_conf.h :該文件是一個(gè)用戶(hù)級(jí)別的配置文件,用來(lái)實(shí)現(xiàn)對(duì)HAL庫(kù)的裁剪,其位于用戶(hù)文件目錄,不要放在庫(kù)目錄中。

接下來(lái)對(duì)于HAL庫(kù)的源碼文件進(jìn)行一下說(shuō)明,HAL庫(kù)文件名均以stm32f2xx_hal開(kāi)頭,后面加上_外設(shè)或者模塊名(如:stm32f2xx_hal_adc.c):

庫(kù)文件:
stm32f2xx_hal_ppp.c/.h//主要的外設(shè)或者模塊的驅(qū)動(dòng)源文件,包含了該外設(shè)的通用API
stm32f2xx_hal_ppp_ex.c/.h//外圍設(shè)備或模塊驅(qū)動(dòng)程序的擴(kuò)展文件。這組文件中包含特定型號(hào)或者系列的芯片的特殊API。以及如果該特定的芯片內(nèi)部有不同的實(shí)現(xiàn)方式,則該文件中的特殊API將覆蓋_ppp中的通用API。
stm32f2xx_hal.c/.h//此文件用于HAL初始化,并且包含DBGMCU、重映射和基于systick的時(shí)間延遲等相關(guān)的API
其他庫(kù)文件
用戶(hù)級(jí)別文件:
stm32f2xx_hal_msp_template.c//只有.c沒(méi)有.h。它包含用戶(hù)應(yīng)用程序中使用的外設(shè)的MSP初始化和反初始化(主程序和回調(diào)函數(shù))。使用者復(fù)制到自己目錄下使用模板。
stm32f2xx_hal_conf_template.h//用戶(hù)級(jí)別的庫(kù)配置文件模板。使用者復(fù)制到自己目錄下使用
system_stm32f2xx.c//此文件主要包含SystemInit()函數(shù),該函數(shù)在剛復(fù)位及跳到main之前的啟動(dòng)過(guò)程中被調(diào)用。**它不在啟動(dòng)時(shí)配置系統(tǒng)時(shí)鐘(與標(biāo)準(zhǔn)庫(kù)相反)**。時(shí)鐘的配置在用戶(hù)文件中使用HAL API來(lái)完成。
startup_stm32f2xx.s//芯片啟動(dòng)文件,主要包含堆棧定義,終端向量表等
stm32f2xx_it.c/.h//中斷處理函數(shù)的相關(guān)實(shí)現(xiàn)
main.c/.h

根據(jù)HAL庫(kù)的命名規(guī)則,其API可以分為以下三大類(lèi):

  • 初始化/反初始化函數(shù):HAL_PPP_Init(), HAL_PPP_DeInit()
  • IO 操作函數(shù):HAL_PPP_Read(), HAL_PPP_Write(),HAL_PPP_Transmit(), HAL_PPP_Receive()
  • 控制函數(shù):HAL_PPP_Set (), HAL_PPP_Get ().
  • 狀態(tài)和錯(cuò)誤:HAL_PPP_GetState (), HAL_PPP_GetError ().

注意:目前 LL 庫(kù)是和 HAL 庫(kù)捆綁發(fā)布的,所以在 HAL 庫(kù)源碼中,還有一些名為 stm32f2xx_ll_ppp 的源碼文件,這些文件就是新增的LL庫(kù)文件。使用 CubeMX 生產(chǎn)項(xiàng)目時(shí),可以選擇LL庫(kù)。

HAL 庫(kù)最大的特點(diǎn)就是對(duì)底層進(jìn)行了抽象。在此結(jié)構(gòu)下,用戶(hù)代碼的處理主要分為三部分:

處理外設(shè)句柄(實(shí)現(xiàn)用戶(hù)功能) 處理MSP 處理各種回調(diào)函數(shù) 外設(shè)句柄定義 ??用戶(hù)代碼的第一大部分:對(duì)于外設(shè)句柄的處理。HAL庫(kù)在結(jié)構(gòu)上,對(duì)每個(gè)外設(shè)抽象成了一個(gè)稱(chēng)為ppp_HandleTypeDef的結(jié)構(gòu)體,其中ppp就是每個(gè)外設(shè)的名字。*所有的函數(shù)都是工作在ppp_HandleTypeDef指針之下。

  1. 多實(shí)例支持:每個(gè)外設(shè)/模塊實(shí)例都有自己的句柄。因此,實(shí)例資源是獨(dú)立的

  2. 外圍進(jìn)程相互通信:該句柄用于管理進(jìn)程例程之間的共享數(shù)據(jù)資源。

下面,以ADC為例

/**
*@briefADChandleStructuredefinition
*/
typedefstruct
{
ADC_TypeDef*Instance;/*!
ADC_InitTypeDefInit;/*!
__IOuint32_tNbrOfCurrentConversionRank;/*!
DMA_HandleTypeDef*DMA_Handle;/*!
HAL_LockTypeDefLock;/*!
__IOuint32_tState;/*!
__IOuint32_tErrorCode;/*!
}ADC_HandleTypeDef;

從上面的定義可以看出,ADC_HandleTypeDef中包含了ADC可能出現(xiàn)的所有定義,對(duì)于用戶(hù)想要使用ADC只要定義一個(gè)ADC_HandleTypeDef的變量,給每個(gè)變量賦好值,對(duì)應(yīng)的外設(shè)就抽象完了。接下來(lái)就是具體使用了。

當(dāng)然,對(duì)于那些共享型外設(shè)或者說(shuō)系統(tǒng)外設(shè)來(lái)說(shuō),他們不需要進(jìn)行以上這樣的抽象,這些部分與原來(lái)的標(biāo)準(zhǔn)外設(shè)庫(kù)函數(shù)基本一樣。例如以下外設(shè):

  • GPIO
  • SYSTICK
  • NVIC
  • RCC
  • FLASH

以GPIO 為例,對(duì)于HAL_GPIO_Init()函數(shù),其只需要GPIO地址以及其初始化參數(shù)即可。

1. 三種編程方式

HAL庫(kù)對(duì)所有的函數(shù)模型也進(jìn)行了統(tǒng)一。在HAL庫(kù)中,支持三種編程模式:輪詢(xún)模式、中斷模式、DMA模式(如果外設(shè)支持)。其分別對(duì)應(yīng)如下三種類(lèi)型的函數(shù)(以ADC為例):

HAL_StatusTypeDefHAL_ADC_Start(ADC_HandleTypeDef*hadc);
HAL_StatusTypeDefHAL_ADC_Stop(ADC_HandleTypeDef*hadc);

HAL_StatusTypeDefHAL_ADC_Start_IT(ADC_HandleTypeDef*hadc);
HAL_StatusTypeDefHAL_ADC_Stop_IT(ADC_HandleTypeDef*hadc);

HAL_StatusTypeDefHAL_ADC_Start_DMA(ADC_HandleTypeDef*hadc,uint32_t*pData,uint32_tLength);
HAL_StatusTypeDefHAL_ADC_Stop_DMA(ADC_HandleTypeDef*hadc);

其中,帶_IT的表示工作在中斷模式下;帶_DMA的工作在DMA模式下(注意:DMA模式下也是開(kāi)中斷的);什么都沒(méi)帶的就是輪詢(xún)模式(沒(méi)有開(kāi)啟中斷的)。至于使用者使用何種方式,就看自己的選擇了。

此外,新的HAL庫(kù)架構(gòu)下統(tǒng)一采用宏的形式對(duì)各種中斷等進(jìn)行配置(原來(lái)標(biāo)準(zhǔn)外設(shè)庫(kù)一般都是各種函數(shù))。針對(duì)每種外設(shè)主要由以下宏:

  • __HAL_PPP_ENABLE_IT(HANDLE,INTERRUPT):使能一個(gè)指定的外設(shè)中斷
  • __HAL_PPP_DISABLE_IT(HANDLE,INTERRUPT):失能一個(gè)指定的外設(shè)中斷
  • __HAL_PPP_GET_IT (HANDLE, __ INTERRUPT __):獲得一個(gè)指定的外設(shè)中斷狀態(tài)
  • __HAL_PPP_CLEAR_IT (HANDLE, __ INTERRUPT __):清除一個(gè)指定的外設(shè)的中斷狀態(tài)
  • __HAL_PPP_GET_FLAG (HANDLE,FLAG):獲取一個(gè)指定的外設(shè)的標(biāo)志狀態(tài)
  • __HAL_PPP_CLEAR_FLAG (HANDLE,FLAG):清除一個(gè)指定的外設(shè)的標(biāo)志狀態(tài)
  • __HAL_PPP_ENABLE(HANDLE) :使能外設(shè)
  • __HAL_PPP_DISABLE(HANDLE) :失能外設(shè)
  • __HAL_PPP_XXXX (HANDLE,PARAM) :指定外設(shè)的宏定義
  • _HAL_PPP_GETIT_SOURCE (HANDLE, __ INTERRUPT __)檢查中斷源

2. 三大回調(diào)函數(shù)

在 HAL 庫(kù)的源碼中,到處可見(jiàn)一些以__weak開(kāi)頭的函數(shù),而且這些函數(shù),有些已經(jīng)被實(shí)現(xiàn)了,比如:

__weakHAL_StatusTypeDefHAL_InitTick(uint32_tTickPriority)
{
/*ConfiguretheSysTicktohaveinterruptin1mstimebasis*/
HAL_SYSTICK_Config(SystemCoreClock/1000U);
/*ConfiguretheSysTickIRQpriority*/
HAL_NVIC_SetPriority(SysTick_IRQn,TickPriority,0U);
/*Returnfunctionstatus*/
returnHAL_OK;
}

有些則沒(méi)有被實(shí)現(xiàn),例如:

__weakvoidHAL_SPI_TxCpltCallback(SPI_HandleTypeDef*hspi)
{
/*Preventunusedargument(s)compilationwarning*/
UNUSED(hspi);
/*NOTE:Thisfunctionshouldnotbemodified,whenthecallbackisneeded,theHAL_SPI_TxCpltCallbackshouldbeimplementedintheuserfile
*/
}

所有帶有__weak關(guān)鍵字的函數(shù)表示,就可以由用戶(hù)自己來(lái)實(shí)現(xiàn)。如果出現(xiàn)了同名函數(shù),且不帶__weak關(guān)鍵字,那么連接器就會(huì)采用外部實(shí)現(xiàn)的同名函數(shù)。通常來(lái)說(shuō),HAL庫(kù)負(fù)責(zé)整個(gè)處理和MCU外設(shè)的處理邏輯,并將必要部分以回調(diào)函數(shù)的形式給出到用戶(hù),用戶(hù)只需要在對(duì)應(yīng)的回調(diào)函數(shù)中做修改即可。HAL 庫(kù)包含如下三種用戶(hù)級(jí)別回調(diào)函數(shù)(PPP為外設(shè)名):

  1. 外設(shè)系統(tǒng)級(jí)初始化/解除初始化回調(diào)函數(shù)(用戶(hù)代碼的第二大部分:對(duì)于MSP的處理):HAL_PPP_MspInit()HAL_PPP_MspDeInit例如:__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)。在HAL_PPP_Init() 函數(shù)中被調(diào)用,用來(lái)初始化底層相關(guān)的設(shè)備(GPIOs, clock, DMA, interrupt)

  2. 處理完成回調(diào)函數(shù)HAL_PPP_ProcessCpltCallback(Process指具體某種處理,如UART的Tx),例如:__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)。當(dāng)外設(shè)或者DMA工作完成后時(shí),觸發(fā)中斷,該回調(diào)函數(shù)會(huì)在外設(shè)中斷處理函數(shù)或者DMA的中斷處理函數(shù)中被調(diào)用

  3. 錯(cuò)誤處理回調(diào)函數(shù)HAL_PPP_ErrorCallback例如:__weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)。當(dāng)外設(shè)或者DMA出現(xiàn)錯(cuò)誤時(shí),觸發(fā)終端,該回調(diào)函數(shù)會(huì)在外設(shè)中斷處理函數(shù)或者DMA的中斷處理函數(shù)中被調(diào)用。

參考文檔及網(wǎng)文鏈接

ST-Description of STM32F4 HAL and LL drivers.pdf
ST-en.stm32_embedded_software_offering.pdf
https://mp.weixin.qq.com/s/GxvIvbxagSPvKuYSXcSVTw

版權(quán)聲明:文章轉(zhuǎn)自網(wǎng)絡(luò)。版權(quán)歸原作者所有,如有侵權(quán),請(qǐng)聯(lián)系我們刪除!

編輯:jq
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10900

    瀏覽量

    356006
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4331

    瀏覽量

    62618
  • HAL
    HAL
    +關(guān)注

    關(guān)注

    2

    文章

    70

    瀏覽量

    12617

原文標(biāo)題:STM32標(biāo)準(zhǔn)庫(kù)和HAL庫(kù)有什么不同?我們?cè)趺从茫?/p>

文章出處:【微信號(hào):mcu168,微信公眾號(hào):硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    HAL庫(kù)在Arduino平臺(tái)上的使用

    ,適合于快速原型開(kāi)發(fā)和教育。HAL(硬件抽象層)庫(kù)是一種在Arduino平臺(tái)上使用的軟件庫(kù),它提供了一種標(biāo)準(zhǔn)化的方式來(lái)訪(fǎng)問(wèn)硬件功能,使得開(kāi)發(fā)者可以編寫(xiě)更通用、更可移植的代碼。 1. 什
    的頭像 發(fā)表于 12-02 14:04 ?284次閱讀

    HAL庫(kù)標(biāo)準(zhǔn)庫(kù)的區(qū)別 HAL庫(kù)與CMSIS的關(guān)系

    在嵌入式系統(tǒng)開(kāi)發(fā)中,HAL(硬件抽象層)庫(kù)標(biāo)準(zhǔn)庫(kù)是兩種常用的軟件庫(kù),它們?cè)诠δ芎褪褂脠?chǎng)景上有所不同。 1.
    的頭像 發(fā)表于 12-02 14:02 ?624次閱讀

    HAL庫(kù)的函數(shù)調(diào)用示例

    HAL(Hardware Abstraction Layer,硬件抽象層)庫(kù)STM32等微控制器中常用的庫(kù),它為開(kāi)發(fā)者提供了訪(fǎng)問(wèn)和控制硬件設(shè)備的接口。以下是一些常用的
    的頭像 發(fā)表于 12-02 14:01 ?370次閱讀

    HAL庫(kù)STM32開(kāi)發(fā)中的重要性

    HAL庫(kù)(Hardware Abstraction Layer Library,硬件抽象層庫(kù))在STM32開(kāi)發(fā)中扮演著至關(guān)重要的角色。以下是HAL
    的頭像 發(fā)表于 12-02 13:35 ?336次閱讀

    如何快速入門(mén)HAL庫(kù)編程 HAL庫(kù)與裸機(jī)編程的比較

    。 選擇開(kāi)發(fā)環(huán)境和工具 : 下載并安裝適用于目標(biāo)微控制器的IDE(如STM32CubeIDE)。 配置開(kāi)發(fā)環(huán)境,包括編譯器、調(diào)試器等。 學(xué)習(xí)HAL庫(kù)文檔和教程 : 閱讀官方HAL
    的頭像 發(fā)表于 12-02 11:39 ?310次閱讀

    HAL庫(kù)在嵌入式系統(tǒng)中的應(yīng)用

    HAL庫(kù)(Hardware Abstraction Layer Library,硬件抽象層庫(kù))在嵌入式系統(tǒng)中扮演著至關(guān)重要的角色。以下是HAL庫(kù)
    的頭像 發(fā)表于 12-02 11:32 ?545次閱讀

    第12章-ADC采集電壓和顯示 基于STM32的ADC—電壓采集(詳細(xì)講解+HAL庫(kù)

    第12章-ADC采集電壓和顯示 基于STM32的ADC—電壓采集(詳細(xì)講解+HAL庫(kù)
    的頭像 發(fā)表于 08-21 16:31 ?2582次閱讀
    第12章-ADC采集電壓和顯示 基于<b class='flag-5'>STM32</b>的ADC—電壓采集(詳細(xì)講解+<b class='flag-5'>HAL</b><b class='flag-5'>庫(kù)</b>)

    STM32F10x標(biāo)準(zhǔn)外設(shè)庫(kù)參考手冊(cè)

    STM32F10x標(biāo)準(zhǔn)外設(shè)庫(kù)參考手冊(cè)
    發(fā)表于 06-24 09:26 ?11次下載

    STM32HAL庫(kù)如何開(kāi)啟FPU?

    求:STM32HAL庫(kù)如何開(kāi)啟FPU?
    發(fā)表于 05-16 07:26

    HAL庫(kù)IAP失敗的原因?

    第一個(gè)項(xiàng)目HAL庫(kù)STM32Cube FW_F1 V1.2.0,生成A_boot.bin,A_app.bin,從A_boot跳轉(zhuǎn)A_app成功 第二個(gè)項(xiàng)目HAL
    發(fā)表于 05-10 08:29

    求助,關(guān)于stm32HAL庫(kù)對(duì)UART采用DMA發(fā)送的地址位標(biāo)志問(wèn)題求解

    stm32 UART多機(jī)通訊可以采用地址喚醒模式,在發(fā)送地址字節(jié)時(shí)設(shè)置USART_DR第9位置1即可,原來(lái)的標(biāo)準(zhǔn)庫(kù)對(duì)這種模式的驅(qū)動(dòng)沒(méi)問(wèn)題,現(xiàn)在最新的HAL驅(qū)動(dòng)
    發(fā)表于 05-09 07:01

    IAP升級(jí),boot和app分別是標(biāo)準(zhǔn)庫(kù)HAL庫(kù)寫(xiě)的,跳轉(zhuǎn)不成功是怎么回事?

    在學(xué)IAP升級(jí)。 我寫(xiě)的app程序是HAL庫(kù)寫(xiě)的,設(shè)置了IROM的起始地址及大小,在程序開(kāi)始后也設(shè)置了中斷向量表偏移地址。 我同事寫(xiě)好的boot程序(
    發(fā)表于 04-24 07:56

    STM32F0的SPL庫(kù)能在STM32G0上嗎?

    原來(lái)用的STM32F0系列,使用的V3.5.0的標(biāo)準(zhǔn)外設(shè)庫(kù)。現(xiàn)在改用STM32G0系列,發(fā)現(xiàn)官網(wǎng)提供的固件庫(kù)
    發(fā)表于 04-08 08:29

    STM32標(biāo)準(zhǔn)庫(kù)程序與HAL庫(kù)程序如何合并的?

    請(qǐng)問(wèn)大家STM32標(biāo)準(zhǔn)款與HAL庫(kù)程序有沒(méi)有合并的教程,或是合并的方法?
    發(fā)表于 04-03 08:02

    STM32F429的工程標(biāo)準(zhǔn)庫(kù)移植到HAL庫(kù)后中斷向量表異常的原因?

    STM32F429的工程標(biāo)準(zhǔn)庫(kù)移植到HAL庫(kù)后中斷向量表異常
    發(fā)表于 03-20 06:02

    主站蜘蛛池模板: 毛片免费高清免费| 乱妇伦小说| 丁香激情六月| 一级毛片aaaaaa视频免费看| 最新毛片网| 欧美freesex交| 国产va免费精品高清在线| 天天躁夜夜躁狠狠躁躁88| 国产亚洲精品久久午夜| 一区二区三区免费在线| 最近2018中文字幕2019视频 | 午夜在线观看免费高清在线播放 | 91大神在线精品视频一区| 黄色xxxx| 亚洲区视频在线观看| 日本三级黄色| 国产高清不卡一区二区| 哥也操| 井野雏田小樱天天被调教| 美女张开大腿让男人捅| 美女被草视频| 日本一区免费观看| 欧美天天视频| 午夜高清免费观看视频| 在线看黄色的网站| 中文字幕不卡在线播放| 美女毛片视频| 精品福利| 速度与激情在线| 国产精品国产三级国产在线观看| 在线视频精品免费| 亚洲欧美在线一区二区 | 亚洲伊人99综合网| 国产精品手机在线| 日本人xxxxxxxxxⅹ69| 宅男在线看片| 口述他拿舌头进去我下面好爽| 国产一卡二卡3卡4卡四卡在线视频| 91p0rn永久备用地址二| 最新欧美伦理网| 亚洲爱爱图片|