筆記:STM32CubeMX-應用指南


toc
資料整理自網絡資料

針對STM32CubeMX,有兩種開發方式

方式1:參考STM32CubeMX初始化代碼,自建工程框架
方式2:使用STM32CubeMX配置片上資源,自動生成工程框架

作為開發者,個人使用方式1,參考STM32CubeMX初始化代碼,自建工程框架
教程參考原子、安富萊、野火等開源教程

軟件版本:STM32CubeMX V5
硬件平台:STM32H750

一、軟件安裝

JRE、STM32CubeMX、HAL庫

二、新建工程

2.1 時鍾配置

2.2 外設配置

2.3 工程配置

2.4 生成工程

2.5 經驗總結

1,自己代碼寫在指定位置(BEGIN---END),否則重新生成工程代碼會被刪除
2,工程目錄最好不包含中文路徑

三、HAL庫相關

1.標准外設庫:Standard Peripheral Libraries,簡寫SPL.
2.Cube硬件抽象層庫:STM32Cube Hardware Abstraction Layer,簡寫Cube HAL.
3.Cube底層庫:STM32Cube Low-Layer,簡寫Cube LL.

STM32 HAL固件庫是Hardware Abstraction Layer的縮寫,中文名稱是:硬件抽象層。HAL庫是ST公司為STM32的MCU最新推出的抽象層嵌入式軟件,為更方便的實現跨STM32產品的最大可移植性



3.1 HAL庫文件


官方給出的HAL庫的包含結構:

stm32f2xx.h:主要包含STM32同系列芯片的不同具體型號的定義,是否使用HAL庫等的定義
stm32f2xx_hal.h:stm32f2xx_hal.c/h 主要實現HAL庫的初始化、系統滴答相關函數、及CPU的調試模式配置
stm32f2xx_hal_conf.h :該文件是一個用戶級別的配置文件,用來實現對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    // 中斷處理函數的相關實現

3.2 HAL API

根據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 ().

HAL庫最大的特點就是對底層進行了抽象。在此結構下,用戶代碼的處理主要分為三部分:
處理外設句柄(實現用戶功能)
處理MSP
處理各種回調函數

3.3 外設句柄

  用戶代碼的第一大部分:對於外設句柄的處理
HAL庫在結構上,對每個外設抽象成了一個稱為ppp_HandleTypeDef的結構體,其中ppp就是每個外設的名字。*所有的函數都是工作在ppp_HandleTypeDef指針之下。
  1. 多實例支持:每個外設/模塊實例都有自己的句柄。 因此,實例資源是獨立的
  2. 外圍進程相互通信:該句柄用於管理進程例程之間的共享數據資源。
下面,以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可能出現的所有定義
  當然,對於那些共享型外設或者說系統外設來說,他們不需要進行以上這樣的抽象,這些部分與原來的標准外設庫函數基本一樣。
例如以下外設:
  - GPIO
  - SYSTICK
  - NVIC
  - RCC
  - FLASH
以GPIO為例,對於HAL_GPIO_Init() 函數,其只需要GPIO 地址以及其初始化參數即可

3.4 三種編程方式-輪詢、中斷、DMA

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.5 三大回調函數

在HAL庫的源碼中,到處可見一些以__weak開頭的函數
所有帶有__weak關鍵字的函數表示,就可以由用戶自己來實現。如果出現了同名函數,且不帶__weak關鍵字,那么連接器就會采用外部實現的同名函數。

通常來說,HAL庫負責整個處理和MCU外設的處理邏輯,並將必要部分以回調函數的形式給出到用戶,用戶只需要在對應的回調函數中做修改即可

  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的中斷處理函數中被調用
    絕大多數用戶代碼均在以上三大回調函數中實現。

HAL庫結構中,在每次初始化前(尤其是在多次調用初始化前),先調用對應的反初始化(DeInit)函數是非常有必要的。某些外設多次初始化時不調用返回會導致初始化失敗。
完成回調函數有多中,例如串口的完成回調函數有HAL_UART_TxCpltCallback 和 HAL_UART_TxHalfCpltCallback等

3.6 HAL庫移植使用

基本步驟

  • 復制stm32f2xx_hal_msp_template.c,參照該模板,依次實現用到的外設的HAL_PPP_MspInit()和 HAL_PPP_MspDeInit。
  • 復制stm32f2xx_hal_conf_template.h,用戶可以在此文件中自由裁剪,配置HAL庫。
    在使用HAL庫時,必須先調用函數:HAL_StatusTypeDef HAL_Init(void)(該函數在stm32f2xx_hal.c中定義,也就意味着第一點中,必須首先實現HAL_MspInit(void)和HAL_MspDeInit(void))

HAL庫與STD庫不同,HAL庫使用RCC中的函數來配置系統時鍾,用戶需要單獨寫時鍾配置函數(STD庫默認在system_stm32f2xx.c中)

關於中斷,HAL提供了中斷處理函數,只需要調用HAL提供的中斷處理函數。用戶自己的代碼,不建議先寫到中斷中,而應該寫到HAL提供的回調函數中。

對於每一個外設,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;,
2, 接着使用初始化句柄(HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef huart))
3, 編寫Msp 例如,建立UartMsp.c,在其中實現
void HAL_UART_MspInit(UART_HandleTypeDef
huart) 和
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
4,實現對應的回調函數 例如,建立UartCallBack.c,在其中實現上文所說明的三大回調函數中的完成回調函數和錯誤回調函數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM