hal库选择滴答时钟函数_stm32h7“理解hal库框架”
1、按照初始化流程調(diào)用的hal庫文件
完成初始化工作需要調(diào)用到的hal庫文件,如下表
序號功能調(diào)用hal庫文件
1Module Selection(模塊選擇)
Oscillator Values adaptation(晶振值配置)
System Configuration(系統(tǒng)配置:VDD值、滴答定時器初始優(yōu)先級、選擇是否使用操作系統(tǒng))
Ethernet Configuration(以太網(wǎng)配置)
Assert Selection(選擇是否使用斷言)
SPI peripheral configuration(SPI外設配置)stm32h7xx_hal_conf.h
2系統(tǒng)上電復位
復位中斷調(diào)用函數(shù)SystemInit和__mainstartup_stm32h743xx.s
system_stm32h7xx.c
3初始化MPUstm32h7xx_hal_cortex.h
stm32h7xx_hal_cortex.c
4初始化Cachecore_cm7.h
5初始化HAL庫stm32h7xx_hal.c
6配置系統(tǒng)時鐘stm32h7xx_hal_rcc.c
7初始化各種外設hal庫外設文件
上表中序號3至7用程序表示是初始化所有設備,如代碼1
代碼1/*
*********************************************************************************************************
* 函 數(shù) 名: bsp_Init
* 功能說明: 初始化所有的硬件設備。該函數(shù)配置CPU寄存器和外設的寄存器并初始化一些全局變量。只需要調(diào)用一次
* 形 參:無
* 返 回 值: 無
*********************************************************************************************************
*/
void bsp_Init(void)
{
/* 配置MPU */
MPU_Config();
/* 使能L1 Cache */
CPU_CACHE_Enable();
/*
STM32H7xx HAL 庫初始化,此時系統(tǒng)用的還是H7自帶的64MHz,HSI時鐘:
- 調(diào)用函數(shù)HAL_InitTick,初始化滴答時鐘中斷1ms。
- 設置NVIV優(yōu)先級分組為4。
*/
HAL_Init();
/*
配置系統(tǒng)時鐘到400MHz
- 切換使用HSE。
- 此函數(shù)會更新全局變量SystemCoreClock,并重新配置HAL_InitTick。
*/
SystemClock_Config();
/*
Event Recorder:
- 可用于代碼執(zhí)行時間測量,MDK5.25及其以上版本才支持,IAR不支持。
- 默認不開啟,如果要使能此選項,務必看V7開發(fā)板用戶手冊第8章
*/
#if Enable_EventRecorder == 1
/* 初始化EventRecorder并開啟 */
EventRecorderInitialize(EventRecordAll, 1U);
EventRecorderStart();
#endif
bsp_InitUart(); /* 初始化串口 */
bsp_InitKey(); /* 按鍵初始化,要放在滴答定時器之前,因為按鈕檢測是通過滴答定時器掃描 */
bsp_InitTimer(); /* 初始化滴答定時器 */
bsp_InitExtIO(); /* 初始化FMC總線74HC574擴展IO. 必須在 bsp_InitLed()前執(zhí)行 */
bsp_InitLed(); /* 初始化LED */
}
第12–15行,配置 MPU 和使能 Cache。
對于H7,這兩個函數(shù)要優(yōu)先執(zhí)行,因為 Flash 速度,SRAM 速度跟 CPU 和 TCM 有些差距的,所以要使能 Cache。而不同存儲區(qū)的 Cache 策略要通過MPU 分別進行配置。
第22行,調(diào)用HAL_Init函數(shù)。
調(diào)用HAL_Init函數(shù)時,系統(tǒng)依然使用的 64MHz HSI 時鐘,這點要特別注意。 此函數(shù)會調(diào)用函數(shù)HAL_InitTick(stm32h7xx_hal.c文件中),初始化滴答時鐘中斷 1ms,并設置 NVIV 優(yōu)先級分組為 4。這里就隱含了一個知識點,就是它會開啟滴答定時器中斷,如果用戶也要使用滴答定時器中斷,此問題就要引起注意,bsp_timer.c文件中void SysTick_Handler(void) 函數(shù)加了一個狀態(tài)標志判斷,只有當使用了定時器初始化函數(shù)才能進入用戶滴答定時器中斷,否則只能執(zhí)行到系統(tǒng)滴答定時器中斷。
第29行,通過此函數(shù)切換 HSI 到外部高速時鐘 HSE,并配置系統(tǒng)時鐘到400MHz。調(diào)用這個函數(shù)會更新全局變量SystemCoreClock,并重新配置HAL_InitTick。
2、hal文件分別學習
2-1、stm32h7xx_hal_conf.h
該文件主要實現(xiàn)功能如下
Module Selection(模塊選擇)
Oscillator Values adaptation(晶振值配置)
System Configuration(系統(tǒng)配置:VDD值、滴答定時器初始優(yōu)先級、選擇是否使用操作系統(tǒng))
Ethernet Configuration(以太網(wǎng)配置)
Assert Selection(選擇是否使用斷言)
SPI peripheral configuration(SPI外設配置)
其中截取Oscillator Values adaptation(晶振值配置)和System Configuration(系統(tǒng)配置:VDD值、滴答定時器初始優(yōu)先級、選擇是否使用操作系統(tǒng))代碼,如代碼2
代碼2/* ########################## Oscillator Values adaptation ####################*/
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal oscillator (CSI) default value.
* This value is the default CSI value after Reset.
*/
#if !defined (CSI_VALUE)
#define CSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* CSI_VALUE */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @brief External Low Speed oscillator (LSE) value.
* This value is used by the UART, RTC HAL module to compute the system frequency
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE ((uint32_t)32768) /*!< Value of the External oscillator in Hz*/
#endif /* LSE_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */
#endif /* LSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for I2S peripheral
* This value is used by the I2S HAL module to compute the I2S clock source
* frequency, this source is inserted directly through I2S_CKIN pad.
*/
#if !defined (EXTERNAL_CLOCK_VALUE)
#define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the External clock in Hz*/
#endif /* EXTERNAL_CLOCK_VALUE */
/* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY ((uint32_t)0x0F) /*!< tick interrupt priority */
#define USE_RTOS 0
/* #define USE_SD_TRANSCEIVER 1U */ /*!< use uSD Transceiver */
所設計板子使用的實際晶振大小一定要與這里數(shù)值一致。比如,設計的外置晶振是 25MHz,那么代碼2的第8行代碼就務必配置宏定義為:define HSE_VALUE ((uint32_t)25000000)。
代碼2第62行:滴答定時器的優(yōu)先級設置。這個優(yōu)先級的設置至關重要。 因為 HAL 庫中各個外設驅(qū)動里面的延遲實現(xiàn)是基于此文件提供的時間基準。如果在中斷服務程序里面調(diào)用基于此時間基準的延遲函數(shù) HAL_Delay 要特別注意,因為這個函數(shù)的時間基準是基于滴答定時器或者其他通用定時器實現(xiàn),實現(xiàn)方式是滴答定時器或者其他通用定時器里面對變量計數(shù)。如此以來,結果是顯而易見的,如果其他中斷服務程序調(diào)用了此函數(shù),且中斷優(yōu)先級高于滴答定時器,會導致滴答定時器中斷服務程序一直得不到執(zhí)行,從而卡死在里面。所以滴答定時器的中斷優(yōu)先級一定要比他們高。另外這個時間基準既可以使用滴答定時器實現(xiàn)也可以使用通用的定時器實現(xiàn),默認情況下是用的滴答定時器。
注:為了方便各種外設延遲的實現(xiàn),HAL 庫專門搞了一個時間基準,默認來源是滴答定時器,也可以通過重定向使用其他定時器實現(xiàn)。 相關函數(shù)全部集中在 stm32h7xx_hal.c 文件里面實現(xiàn)。
2-2、startup_stm32h743xx.s
關于此函數(shù)詳細分析,見另外一篇博客《stm32h7“啟動文件分析”》http://www.mazirong.com/?p=358
2-3、system_stm32h7xx.c
void SystemInit (void)函數(shù)功能:Setup the microcontroller system,Initialize the FPU setting, vector table location and External memory configuration.(主要用于復位 RCC 相關寄存器和中斷向量表位置設置)
2-4、stm32h7xx_hal_cortex.h
主要提供中斷分組參數(shù)、時鐘分頻參數(shù)、MPU配置參數(shù)。
2-5、stm32h7xx_hal_cortex.c
這個庫文件主要功能是NVIC相關函數(shù),MPU相關函數(shù)和Systick相關函數(shù)。 此文件有個臃腫的地方,里面的 API 其實就是將 ARM 的 CMSIS 庫各種 API 重新封裝了一遍。這么做的好處是保證了HAL的API都是以字母HAL開頭。
2-6、core_cm7.h
主要為Cache的配置提供了11個相關函數(shù)。
2-7、stm32h7xx_hal.c
重要的函數(shù)有
HAL_Init函數(shù)
HAL_DeInit
HAL_InitTick及其他Systick相關函數(shù)
HAL_SYSCFG_VREFBUF_VoltageScalingConfig(配置內(nèi)部基準電壓大小函數(shù))及內(nèi)部基準電壓相關函數(shù)
HAL_SYSCFG_EnableBOOST(BOOST的使能/禁止函數(shù)),主要用于ADC
HAL_SYSCFG_CM7BootAddConfig(用于配置BOOT = 0或者BOOT = 1時的啟動地址)
IO補償相關函數(shù)
低功耗相關函數(shù)
EXTI相關函數(shù)
2-8、stm32h7xx_hal_rcc.c
這個文件主要是實現(xiàn)內(nèi)部和外部時鐘(HSE、 HSI、 LSE、 CSI、 LSI、 HSI48、 PLL、 CSS、 MCO)以及總線時鐘(SYSCLK、 AHB3、 AHB1、 AHB2、 AHB4、 APB3、 APB1L、 APB1H、 APB2、 APB4)的配置。
系統(tǒng)上電復位后,通過內(nèi)部高速時鐘 HSI 運行(主頻 64MHz),Flash 工作在 0 等待周期,所有外設除了 SRAM、 Flash、 JTAG 和 PWR,時鐘都是關閉的。AHB 和 APB 總線無分頻,所有掛載這兩類總線上的外設都是以 HSI 頻率運行。所有的 GPIO 都是模擬模式,除了 JTAG 相關的幾個引腳。
用戶需要完成以下工作:
選擇用于驅(qū)動系統(tǒng)時鐘的時鐘源。
配置系統(tǒng)時鐘頻率和 Flash 設置。
配置分頻器。
使能外設時鐘。
配置外設時鐘源,部分外設的時鐘可以不來自系統(tǒng)時鐘,此時通過配置寄存器 RCC_D1CCIPR、RCC_D2CCIP1R、 RCC_D2CCIP2R 和 RCC_D3CCIPR 實現(xiàn)。
RCC 局限性:使能了外設時鐘后,不能立即操作對應的寄存器,要加延遲。 不同外設延遲不同:
如果是 AHB 的外設,使能了時鐘后,需要等待 2 個 AHB 時鐘周期才可以操作這個外設的寄存器。
如果是 APB 的外設,使能了時鐘后,需要等待 2 個 APB 時鐘周期才可以操作這個外設的寄存器。
當前 HAL 庫的解決方案是在使能了外設時鐘后,再搞一個讀操作,算是當做延遲用,如代碼3(位于stm32h7xx_hal_rcc.h文件)
代碼3#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \
__IO uint32_t tmpreg; \
SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOAEN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOAEN);\
UNUSED(tmpreg); \
} while(0)
注:HAL_RCC_ClockConfig函數(shù)會更新全局變量 SystemCoreClock 的主頻值,并且會再次調(diào)用函數(shù) HAL_InitTick 更新系統(tǒng)滴答時鐘,這點要特別注意。
2-9、hal庫外設文件
為了方便調(diào)用,HAL 庫為各種外設基本都配了三套 API,查詢方式,中斷方式和DMA方式。
總結
以上是生活随笔為你收集整理的hal库选择滴答时钟函数_stm32h7“理解hal库框架”的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows主板怎么恢复出厂设置
- 下一篇: SUBMAIL API如何帮助您构建企业