1、按照初始化流程调用的hal库文件

完成初始化工作需要调用到的hal库文件,如下表

序号功能调用hal库文件

1Module Selection(模块选择)

Oscillator Values adaptation(晶振值配置)

System Configuration(系统配置:VDD值、滴答定时器初始优先级、选择是否使用操作系统)

Ethernet Configuration(以太网配置)

Assert Selection(选择是否使用断言)

SPI peripheral configuration(SPI外设配置)stm32h7xx_hal_conf.h

2系统上电复位

复位中断调用函数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配置系统时钟stm32h7xx_hal_rcc.c

7初始化各种外设hal库外设文件

上表中序号3至7用程序表示是初始化所有设备,如代码1

代码1/*

*********************************************************************************************************

* 函 数 名: bsp_Init

* 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次

* 形 参:无

* 返 回 值: 无

*********************************************************************************************************

*/

void bsp_Init(void)

{

/* 配置MPU */

MPU_Config();

/* 使能L1 Cache */

CPU_CACHE_Enable();

/*

STM32H7xx HAL 库初始化,此时系统用的还是H7自带的64MHz,HSI时钟:

- 调用函数HAL_InitTick,初始化滴答时钟中断1ms。

- 设置NVIV优先级分组为4。

*/

HAL_Init();

/*

配置系统时钟到400MHz

- 切换使用HSE。

- 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。

*/

SystemClock_Config();

/*

Event Recorder:

- 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。

- 默认不开启,如果要使能此选项,务必看V7开发板用户手册第8章

*/

#if Enable_EventRecorder == 1

/* 初始化EventRecorder并开启 */

EventRecorderInitialize(EventRecordAll, 1U);

EventRecorderStart();

#endif

bsp_InitUart(); /* 初始化串口 */

bsp_InitKey(); /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */

bsp_InitTimer(); /* 初始化滴答定时器 */

bsp_InitExtIO(); /* 初始化FMC总线74HC574扩展IO. 必须在 bsp_InitLed()前执行 */

bsp_InitLed(); /* 初始化LED */

}

第12–15行,配置 MPU 和使能 Cache。

对于H7,这两个函数要优先执行,因为 Flash 速度,SRAM 速度跟 CPU 和 TCM 有些差距的,所以要使能 Cache。而不同存储区的 Cache 策略要通过MPU 分别进行配置。

第22行,调用HAL_Init函数。

调用HAL_Init函数时,系统依然使用的 64MHz HSI 时钟,这点要特别注意。 此函数会调用函数HAL_InitTick(stm32h7xx_hal.c文件中),初始化滴答时钟中断 1ms,并设置 NVIV 优先级分组为 4。这里就隐含了一个知识点,就是它会开启滴答定时器中断,如果用户也要使用滴答定时器中断,此问题就要引起注意,bsp_timer.c文件中void SysTick_Handler(void) 函数加了一个状态标志判断,只有当使用了定时器初始化函数才能进入用户滴答定时器中断,否则只能执行到系统滴答定时器中断。

第29行,通过此函数切换 HSI 到外部高速时钟 HSE,并配置系统时钟到400MHz。调用这个函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。

2、hal文件分别学习

2-1、stm32h7xx_hal_conf.h

该文件主要实现功能如下

Module Selection(模块选择)

Oscillator Values adaptation(晶振值配置)

System Configuration(系统配置:VDD值、滴答定时器初始优先级、选择是否使用操作系统)

Ethernet Configuration(以太网配置)

Assert Selection(选择是否使用断言)

SPI peripheral configuration(SPI外设配置)

其中截取Oscillator Values adaptation(晶振值配置)和System Configuration(系统配置:VDD值、滴答定时器初始优先级、选择是否使用操作系统)代码,如代码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 */

所设计板子使用的实际晶振大小一定要与这里数值一致。比如,设计的外置晶振是 25MHz,那么代码2的第8行代码就务必配置宏定义为:define HSE_VALUE ((uint32_t)25000000)。

代码2第62行:滴答定时器的优先级设置。这个优先级的设置至关重要。 因为 HAL 库中各个外设驱动里面的延迟实现是基于此文件提供的时间基准。如果在中断服务程序里面调用基于此时间基准的延迟函数 HAL_Delay 要特别注意,因为这个函数的时间基准是基于滴答定时器或者其他通用定时器实现,实现方式是滴答定时器或者其他通用定时器里面对变量计数。如此以来,结果是显而易见的,如果其他中断服务程序调用了此函数,且中断优先级高于滴答定时器,会导致滴答定时器中断服务程序一直得不到执行,从而卡死在里面。所以滴答定时器的中断优先级一定要比他们高。另外这个时间基准既可以使用滴答定时器实现也可以使用通用的定时器实现,默认情况下是用的滴答定时器。

注:为了方便各种外设延迟的实现,HAL 库专门搞了一个时间基准,默认来源是滴答定时器,也可以通过重定向使用其他定时器实现。 相关函数全部集中在 stm32h7xx_hal.c 文件里面实现。

2-2、startup_stm32h743xx.s

关于此函数详细分析,见另外一篇博客《stm32h7“启动文件分析”》http://www.mazirong.com/?p=358

2-3、system_stm32h7xx.c

void SystemInit (void)函数功能:Setup the microcontroller system,Initialize the FPU setting, vector table location and External memory configuration.(主要用于复位 RCC 相关寄存器和中断向量表位置设置)

2-4、stm32h7xx_hal_cortex.h

主要提供中断分组参数、时钟分频参数、MPU配置参数。

2-5、stm32h7xx_hal_cortex.c

这个库文件主要功能是NVIC相关函数,MPU相关函数和Systick相关函数。 此文件有个臃肿的地方,里面的 API 其实就是将 ARM 的 CMSIS 库各种 API 重新封装了一遍。这么做的好处是保证了HAL的API都是以字母HAL开头。

2-6、core_cm7.h

主要为Cache的配置提供了11个相关函数。

2-7、stm32h7xx_hal.c

重要的函数有

HAL_Init函数

HAL_DeInit

HAL_InitTick及其他Systick相关函数

HAL_SYSCFG_VREFBUF_VoltageScalingConfig(配置内部基准电压大小函数)及内部基准电压相关函数

HAL_SYSCFG_EnableBOOST(BOOST的使能/禁止函数),主要用于ADC

HAL_SYSCFG_CM7BootAddConfig(用于配置BOOT = 0或者BOOT = 1时的启动地址)

IO补偿相关函数

低功耗相关函数

EXTI相关函数

2-8、stm32h7xx_hal_rcc.c

这个文件主要是实现内部和外部时钟(HSE、 HSI、 LSE、 CSI、 LSI、 HSI48、 PLL、 CSS、 MCO)以及总线时钟(SYSCLK、 AHB3、 AHB1、 AHB2、 AHB4、 APB3、 APB1L、 APB1H、 APB2、 APB4)的配置。

系统上电复位后,通过内部高速时钟 HSI 运行(主频 64MHz),Flash 工作在 0 等待周期,所有外设除了 SRAM、 Flash、 JTAG 和 PWR,时钟都是关闭的。AHB 和 APB 总线无分频,所有挂载这两类总线上的外设都是以 HSI 频率运行。所有的 GPIO 都是模拟模式,除了 JTAG 相关的几个引脚。

用户需要完成以下工作:

选择用于驱动系统时钟的时钟源。

配置系统时钟频率和 Flash 设置。

配置分频器。

使能外设时钟。

配置外设时钟源,部分外设的时钟可以不来自系统时钟,此时通过配置寄存器 RCC_D1CCIPR、RCC_D2CCIP1R、 RCC_D2CCIP2R 和 RCC_D3CCIPR 实现。

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函数会更新全局变量 SystemCoreClock 的主频值,并且会再次调用函数 HAL_InitTick 更新系统滴答时钟,这点要特别注意。

2-9、hal库外设文件

为了方便调用,HAL 库为各种外设基本都配了三套 API,查询方式,中断方式和DMA方式。

