色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

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

全網(wǎng)最全STM32 HAL的知識(shí)總結(jié)

Q4MP_gh_c472c21 ? 來(lái)源:博客園、CSDN ? 作者:csdnpapa、焦糖-布丁 ? 2021-06-28 17:54 ? 次閱讀

ST 為開(kāi)發(fā)者提供了非常方便的開(kāi)發(fā)庫(kù):有標(biāo)準(zhǔn)外設(shè)庫(kù)(SPL庫(kù))、HAL 庫(kù)(Hardware Abstraction Layer,硬件抽象層庫(kù))、LL 庫(kù)(Low-Layer,底層庫(kù))三種。前者是ST的老庫(kù)已經(jīng)停更了,后兩者是ST現(xiàn)在主推的開(kāi)發(fā)庫(kù)。

相比標(biāo)準(zhǔn)外設(shè)庫(kù),STM32Cube HAL庫(kù)表現(xiàn)出更高的抽象整合水平,HAL API集中關(guān)注各外設(shè)的公共函數(shù)功能,這樣便于定義一套通用的用戶(hù)友好的API函數(shù)接口,從而可以輕松實(shí)現(xiàn)從一個(gè)STM32產(chǎn)品移植到另一個(gè)不同的STM32系列產(chǎn)品。HAL庫(kù)是ST未來(lái)主推的庫(kù),ST新出的芯片已經(jīng)沒(méi)有STD庫(kù)了,比如F7系列。目前,HAL庫(kù)已經(jīng)支持STM32全線(xiàn)產(chǎn)品。

通過(guò)文字描述可以知道HAL庫(kù)的幾個(gè)點(diǎn):1.最大可移植性。2.提供了一整套一致的中間件組件,如RTOSUSB,TCP / IP和圖形等。3.通用的用戶(hù)友好的API函數(shù)接口。4.ST新出的芯片已經(jīng)沒(méi)有標(biāo)準(zhǔn)庫(kù)。5.HAL庫(kù)已經(jīng)支持STM32全線(xiàn)產(chǎn)品。

網(wǎng)友認(rèn)為,“HAL我覺(jué)得是極好的,就是SPI接收時(shí)速度實(shí)在太慢,不用DMA的話(huà),吃不消。“

通常新手在入門(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)法很直觀的去真正了解這些不同開(kāi)發(fā)方式彼此之間的區(qū)別,所以筆者想以一種非常直白的方式,用自己的理解去將這些東西表述出來(lái),如果有描述的不對(duì)的地方或者是不同意見(jiàn)的也可以大家提出。

01、直接配置寄存器

不少先學(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)檫@樣更接近原理,知其然也知其所以然。

02、標(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ā)方式,我也就不多闡述了。

03、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ù)。

HAL庫(kù)和標(biāo)準(zhǔn)固件庫(kù)區(qū)別

STM32的開(kāi)發(fā)中,我們可以操作寄存器:

GPIOF-》BSRR=0x00000001;//這里是針對(duì)STM32F1系列

這種方法當(dāng)然可以,但是這種方法的劣勢(shì)是你需要去掌握每個(gè)寄存器的用法,你才能正確使用STM32,而對(duì)于STM32這種級(jí)別的MCU,數(shù)百個(gè)寄存器記起來(lái)又是談何容易。于是ST(意法半導(dǎo)體)推出了官方標(biāo)準(zhǔn)固件庫(kù),標(biāo)準(zhǔn)固件庫(kù)將這些寄存器底層操作都封裝起來(lái),提供一整套接口(API)供開(kāi)發(fā)者調(diào)用,大多數(shù)場(chǎng)合下,你不需要去知道操作的是哪個(gè)寄存器,你只需要知道調(diào)用哪些函數(shù)即可。

比如上面的控制 BRR 寄存器實(shí)現(xiàn)電平控制,官方庫(kù)封裝了一個(gè)函數(shù):

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){GPIOx-》BRR= GPIO_Pin;}

這個(gè)時(shí)候你不需要再直接去操作 BRR 寄存器了,你只需要知道怎么使用 GPIO_ResetBits()這個(gè)函數(shù)就可以了。在你對(duì)外設(shè)的工作原理有一定的了解之后,你再去看標(biāo)準(zhǔn)庫(kù)函數(shù),基本上函數(shù)名字能告訴你這個(gè)函數(shù)的功能是什么,該怎么使用,這樣開(kāi)發(fā)就方便很多。

