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

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

STM32的HAL庫與標準庫的區別

科技綠洲 ? 來源:STM32嵌入式開發 ? 作者:STM32嵌入式開發 ? 2023-06-22 11:43 ? 次閱讀

新手在入門 STM32 的時候,一般大多數都會選用標準庫和 HAL 庫,而極少部分人會通過直接配置寄存器進行開發。

對于剛入門的朋友,可能沒法直觀了解這些不同開發發方式之間的區別,本文試圖以一種非常直白的方式,用自己的理解去將這些東西表述出來。

配置寄存器

不少先學了 51單片機的朋友可能會知道,會有一小部分人或教程是通過匯編語言直接操作寄存器實現功能的,這種方法到了 STM32 就變得不太容易行得通了。

因為 STM32 的寄存器數量是 51單片機的十數倍,如此多的寄存器根本無法全部記憶,開發時需要經常的翻查芯片的數據手冊,此時直接操作寄存器就變得非常的費力了。也有人喜歡去直接操作寄存器,因為這樣更接近原理,代碼更少,知其然也知其所以然。

標準庫

上面也提到了,STM32 有非常多的寄存器,而導致了開發困難,所以為此 ST 公司就為每款芯片都編寫了一份庫文件,也就是工程文件里 stm32F1xx..... 之類的。在這些 .c 與 .h 文件中,包括一些常用量的宏定義,把一些外設也通過結構體變量封裝起來,如 GPIO、時鐘等。

所以我們只需要配置結構體變量成員就可以修改外設的配置寄存器,從而選擇不同的功能。也是目前最多人使用的方式,也是學習 STM32 接觸最多的一種開發方式,我也就不多闡述了。

HAL庫

HAL 庫是 ST 公司目前主推的開發方式,全稱就是 Hardware Abstraction Layer(抽象印象層),簡單來說就是弱化了開發者對硬件底層知識的依賴。

同樣的功能,標準庫可能要用幾句話,HAL 庫只需用一句話就夠了。并且 HAL 庫也很好地解決了程序移植的問題。不同型號的 STM32 芯片它的標準庫是不一樣的,例如在F4 上開發的程序移植到 F3 上是不能通用的,而使用 HAL 庫,只要使用的是相同的外設,程序基本可以完全復制粘貼。注意是相同外設,意思也就是不能無中生有。例如 F7 比 F3 要多幾個定時器,不能明明沒有這個定時器卻非要配置,但其實這種情況不多,絕大多數都可以直接復制粘貼。

而且使用 ST 公司研發的 STMcube 軟件,可以通過圖形化的配置功能,直接生成整個適用于HAL庫的工程文件,可以說是方便至極。但是方便的同時也造成了它執行效率偏低。

綜合上面說的,其實筆者還是強烈推薦 HAL 庫的,理由:

  • ST 公司已經停止更新標準庫,公司主打 HAL 庫的目的已經非常明顯了;
  • 模塊化的 HAL 庫是趨勢,低效的短板會被硬件的增強所彌補。

當然底層的基本原理是必須要懂的,HAL 庫也不是萬能的,結合對底層的理解相信一定會讓你的開發水準大大提高。

HAL庫與標準庫的區別

1 句柄

在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

可以看到,要初始化一個串口,需要對六個位置進行賦值,然后引用 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;

我們發現,與標準庫不同的是,該成員不僅包含了之前標準庫就有的六個成員(波特率,數據格式等),還包含過采樣、(發送或接收的)數據緩存、數據指針、串口 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函數

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;
  //接收中斷(接收到的數據必須是0x0d 0x0a結尾)
  if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
  {
    //讀取接收到的數據
    Res =USART_ReceiveData(USART3); 


    /*數據處理區*/
  } 
}

而在HAL庫中,進入串口中斷后,直接由 HAL 庫中斷函數進行托管:

void USART1_IRQHandler(void)                 
{
  //調用HAL庫中斷處理公用函數
  HAL_UART_IRQHandler(&UART1_Handler); 


  /***************省略無關代碼****************/ 
}

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 庫的可移植性之強大,并且用戶可以完全不去理會底層各個寄存器的操作,代碼也更有邏輯性。但由此帶來的是復雜的代碼量,極慢的編譯速度,略微低下的效率。看怎么取舍了。

HAL庫的結構

說到 STM32 的 HAL庫,就不得不提 STM32CubeMX,其作為一個可視化的配置工具,對于開發者來說,確實大大節省了開發時間。另外 STM32CubeIDE 集成了STM32CubeMX 的功能,是一個集配置與編譯于一體的軟件,可以嘗試一下。軟件更新頻率很高,持續優化某些 bug 及性能問題。

圖片

上面兩個開發軟件是以 HAL 庫為基礎的,且目前僅支持 HAL 庫及LL庫!

首先看一下,官方給出的HAL庫的文件結構:

圖片

下圖是STM32庫文件結構。

圖片

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

#if defined(STM32F205xx)
#include "stm32f205xx.h"
#elif defined(STM32F215xx)
#include "stm32f215xx.h"
#elif defined(STM32F207xx)
#include "stm32f207xx.h"
#elif defined(STM32F217xx)
#include "stm32f217xx.h"
#else
#error "Please select first the target STM32F2xx device used in your application (in stm32f2xx.h file)"
#endif

緊接著,其會包含 stm32f2xx_hal.h。

  • stm32f2xx_hal.h:stm32f2xx_hal.c/h 主要實現 HAL 庫的初始化、系統滴答時鐘相關的函數、及 CPU 的調試模式配置
  • stm32f2xx_hal_conf.h :該文件是一個用戶級別的配置文件,用來實現對 HAL 庫的裁剪,其位于用戶文件目錄,不要放在庫目錄中。

接下來對于HAL庫的源碼文件進行一下說明,HAL 庫文件名均以 stm32f2xx_hal 開頭,后面加上_外設或者模塊名(如:stm32f2xx_hal_adc.c):

庫文件:
 stm32f2xx_hal_ppp.c/.h   // 主要的外設或者模塊的驅動源文件,包含了該外設的通用API
 stm32f2xx_hal_ppp_ex.c/.h  // 外圍設備或模塊驅動程序的擴展文件。這組文件中包含特定型號或者系列的芯片的特殊API。以及如果該特定的芯片內部有不同的實現方式,則該文件中的特殊API將覆蓋_ppp中的通用API。
 stm32f2xx_hal.c/.h    // 此文件用于HAL初始化,并且包含DBGMCU、重映射和基于systick的時間延遲等相關的API
 其他庫文件
用戶級別文件:
 stm32f2xx_hal_msp_template.c // 只有.c沒有.h。它包含用戶應用程序中使用的外設的MSP初始化和反初始化(主程序和回調函數)。使用者復制到自己目錄下使用模板。
 stm32f2xx_hal_conf_template.h // 用戶級別的庫配置文件模板。使用者復制到自己目錄下使用
 system_stm32f2xx.c    // 此文件主要包含SystemInit()函數,該函數在剛復位及跳到main之前的啟動過程中被調用。**它不在啟動時配置系統時鐘(與標準庫相反)**。時鐘的配置在用戶文件中使用HAL API來完成。
 startup_stm32f2xx.s    // 芯片啟動文件,主要包含堆棧定義,終端向量表等
 stm32f2xx_it.c/.h    // 中斷處理函數的相關實現
 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
  • 處理各種回調函數,外設句柄定義

HAL 庫在結構上,對每個外設抽象成了一個稱為 ppp_HandleTypeDef 的結構體,其中 ppp 就是每個外設的名字。所有的函數都是工作在 ppp_HandleTypeDef 指針之下。

每個外設/模塊實例都有自己的句柄。因此,實例資源是獨立的。

外圍進程相互通信:該句柄用于管理進程例程之間的共享數據資源。

下面,以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 可能出現的所有定義,對于用戶想要使用 ADC 只要定義一個 ADC_HandleTypeDef 的變量,給每個變量賦好值,對應的外設就抽象完了。接下來就是具體使用了。

當然,對于那些共享型外設或者說系統外設來說,他們不需要進行以上這樣的抽象,這些部分與原來的標準外設庫函數基本一樣。例如以下外設:

  • GPIO
  • SYSTICK
  • NVIC
  • RCC
  • FLASH

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

1 三種編程方式

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 __) 檢查中斷源

2 三大回調函數

在 HAL 庫的源碼中,到處可見一些以__weak開頭的函數,而且這些函數,有些已經被實現了,比如:

圖片

有些則沒有被實現,例如:

__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 的中斷處理函數中被調用。
  3. 錯誤處理回調函數:HAL_PPP_ErrorCallback例如:__weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)。當外設或者 DMA 出現錯誤時,觸發終端,該回調函數會在外設中斷處理函數或者DMA的中斷處理函數中被調用。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5369

    瀏覽量

    121275
  • STM32
    +關注

    關注

    2273

    文章

    10926

    瀏覽量

    357767
  • HAL
    HAL
    +關注

    關注

    2

    文章

    71

    瀏覽量

    12688
