STM32源码阅读记录之HAL库(SystemTick)

news2024/10/7 11:27:13

问题

  1. HAL_Delay是怎么做到可以延迟控制的?

分析记录

步骤01:看函数本身

void HAL_Delay(uint32_t Delay);

/**
  * @brief 此函数根据变量递增提供最小延迟(以毫秒为单位)。
  * @note 在默认的实现中,SysTick计时器是时基的来源。它用于以固定的时间间隔生成中断,其中 uwTick 递增
  * @note 此函数声明为__weak在用户文件中出现其他实现时要覆盖。
  * @param Delay 指定延迟时间长度(以毫秒为单位)。
  * @retval None
  */
__weak void HAL_Delay(uint32_t Delay)
{
  // 获取一个计数值,简单来说就是一个记录当前时刻的记录值
  uint32_t tickstart = HAL_GetTick();
 
  uint32_t wait = Delay;

  /* 添加频率以保证最短的等待时间 */
  if (wait < HAL_MAX_DELAY)
  {
    wait += (uint32_t)(uwTickFreq);
  }
  //  死循环,直到不满足要求时结束
  while ((HAL_GetTick() - tickstart) < wait)
  {
  }
}

uint32_t HAL_GetTick(void)

/**
  * @brief 提供以毫秒为单位的刻度值。
  * @note  此函数声明为__weak在用户文件中出现其他实现时要覆盖。
  * @retval tick value
  */
__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
}

void HAL_IncTick(void)

/**
  * @brief 调用此函数以递增用作应用程序时基的全局变量“uwTick”。
  * @note 在默认实现中,此变量在 SysTick ISR 中每 1 毫秒递增一次。
  * @note 此函数声明为__weak在用户文件中出现其他实现时要覆盖。
  * @retval None
  */
__weak void HAL_IncTick(void)
{
  uwTick += uwTickFreq;
}

步骤02:观察相关联的变量

在这里插入图片描述

步骤03:观察变化的地方

在这里插入图片描述1. 在SysTick_Handler中被调用
在这里插入图片描述

步骤04:中断要执行是需要开启的

  1. 在程序的开头HAL_Init();
    在这里插入图片描述在这里插入图片描述
/**
  * @brief  此函数用于初始化 HAL 库;它必须是在主程序中执行的第一个指令(在调用任何其他 HAL 函数之前), 它执行以下操作:
  *           1. 配置闪存预取。
  *           2. 将 SysTick 配置为每 1 毫秒生成一次中断,
  *           3. 由 HSI 计时(在此阶段,时钟尚未配置,因此系统从内部 HSI 以 16 MHz 运行).
  *           4. 将 NVIC 组优先级设置为 4
  *           5. 调用用户文件 “stm32f1xx_hal_msp.c” 中定义的 HAL_MspInit() 回调函数来执行全局低级硬件初始化
  *
  * @note   SysTick 用作 HAL_Delay() 函数的时基,应用程序需要确保 SysTick 时基始终设置为 1 毫秒,以便具有正确的 HAL 操作
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_Init(void) {
    /* 配置闪存预取 */
#if (PREFETCH_ENABLE != 0)
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || \
    defined(STM32F102x6) || defined(STM32F102xB) || \
    defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || \
    defined(STM32F105xC) || defined(STM32F107xC)

    /* 预取缓冲区在超值行设备上不可用 */
    __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
#endif
#endif /* PREFETCH_ENABLE */

    /* NVIC 组优先级设置 */
    HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

    /*将 SysTick 配置为每 1 毫秒生成一次中断(重置后的默认时钟为 HSI) */
    HAL_InitTick(TICK_INT_PRIORITY);

    /* 初始化低级硬件 */
    HAL_MspInit();

    /* 返回函数状态 */
    return HAL_OK;
}

步骤04:查看HAL_InitTick执行函数

在这里插入图片描述