標(biāo)準(zhǔn)固件庫(kù)自推出以來(lái)受到廣大工程師推崇,現(xiàn)在很多工程師和公司還在使用標(biāo)準(zhǔn)庫(kù)函數(shù)開(kāi)發(fā)。不過(guò),ST官方已經(jīng)不再更新STM32標(biāo)準(zhǔn)固件庫(kù),而是力推新的固件庫(kù):HAL庫(kù)。

比如上面的控制BSRRL 寄存器實(shí)現(xiàn)電平控制,官方 HAL 庫(kù)封裝了一個(gè)函數(shù):

voidHAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,GPIO_PinStatePinState){assert_param(IS_GPIO_PIN(GPIO_Pin));assert_param(IS_GPIO_PIN_ACTION(PinState));if(PinState!= GPIO_PIN_RESET){GPIOx-》BSRR= GPIO_Pin;}else{GPIOx-》BSRR= (uint32_t)GPIO_Pin 《《 16;}}

這個(gè)時(shí)候你不需要再直接去操作BSRRL 寄存器了,你只需要知道怎么使用HAL_GPIO_WritePin這個(gè)函數(shù)就可以了。

標(biāo)準(zhǔn)固件庫(kù)和HAL庫(kù)一樣都是固件庫(kù)函數(shù),由ST官方硬件抽象層而設(shè)計(jì)的軟件函數(shù)包,由程序、數(shù)據(jù)結(jié)構(gòu)和宏組成,包括了STM32所有外設(shè)的性能特征。 這些固件庫(kù)為開(kāi)發(fā)者底層硬件提供了中間API,通過(guò)使用固件庫(kù),無(wú)需掌握底層細(xì)節(jié),開(kāi)發(fā)者就可以輕松應(yīng)用每一個(gè)外設(shè)。

HAL 庫(kù)和標(biāo)準(zhǔn)庫(kù)本質(zhì)上是一樣的,都是提供底層硬件操作 API,而且在使用上也是大同小異。有過(guò)標(biāo)準(zhǔn)庫(kù)基礎(chǔ)的同學(xué)對(duì) HAL 庫(kù)的使用也很容易入手。ST 官方之所以這幾年大力推廣 HAL 庫(kù),是因?yàn)?HAL 的結(jié)構(gòu)更加容易整合 STM32Cube,而 STM32CubeMX 是 ST 這幾年極力推薦的程序生成開(kāi)發(fā)工具。所以這幾年新出的 STM32 芯片,ST 直接只提供 HAL 庫(kù)。

在ST的官方聲明中,HAL庫(kù)是大勢(shì)所趨。ST最新開(kāi)發(fā)的芯片中,只有HAL庫(kù)沒(méi)有標(biāo)準(zhǔn)庫(kù)。標(biāo)準(zhǔn)庫(kù)和HAL庫(kù)雖然都是對(duì)外設(shè)進(jìn)行操作的函數(shù),但由于標(biāo)準(zhǔn)庫(kù)官方已經(jīng)停止更新,而且標(biāo)準(zhǔn)庫(kù)在STM32創(chuàng)建工程和初始化時(shí),不能由CubMX軟件代碼生成使用,也就是說(shuō)CubMX軟件在生產(chǎn)代碼時(shí)。

工程項(xiàng)目和初始化代碼就自動(dòng)生成,這個(gè)工程項(xiàng)目和初始化代碼里面使用的庫(kù)都是基于HAL庫(kù)的。STM32CubeMX是一個(gè)圖形化的工具,也是配置和初始化C代碼生成器 ,與STM32CubeMX配合使用的是HAL庫(kù)(硬件抽象層軟件庫(kù))。

基本配置

工程創(chuàng)建

通過(guò)內(nèi)核芯片的選擇,創(chuàng)建相應(yīng)的工程文件。

對(duì)時(shí)鐘系統(tǒng)進(jìn)行配置,對(duì)引腳及基本功能進(jìn)行配置。