收藏 人收藏

    評論

    相關推薦

    STM32標準HAL和LL介紹

    我們在進行STM32開發的時候,使用寄存器進行開發的終究是少數,大多數人還是習慣用庫函數進行開發。到目前為止,有標準外設HAL、LL
    發表于 06-21 15:13 ?1.4w次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>標準</b><b class='flag-5'>庫</b>、<b class='flag-5'>HAL</b><b class='flag-5'>庫</b>和LL<b class='flag-5'>庫</b>介紹

    stm32hal標準有什么區別

    stm32hal標準有什么區別
    發表于 07-20 08:20

    HAL標準的原理區別

    HAL的學習HAL標準的原理區別串口通信實驗
    發表于 07-29 08:48

    標準HAL有啥區別

    “健康守護者”——STM32標準HAL的比較使用STM32芯片的時候呢,大家可能都喜歡用
    發表于 08-04 08:22

    STM32標準HAL有哪些不同

    STM32標準HAL有哪些不同?標準
    發表于 10-21 07:44

    STM32 HAL標準區別有哪些

    STM32的開發方式有哪幾種?怎樣去安裝HAL固件呢?STM32 HAL
    發表于 10-25 07:49

    HAL標準有哪些區別

    什么是HAL標準又是什么?HAL標準
    發表于 10-26 06:54

    請問STM32 HAL標準區別是什么?

    請問STM32 HAL標準區別是什么?
    發表于 11-25 08:43

    STM32 HAL標準區別在哪

    最近筆者開始學習STM32HAL,由于以前一直用標準進行開發,于是發現了HAL
    發表于 02-15 07:03

    STM32標準改為HAL的程序實現

    標準占絕大多數,自己買的板子跟的資料也一般是標準HAL很少,不過要是使用
    發表于 11-22 11:23 ?3.5w次閱讀

    STM32四種對比:寄存器、標準外設HAL、LL

    1.我是選擇寄存器開發STM32,還是標準外設呢? 2.你有STM32L0標準外設嗎? 3.
    發表于 03-05 06:17 ?50次下載
    <b class='flag-5'>STM32</b>四種<b class='flag-5'>庫</b>對比:寄存器、<b class='flag-5'>標準</b>外設<b class='flag-5'>庫</b>、<b class='flag-5'>HAL</b>、LL

    STM32 HAL標準區別_淺談句柄、MSP函數、Callback函數

    最近筆者開始學習STM32HAL,由于以前一直用標準進行開發,于是發現了HAL
    發表于 12-16 16:57 ?30次下載
    <b class='flag-5'>STM32</b> <b class='flag-5'>HAL</b><b class='flag-5'>庫</b>與<b class='flag-5'>標準</b><b class='flag-5'>庫</b>的<b class='flag-5'>區別</b>_淺談句柄、MSP函數、Callback函數

    STM32 HAL標準區別

    ??相比較早幾年使用標準開發來講,最近幾年HAL的使用是越來越多,那么我們開發應當使用哪一種呢,本文著重介紹常用的幾種開發方式及相互之間的區別
    的頭像 發表于 03-22 09:13 ?1.5w次閱讀

    stm32 hal資料分享

    stm32 hal資料分享
    發表于 11-03 16:17 ?120次下載

    STM32 HAL的功能和使用方法 STM32 HAL標準區別

    和可維護性,從而節省開發成本和時間。STM32 HALSTM32系列芯片的HAL,由ST公
    發表于 08-08 18:21 ?4844次閱讀
    主站蜘蛛池模板: 最近视频在线播放免费观看 | 日韩一级黄色录像 | 久久天天躁狠狠躁夜夜躁 | 黄视频网站入口 | 欧美视频亚洲色图 | 理论在线看 | 午夜无遮挡怕怕怕免费视频 | jizz免费一区二区三区 | 久久99精品久久久久久秒播 | 干干干日日日 | 嫩草影院播放地址一二三 | 国产精品9999久久久久仙踪林 | 欧美性受xxxx | 天天干夜夜添 | www五月天com| 亚洲一成人毛片 | 国产精品嫩草影院人体模特 | 一区二区在线看 | 激情五月宗合网 | 国产一区二区三区在线观看影院 | 久色中文| 国产在线精品美女观看 | 特级无码毛片免费视频尤物 | 婷婷四房播客五月天 | h网站亚洲 | 亚洲成人网在线 | 九九re热| 国产精品一级毛片不收费 | 欧美一卡2卡三卡四卡五卡 欧美一卡二卡3卡4卡无卡六卡七卡科普 | 午夜精品久久久久久久 | avtt天堂网永久资源 | 黄色a∨| аⅴ天堂中文在线网 | 永久黄网站色视频免费 | www.一区二区三区 | 久久国产美女免费观看精品 | 狠狠色欧美亚洲狠狠色www | 日日噜噜夜夜狠狠va视频 | 国产毛片久久久久久国产毛片 | 人人搞人人爽 | 奇米第四狠狠777高清秒播 |