/**
  * @brief 此函数配置时基源。时间源配置为具有 1ms 时基,具有专用的 Tick 中断优先级
  * @note 此函数在程序开始时由 HAL_Init() 重置后或在时钟由 HAL_RCC_ClockConfig() 重新配置时自动调用。
  * @note 在默认实现中,SysTick 计时器是时基的来源。它用于以固定的时间间隔生成中断。
  *       如果从外设 ISR 进程调用 HAL_Delay(),则必须小心,SysTick 中断的优先级必须高于外设中断(数值较低)。否则,调用方 ISR 进程将被阻止。
  * @param TickPriority Tick interrupt priority.
  * @retval HAL status
  */
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {
    /* 将系统滴答配置为在 1ms 时间内中断*/
    if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U) {
        return HAL_ERROR;
    }

    /* 配置系统滴答 IRQ 优先级 */
    if (TickPriority < (1UL << __NVIC_PRIO_BITS)) {
        HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
        uwTickPrio = TickPriority;
    } else {
        return HAL_ERROR;
    }

    /* Return function status */
    return HAL_OK;
}

步骤05: 查看HAL_SYSTICK_Config函数

  1. 这一步就是对外再包装了一层
    在这里插入图片描述

步骤06: 查看SysTick_Config函数(实际执行的)

在这里插入图片描述

步骤07: 重点记录SystemCoreClock的变化:

在这里插入图片描述在这里插入图片描述

第一次使用的地方

在这里插入图片描述

第一次变化的地方

在这里插入图片描述

查看HAL_RCC_ClockConfig执行函数

在这里插入图片描述在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/632703.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Leetcode -225.用队列实现栈 -232.用栈实现队列】

Leetcode Leetcode -225.用队列实现栈Leetcode -232.用栈实现队列 Leetcode -225.用队列实现栈 题目&#xff1a;仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 …

chatgpt赋能python:Python实践:如何升级pip

Python实践&#xff1a;如何升级pip Python作为一门高效的脚本语言&#xff0c;被广泛应用于数据分析、人工智能、Web开发等领域。而pip则是Python的包管理工具&#xff0c;是开发Python应用的必备工具。但是pip在使用过程中&#xff0c;有时候会出现版本不兼容或者出现漏洞等…

chatgpt赋能python:Python取两位小数的方法

Python取两位小数的方法 介绍 Python是一种高级编程语言&#xff0c;因其简洁易懂、跨平台等特点&#xff0c;被广泛应用于科学计算、数据分析、网站开发、人工智能等领域。在编写Python程序时&#xff0c;我们经常需要将浮点数精确到小数点后几位&#xff0c;比如精确到两位…

【0基础教程】Javascript 里的分组正则Capturing Groups使用方法及原理

一、从最简单开始 现有一个字符串&#xff1a; “1-apple” 需要提取出 1 和 apple 来&#xff0c;对应的正则表达式很简单&#xff1a; ^(\d)-(.)$ 对应的代码也比较简单&#xff1a; const str "1-apple"const regexp /^(\d)-(.)$/let match regexp.exec(str)c…

chatgpt赋能python:Python如何升序输出?从入门到实践!

Python如何升序输出&#xff1f;从入门到实践&#xff01; 作为一门高级编程语言&#xff0c;Python是目前应用广泛且最为流行的一门语言之一。它逐渐成为开发者的首选语言&#xff0c;因为它易学易用&#xff0c;可读性强&#xff0c;支持多种编程范式&#xff0c;提供了强大…

chatgpt赋能python:如何升级Python的pip版本

如何升级Python的pip版本 如果你使用Python来进行程序开发&#xff0c;那么你一定需要用到pip&#xff0c;它是Python的包管理器&#xff0c;用于安装和管理各种Python库。 不过&#xff0c;一旦你开始使用pip&#xff0c;你可能会遇到一个问题&#xff1a;你的pip版本可能会…

软考A计划-系统架构师-学习笔记-第二弹

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

前端vue基于原生check增强单选多选插件

前端vue基于原生check增强单选多选插件, 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id12979 效果图如下: #### 使用方法 使用方法 <!-- 多选组件 checkData&#xff1a;多选数据 change&#xff1a;多选事件 --> <ccCheckView…

FreeRTOS:软件定时器

目录 前言什么是硬件定时器什么是软件定时器 一、回调函数二、定时器的配置2.1软件定时器分类2.2定时器相关API函数2.2.1创建软件定时器2.2.2开启软件定时器2.2.3停止软件定时器2.2.4复位软件定时器 三、软件定时器实验3.1实验要求3.2实验代码 前言 什么是硬件定时器 CPU内部…