配置時(shí)鐘系統(tǒng)我們首要思考的是:我們需要怎樣的時(shí)鐘系統(tǒng),而不是如何配置時(shí)鐘系統(tǒng)。

配置SWD程序燒錄接口,使用ST-Link進(jìn)行燒錄下載

工程管理設(shè)置推薦圖中所示配置,實(shí)現(xiàn)更快編譯和更簡(jiǎn)潔的文件系統(tǒng)。

點(diǎn)擊“GENERATE CODE”生成Keil工程文件

如果你已經(jīng)安裝了編譯環(huán)境MDK了,可點(diǎn)擊直接打開(kāi)工程。

GPIO使用

開(kāi)發(fā)環(huán)境搭建好以后,可以依開(kāi)始STM32的開(kāi)發(fā),下面是使用GPIO的例程,讓LED燈每隔400ms閃爍一次

打開(kāi)STM32CubeMX新建工程,選擇STM32F103ZET6芯片。選擇外部高速晶振(HSE)。

根據(jù)下位機(jī)主控引腳分配圖及原理圖,選擇LED引腳

PD7為L(zhǎng)ED1輸出控制管腳,選擇GPIO_OUTPUT模式。

點(diǎn)擊Clock Configuration配置系統(tǒng)時(shí)鐘為72M最高速度。

點(diǎn)擊Configuration-》GPIO配置管腳。LED管腳配置為低速推挽輸出模式,既不上拉也不下拉(即默認(rèn)的模式不用配置)。

點(diǎn)擊生成報(bào)告,軟件會(huì)提示新建工程,輸入工程名,選擇工程保存路徑。IDE選擇MDK-ARM V5。

在Code Generator中找到Generated files框,勾選Generated periphera initialization as a pair of ‘.c/.h’files per IP。外設(shè)初始化為獨(dú)立的C文件和頭文件。

點(diǎn)擊生成代碼。點(diǎn)擊Open Project打開(kāi)工程。到這里我們就配置好工程外設(shè)初始化。

點(diǎn)擊Build按鈕,然后等一會(huì),Build Optput信息框會(huì)輸出沒(méi)有錯(cuò)誤沒(méi)有警告。在main函數(shù)里添加如下代碼

延時(shí)電平翻轉(zhuǎn)函數(shù),這樣LED燈就能開(kāi)始閃爍。

再點(diǎn)擊Build按鈕,然后等一會(huì),Build Optput信息框會(huì)輸出沒(méi)有錯(cuò)誤沒(méi)有警告。代碼燒寫(xiě)。

現(xiàn)在開(kāi)始燒寫(xiě)程序,燒寫(xiě)程序有兩種,一種是使用ST-LINK工具燒寫(xiě),一種是直接用與上位機(jī)通訊的串口1燒寫(xiě)。燒寫(xiě)工具使用mcuisp。

軟件可自行網(wǎng)上搜索,下載配置如下。

選擇好串口端口后,可以開(kāi)始下載。

HAL庫(kù)固件庫(kù)安裝與用戶(hù)手冊(cè)

1.首先設(shè)置讓Cube可以自動(dòng)聯(lián)網(wǎng)下載相關(guān)固件庫(kù)選擇updater Settings

2.根據(jù)芯片選擇所需固件版本是向下兼容的,可以直接選擇最新版。但如果覺(jué)得最新版太大,可以閱讀下面的Main Changes.能夠支持你目前的芯片就好。

選好了,點(diǎn)擊Install Now就行,過(guò)程可能有點(diǎn)長(zhǎng)。建議直接官網(wǎng)下載到本地,再安裝

文件會(huì)被下載到如下位置,建議更改此目錄,不要選在C盤(pán)!!!

查找?guī)椭謨?cè)

3.尋找用戶(hù)幫助手冊(cè)進(jìn)入固件所在文件夾,里面包含很多內(nèi)容。

比如說(shuō) 官方提供的開(kāi)發(fā)板程序

每個(gè)型號(hào)下面都有對(duì)應(yīng)功能的實(shí)現(xiàn)

用戶(hù)手冊(cè)就在Drivers文件夾下面。

STM32 HAL庫(kù)與標(biāo)準(zhǔn)庫(kù)的區(qū)別——淺談句柄、MSP函數(shù)、Callback函數(shù)

01句柄