hal库选择滴答时钟函数_stm32h7“理解hal库框架”相关推荐

  1. hal库选择滴答时钟函数_STM32入门 : HAL库、标准外设库、LL库

      国内使用STM32 单片机的人很多,ST 为开发者提供了非常方便的开发库:有标准外设库(SPL 库).HAL 库.LL 库 三种.前者是ST的老库,后两者是ST现在主推的开发库,其中 LL 库是 ...

  2. 4、系统滴答时钟SysTick

    写在开篇前: 首先要明确的第一点:学习知识我们都会到网上查询各种资料,但是由于网上资料大多不全 面,我们对于这些资料需要加以自身的理解并对其有所取舍,所以建议网上查来的资料只做引导. 参考作用,最终确 ...

  3. stm32f4xx-systick系统滴答时钟

    文章目录 一.系统滴答时钟 1.简介 注意: 2.工作原理(向下计数,向上计数) 3.频率的概念 二.库函数 四.延时函数 1.系统定时器的用途 2.官方示例 3.寄存器 4.毫秒级延时函数 5.微秒 ...

  4. STM32滴答时钟[直接用寄存器]

    生活中,我们通过看表来知道当前时间,知道我们在这个点应该做什么事情,那么芯片呢,就通过各种定时器来记录时间,滴答时钟就是定时器的一种,它可以用来做操作系统的节拍(心跳),可以用来计时,可以用来做闹钟, ...

  5. 基于STM32滴答时钟的多任务定时器

    基于STM32滴答时钟的多任务定时器 基于STM32滴答时钟的多任务定时器 概述 声明:此定时器仅提升个人编程能力和学习使用,不得用于商用,用于商用一切后果自行负责. API说明 滴答时钟初始化并创建 ...

  6. STM32CbueMX之利用滴答时钟delay us

    参考<PM0214: STM32 Cortex®-M4 MCUs and MPUs programming manual.pdf>(STM32 Cortex_-M4内核参考手册.pdf)的 ...

  7. stm32成长记之滴答时钟

    SysTick具体操作可参照: http://www.st.com/content/ccc/resource/technical/document/programming_manual/5b/ca/8 ...

  8. freeRTOS滴答时钟相关源码分析

    最近学习白问网韦东山老师在B站开源的freeRTOS课程,网址:韦东山直播公开课:RTOS实战项目之实现多任务系统 第1节:裸机程序框架和缺陷_哔哩哔哩_bilibili和7天物联网训练营[第2期]7 ...

  9. 【STM32】HAL库-系统滴答定时器SysTick

    SysTick定时器被捆绑在NVIC中,是一个简单的定时器,对于CM3.CM4内核芯片,都有Systick定时器.Systick定时器常用来做延时,或者实时系统的心跳时钟.这样可以节省MCU资源,不用 ...

最新文章

  1. vc 添加打开文件对话框并读取文件
  2. JSONP跨域的原理解析
  3. 信息系统项目管理师-项目范围管理考点笔记
  4. android php mysql json 查询_android php mysql json
  5. import win32com.client在python中报错及其解决办法
  6. B端产品如何寻找竞品?
  7. select、poll和epoll
  8. QJson数据用法实例
  9. (可行方案)mysql5.7.9安装教程
  10. MYSQL添加新用户 MYSQL为用户创建数据库 MYSQL为新用户分配权限(转)
  11. Nexon由Xsolla全球支付服务
  12. java仿百度分页_java仿百度假分页代码实现
  13. java七武器系列_Java七武器系列多情环 --多功能Profiling工具 JVisual VM
  14. GDI+学习及代码总结之------画刷Brush .
  15. python中eval和ast.literal_eval的区别
  16. 计算机权限全部用户,允许所有人权限应用于匿名用户 (Windows 10) - Windows security | Microsoft Docs...
  17. Java游戏开发——flappy bird
  18. Leetcode刷题笔记 35.搜索插入位置(详细说明二分查找)
  19. C# 强化系列文章四:匿名方法的使用
  20. 基于Java+Springmvc+vue+element员工信息管理系统详细设计

热门文章

  1. 使用JavaScript遍历本地文件夹的文件
  2. Azure上用API成功创建Lambda Function的截图
  3. 仅仅有单日的确诊总人数,无法触发SAP Analytics Cloud的Smart Discovery功能
  4. ABAP Netweaver里的那些月亮
  5. 使用abapGit在ABAP On-Premises系统和SAP云平台ABAP环境之间进行代码传输
  6. How to find documentation of given API
  7. SAP Marketing Cloud的profile dashboard
  8. S4HANA里至关重要的建模方式CDS view架构介绍
  9. when is valid from and valid to filled in SAP IBASE buffer table
  10. ubuntu上的wordpress安装