Limma | 三个组的差异分析怎么分析做呢!?~

1写在前面 高考结束了&#xff0c;不知道各位考生考的怎么样&#xff0c;这种时候总是几家欢喜几家忧&#xff0c;但这也是实现阶级流动的最佳机会。&#x1f914; 回想自己高考过去10几年了&#xff0c;不能说学了医后悔吧&#xff0c;只能说后悔至极&#xff0c;苦不堪言啊&a…

Linux -- 用户和组

目录 一、root用户&#xff08;超级管理员&#xff09; 1.1 切换用户命令&#xff1a;su 和 exit 命令 1.2 sudo命令 二、用户、用户组 2.1 用户组管理 2.1.1 创建用户组 2.1.2 删除用户组 2.2 用户管理 2.2.1 创建用户 2.2.2 删除用户 2.2.3 查看用户所属组 2.2.…

Linux系统防火墙iptables

目录 一、iptables防火墙概述 1.简介 2.netfilter/iptables关系 3.iptables的四表五链 &#xff08;1&#xff09;四表 &#xff08;2&#xff09;五链 4.数据包过滤的匹配流程 &#xff08;1&#xff09;入站 &#xff08;2&#xff09;转发 &#xff08;3&#xff…

前端vue简单好用的上拉加载下拉刷新组件,支持列表分页 本地分页

前端vue简单好用的上拉加载下拉刷新组件,支持列表分页 本地分页, 下载完整代码请访问uni-app插件市场地址: https://ext.dcloud.net.cn/plugin?id12942 效果图如下: #### 使用方法 使用方法 <!-- pullDown:下拉刷新 back-top: 回到顶部 --> <ccPullScroll class…

OMG--IDL(Interface Definition Language)

OMG--IDL&#xff08;Interface Definition Language&#xff09; 1 概述2 内容缩写IDL 语法和语义概述词法约定ISO Latin-1的字母字符如下表十进制数字字符图形字符格式化字符Tokens注释标识符冲突规则转义标识符关键字IDL识别的其他字符字面量 预处理IDL 语法构建块核心数据类…

dubbo流量录制异常(dubbo2.7.3)的问题解决排查

背景 我们自己基于jvm-sandbox-repeater做的流量录制出现了如下的问题, 从这个问题的堆栈信息来看&#xff0c;是在针对dubbo的调用的时候判断这个dubbo的返回是否有异常的时候&#xff0c;报了空指针异常了。 分析 我们看下具体出错的代码地方是怎么样的吧。 Overridepro…

chatgpt赋能python:Python怎么判断素数:一篇完整指南

Python怎么判断素数&#xff1a;一篇完整指南 Python是一种广泛应用于编程领域的语言&#xff0c;它非常适合初学者。在许多编程任务中&#xff0c;一个常见问题是需要判断一个数字是否是素数。本篇文章将介绍Python是如何判断素数的&#xff0c;并带领读者详细了解其中的细节…

Java入门之String 学习随记(一)

一. 前置知识 API-Application Programming Interface-应用程序编程接口,接口可以简单理解为别人写好的东西,我们拿过来直接使用即可.顾名思义,JavaAPI指的就是JDK提供的各种功能的Java类,它们将底层的实现封装了起来. 二. java.lang.String 该类为字符串,在Java中所有字符串…

chatgpt赋能python:如何正确删掉Python代码

如何正确删掉Python代码 介绍 在编写Python代码时&#xff0c;难免会出现一些多余或者错误的代码。为了保持代码的整洁和高效&#xff0c;我们需要学会如何正确地删掉Python代码。本文将介绍一些实用的方法和技巧&#xff0c;帮助您轻松删除不必要的代码。 方法 1. 手动删除…

前端基于radio增强单选框组件

前端基于radio增强单选框组件, 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id12977 效果图如下: # #### 使用方法 使用方法 <!-- radioData:单选数据 curIndex&#xff1a;当前选择序列 change&#xff1a;单选事件 --> <ccRadio…

软考A计划-系统架构师-学习笔记-第一弹

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…