句柄(handle),有多種意義,其中第一種是指程序設(shè)計(jì),第二種是指Windows編程。現(xiàn)在大部分都是指程序設(shè)計(jì)/程序開(kāi)發(fā)這類(lèi)。

· 第一種解釋?zhuān)壕浔且环N特殊的智能指針。當(dāng)一個(gè)應(yīng)用程序要引用其他系統(tǒng)(如數(shù)據(jù)庫(kù)、操作系統(tǒng))所管理的內(nèi)存塊或?qū)ο髸r(shí),就要使用句柄。· 第二種解釋?zhuān)赫麄€(gè)Windows編程的基礎(chǔ)。一個(gè)句柄是指使用的一個(gè)唯一的整數(shù)值,即一個(gè)4字節(jié)(64位程序中為8字節(jié))長(zhǎng)的數(shù)值,來(lái)標(biāo)識(shí)應(yīng)用程序中的不同對(duì)象和同類(lèi)中的不同的實(shí)例。

諸如,一個(gè)窗口,按鈕,圖標(biāo),滾動(dòng)條,輸出設(shè)備,控件或者文件等。應(yīng)用程序能夠通過(guò)句柄訪(fǎng)問(wèn)相應(yīng)的對(duì)象的信息,但是句柄不是指針,程序不能利用句柄來(lái)直接閱讀文件中的信息。如果句柄不在I/O文件中,它是毫無(wú)用處的。句柄是Windows用來(lái)標(biāo)志應(yīng)用程序中建立的或是使用的唯一整數(shù),Windows大量使用了句柄來(lái)標(biāo)識(shí)對(duì)象。

STM32的標(biāo)準(zhǔn)庫(kù)中,句柄是一種特殊的指針,通常指向結(jié)構(gòu)體!

在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_InitTypeDef USART_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è)串口,需要:

· 1、對(duì)六個(gè)位置進(jìn)行賦值,

· 2、然后引用Init函數(shù),

USART_InitStructure并不是一個(gè)全局結(jié)構(gòu)體變量,而是只在函數(shù)內(nèi)部的局部變量,初始化完成之后,USART_InitStructure就失去了作用。

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

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;

我們發(fā)現(xiàn),與標(biāo)準(zhǔn)庫(kù)不同的是,該成員不僅:

· 1、包含了之前標(biāo)準(zhǔn)庫(kù)就有的六個(gè)成員(波特率,數(shù)據(jù)格式等),· 2、還包含過(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);

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

void HAL_UART_MspInit(UART_HandleTypeDef *huart);void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);

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

02MSP函數(shù)

MSP: 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í)。可以說(shuō)各有利弊。

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

void HAL_UART_MspInit(UART_HandleTypeDef *huart);

入口參數(shù)僅僅需要一個(gè)串口句柄,這樣就能看出句柄的方便。

03Callback函數(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ì)顯得很混亂:

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

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

void USART1_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*/u8 aRxBuffer[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ù):

void HAL_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ù)雜的代碼量,極慢的編譯速度,略微低下的效率。看怎么取舍了。

04STM32 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):

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

#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

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

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

· 4.3 stm32f4xx_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ù)文件名均以stm32f4xx_hal開(kāi)頭,后面加上_外設(shè)或者模塊名(如:stm32f4xx_hal_adc.c):

· 4.4 庫(kù)文件

stm32f4xx_hal_ppp.c/.h // 主要的外設(shè)或者模塊的驅(qū)動(dòng)源文件,包含了該外設(shè)的通用API

stm32f4xx_hal_ppp_ex.c/.h // 外圍設(shè)備或模塊驅(qū)動(dòng)程序的擴(kuò)展文件。這組文件中包含特定型號(hào)或者系列的芯片的特殊API。以及如果該特定的芯片內(nèi)部有不同的實(shí)現(xiàn)方式,則該文件中的特殊API將覆蓋_ppp中的通用API

stm32f4xx_hal.c/.h // 此文件用于HAL初始化,并且包含DBGMCU、重映射和基于systick的時(shí)間延遲等相關(guān)的API

· 4.5 其他庫(kù)文件

用戶(hù)級(jí)別文件:

stm32f4xx_hal_msp_template.c // 只有.c沒(méi)有.h。它包含用戶(hù)應(yīng)用程序中使用的外設(shè)的MSP初始化和反初始化(主程序和回調(diào)函數(shù))。使用者復(fù)制到自己目錄下使用模板。

stm32f4xx_hal_conf_template.h // 用戶(hù)級(jí)別的庫(kù)配置文件模板。使用者復(fù)制到自己目錄下使用

system_stm32f4xx.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_stm32f4xx.s // 芯片啟動(dòng)文件,主要包含堆棧定義,終端向量表等stm32f4xx_it.c/.h // 中斷處理函數(shù)的相關(guān)實(shí)現(xiàn)

· 4.6 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ù)

相關(guān)知識(shí)如下:

· (1) 外設(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為例

/** * @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可能出現(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ù)即可。

· (2) 三種編程方式??HAL庫(kù)對(duì)所有的函數(shù)模型也進(jìn)行了統(tǒng)一。在HAL庫(kù)中,支持三種編程模式:輪詢(xún)模式、中斷模式、DMA模式(如果外設(shè)支持)。其分別對(duì)應(yīng)如下三種類(lèi)型的函數(shù)(以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模式下也是開(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_GET IT_SOURCE (HANDLE, __ INTERRUPT __):檢查中斷源

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

__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;}

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

__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關(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 voidHAL_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)用

絕大多數(shù)用戶(hù)代碼均在以上三大回調(diào)函數(shù)中實(shí)現(xiàn)。

HAL庫(kù)結(jié)構(gòu)中,在每次初始化前(尤其是在多次調(diào)用初始化前),先調(diào)用對(duì)應(yīng)的反初始化(DeInit)函數(shù)是非常有必要的。某些外設(shè)多次初始化時(shí)不調(diào)用返回會(huì)導(dǎo)致初始化失敗。完成回調(diào)函數(shù)有多種,例如串口的完成回調(diào)函數(shù)有HAL_UART_TxCpltCallback 和 HAL_UART_TxHalfCpltCallback等(用戶(hù)代碼的第三大部分:對(duì)于上面第二點(diǎn)和第三點(diǎn)的各種回調(diào)函數(shù)的處理)在實(shí)際使用中,發(fā)現(xiàn)HAL仍有不少問(wèn)題,例如在使用USB時(shí),其庫(kù)配置存在問(wèn)題

05HAL庫(kù)移植使用

基本步驟

1.復(fù)制stm32f2xx_hal_msp_template.c,參照該模板,依次實(shí)現(xiàn)用到的外設(shè)的HAL_PPP_MspInit()和 HAL_PPP_MspDeInit。

2.復(fù)制stm32f2xx_hal_conf_template.h,用戶(hù)可以在此文件中自由裁剪,配置HAL庫(kù)。

3.在使用HAL庫(kù)時(shí),必須先調(diào)用函數(shù):HAL_StatusTypeDef HAL_Init(void)(該函數(shù)在stm32f2xx_hal.c中定義,也就意味著第一點(diǎn)中,必須首先實(shí)現(xiàn)HAL_MspInit(void)和HAL_MspDeInit(void))

4.HAL庫(kù)與STD庫(kù)不同,HAL庫(kù)使用RCC中的函數(shù)來(lái)配置系統(tǒng)時(shí)鐘,用戶(hù)需要單獨(dú)寫(xiě)時(shí)鐘配置函數(shù)(STD庫(kù)默認(rèn)在system_stm32f2xx.c中)

5.關(guān)于中斷,HAL提供了中斷處理函數(shù),只需要調(diào)用HAL提供的中斷處理函數(shù)。用戶(hù)自己的代碼,不建議先寫(xiě)到中斷中,而應(yīng)該寫(xiě)到HAL提供的回調(diào)函數(shù)中。

6.對(duì)于每一個(gè)外設(shè),HAL都提供了回調(diào)函數(shù),回調(diào)函數(shù)用來(lái)實(shí)現(xiàn)用戶(hù)自己的代碼。整個(gè)調(diào)用結(jié)構(gòu)由HAL庫(kù)自己完成。例如:Uart中,HAL提供了void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);函數(shù),用戶(hù)只需要觸發(fā)中斷后,用戶(hù)只需要調(diào)用該函數(shù)即可,同時(shí),自己的代碼寫(xiě)在對(duì)應(yīng)的回調(diào)函數(shù)中即可!如下:

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

使用了哪種就用哪個(gè)回調(diào)函數(shù)即可!

基本結(jié)構(gòu)?綜上所述,使用HAL庫(kù)編寫(xiě)程序(針對(duì)某個(gè)外設(shè))的基本結(jié)構(gòu)(以串口為例)如下:

1.配置外設(shè)句柄 例如,建立UartConfig.c,在其中定義串口句柄 UART_HandleTypeDef huart;,接著使用初始化句柄(HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef huart))

2.編寫(xiě)Msp 例如,建立UartMsp.c,在其中實(shí)現(xiàn)void HAL_UART_MspInit(UART_HandleTypeDef huart) 和 void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)

3.實(shí)現(xiàn)對(duì)應(yīng)的回調(diào)函數(shù) 例如,建立UartCallBack.c,在其中實(shí)現(xiàn)上文所說(shuō)明的三大回調(diào)函數(shù)中的完成回調(diào)函數(shù)和錯(cuò)誤回調(diào)函數(shù)

編輯:jq

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

    關(guān)注

    31

    文章

    5363

    瀏覽量

    121083
  • ST
    ST
    +關(guān)注

    關(guān)注

    32

    文章

    1137

    瀏覽量

    129140
  • STM32
    +關(guān)注

    關(guān)注

    2272

    文章

    10923

    瀏覽量

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

    關(guān)注

    3

    文章

    4345

    瀏覽量

    62937
  • dma
    dma
    +關(guān)注

    關(guān)注

    3

    文章

    566

    瀏覽量

    100908

原文標(biāo)題:STM32 HAL的超全知識(shí)總結(jié)

文章出處:【微信號(hào):gh_c472c2199c88,微信公眾號(hào):嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    STM32F1開(kāi)發(fā)指南

    這本書(shū)詳細(xì)講述了STM32HAL庫(kù)開(kāi)發(fā)的配置流程,非常詳細(xì)
    發(fā)表于 01-21 15:33 ?0次下載

    STM32CubeMX生成的代碼,是怎樣的HAL架構(gòu)?

    需要注意,CubeMX只是一個(gè)初始化工具,它只是幫你完成了HAL庫(kù)外設(shè)和時(shí)鐘的初始化,具體程序的編寫(xiě)還需要查閱HAL庫(kù)的說(shuō)明,使用相關(guān)函數(shù)實(shí)現(xiàn)你想實(shí)現(xiàn)的功能。CubeMX生成的代碼包含了豐富的注釋
    的頭像 發(fā)表于 01-01 21:01 ?187次閱讀
    <b class='flag-5'>STM32</b>CubeMX生成的代碼,是怎樣的<b class='flag-5'>HAL</b>架構(gòu)?

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

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

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

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

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

    如何快速入門(mén)HAL庫(kù)編程 要快速入門(mén)HAL庫(kù)編程,可以遵循以下步驟: 了解基礎(chǔ)知識(shí) : 掌握C語(yǔ)言編程基礎(chǔ),包括變量、數(shù)據(jù)類(lèi)型、函數(shù)、指針等。 了解嵌入式系統(tǒng)的基本概念,如微控制器、中斷、外設(shè)等
    的頭像 發(fā)表于 12-02 11:39 ?418次閱讀

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

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

    stm32H7 HAL庫(kù)中存在的bug

    stm32H7 hal 庫(kù)里面的以太網(wǎng)代碼,坑了魚(yú)鷹很多次(不知道最新版是否已經(jīng)修復(fù)了這些bug),這里分享一篇網(wǎng)上的文章,因?yàn)轸~(yú)鷹也遇到過(guò),靠它解決了其中一個(gè)編譯優(yōu)化問(wèn)題,在此感謝作者。不過(guò)hal
    的頭像 發(fā)表于 08-12 17:37 ?1357次閱讀

    課程上線(xiàn) | STM32單片機(jī)入門(mén)教程(1)基于HAL庫(kù)的多核心開(kāi)發(fā)(F1/F4/G0/U5)

    ?好消息!華清遠(yuǎn)見(jiàn)STM32入門(mén)視頻課程《基于HAL庫(kù)的STM32多核心開(kāi)發(fā)》正式上線(xiàn),已更新90講,持續(xù)更新中,8月份將全部上線(xiàn)。課程優(yōu)勢(shì)真人出鏡,手把手教學(xué)一板玩轉(zhuǎn)STM32多型號(hào)
    的頭像 發(fā)表于 08-08 16:42 ?434次閱讀
    課程上線(xiàn) | <b class='flag-5'>STM32</b>單片機(jī)入門(mén)教程(1)基于<b class='flag-5'>HAL</b>庫(kù)的多核心開(kāi)發(fā)(F1/F4/G0/U5)

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

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

    模擬電子技術(shù)知識(shí)點(diǎn)問(wèn)題總結(jié)概覽

    給大家分享模擬電子技術(shù)知識(shí)點(diǎn)問(wèn)題總結(jié)
    的頭像 發(fā)表于 05-08 15:16 ?1228次閱讀
    模擬電子技術(shù)<b class='flag-5'>知識(shí)</b>點(diǎn)問(wèn)題<b class='flag-5'>總結(jié)</b>概覽

    STM32 HAL串口接收中斷突然失效的原因?

    STM32 HAL 串口接收中斷突然失效
    發(fā)表于 04-08 06:40

    STM32CubeMX HAL_UART_Receive函數(shù)怎么使用?

    STM32CubeMX HAL_UART_Receive函數(shù)的使用
    發(fā)表于 04-03 08:19

    STM32蜂鳴器音樂(lè)播放實(shí)例教程

    開(kāi)啟定時(shí)器TIM7,是為了寫(xiě)延時(shí)函數(shù)HAL_Delay_us()。具體過(guò)程請(qǐng)移步此文:STM32HAL庫(kù)實(shí)現(xiàn)自定義延時(shí)函數(shù)delay_us(),文末附代碼。
    發(fā)表于 03-26 14:19 ?2266次閱讀
    <b class='flag-5'>STM32</b>蜂鳴器音樂(lè)播放實(shí)例教程

    STM32G HAL庫(kù)中HAL_init()代碼中,為什么SysTick_Config函數(shù)不調(diào)用?

    STM32G HAL庫(kù)中HAL_init()代碼中,為什么SysTick_Config函數(shù)不調(diào)用?
    發(fā)表于 03-12 07:46

    HAL src如何把stm32h7xx_hal_flash.c文件添加到src目錄?

    HAL src里怎么添加stm32h7xx_hal_flash.c文件到src目錄
    發(fā)表于 02-23 06:57
    主站蜘蛛池模板: 精品国产mmd在线观看 | 韩国伦理片2018在线播放免费观看 | 51久久成人国产精品麻豆 | 超碰最新地址 | RUNAWAY韩国动漫免费官网版 | 一本道在线综合久久88 | 成片免费观看视频大全 | AV天堂午夜精品一区 | 91进入蜜桃臀在线播放 | 偷窥wc美女毛茸茸视频 | 狠狠撸亚洲视频 | 亚洲精品视频免费观看 | 久热在线这里只有精品7 | 55夜色66夜亚洲精品播放 | 暖暖 视频 免费 高清 在线观看 | 国产亚洲精品精华液 | 毛片免费在线 | 亚洲乱码爆乳精品成人毛片 | 一本色道久久综合亚洲AV蜜桃 | 野花社区视频WWW高清 | 亚洲精品无码成人AAA片 | 日日干夜夜啪蕉视频 | 成年色黄APP下载 | 被滋润的艳妇疯狂呻吟白洁老七 | 亚洲精品线在线观看 | 久久国产高清字幕中文 | 亚洲色欲色欲WWW在线丝 | 乌克兰肛交影视 | 幼儿交1300部一区二区 | 国产色婷婷亚洲99精品 | 狠狠色色综合站 | 欧美人与禽ZOZO性伦交视频 | 成人啪啪色婷婷久色社区 | 九九在线精品亚洲国产 | 亚洲精品免播放器在线观看 | BLACKED太粗太长 | 亚洲欧洲精品A片久久99 | 国产一区免费在线观看 | 手机伊在人线香蕉2 | 久久精品视频在线看 | 国产色无码精品视频国产 |