06. 系统滴答定时器

news/发布时间2024/8/25 6:50:34

一、SysTick定时器简介

  SysTick,即系统滴答定时器,是属于 CM3 内核中的一个外设,内嵌在 NVIC 中。系统定时器是一个 24bit 的向下递减的计数器,SysTick 的时钟源自 HCLK。当计数值减到 0 时,将从 RELOAD 寄存器中自动重装载定时初值,开始新一轮计数。只要不把它在 SysTick 控制及状态寄存器中的使能位清除,就永不停息。

  因为 SysTick 是属于 CM3 内核的外设,所以所有基于 CM3 内核的单片机都具有这个系统定时器,使得软件在 CM3 单片机中可以很容易的移植。系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。

二、SysTick工作原理

Systick工作原理

每次 VAL 减到 0 时,VAL 自动从 LOAD 重载,开始新的一轮递减计数;

三、SysTick寄存器介绍

  SysTick 有4个寄存器。在使用 SysTick 产生定时的时候,只需要配置前三个寄存器,最后一个校准寄存器不需要使用。

3.1、SysTick控制及状态寄存器(CTRL)

SysTick控制及状态寄存器

3.2、SysTick重装载数值寄存器(LOAD)

SysTick重装载数值寄存器

3.3、SysTick当前数值寄存器(VAL)

SysTick当前数值寄存器

3.4、SysTick校准数值寄存器(CALIB)

SysTick校准数值寄存器

四、SysTick定时时间的计算

  SysTick 的时钟源自 HCLK ,它的计数器是向下递减计数的,计数一次的时间 \(T_{DEC}\)=1/HCLK,,假设配置系统时钟为 72MHZ,经过分频器 8 分频后,那么 SysTick 的时钟即为 9Mhz,也就是 SysTick 的计数器 VAL 每减 1,就代表时间过了 1/9us。

  SysTick 延迟初始化函数

uint16_t g_frequency_us = 0;                                    // us延时倍乘数void Delay_Init(uint8_t clock)
{SysTick->CTRL = 0;                                            // 清Systick状态HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);     // Systick使用内核时钟源8分频,因Systick的计数器最大值只有2^24g_frequency_us = clock / 8;                                   // 1us作为基础时基
}

  微秒级延迟函数

void Delay_us(uint32_t us)
{uint32_t temp;SysTick->LOAD = us * g_frequency_us;                          // 延迟时间加载SysTick->VAL = 0x00;                                          // 清空计数器SysTick->CTRL |= 1<<0;                                        // 开始倒数do {temp = SysTick->CTRL;}while ((temp & 0x01) && !(temp & (1<<16)));                  // CTRL.ENABLE位必须为1,并等待时间到达SysTick->CTRL &= ~(1<<0);                                     // 关闭SystickSysTick->VAL = 0x00;                                          // 清空计数器
}

  毫秒级延迟函数

void Delay_ms(uint32_t ms)
{uint32_t repeat = ms / 1000;uint32_t remain = ms % 1000;while (repeat){Delay_us(1000 * 1000);                                      // 利用Delay_us()实现1000ms延时repeat--;}if (remain){Delay_us(remain * 1000);                                    // 利用Delay_us(),实现尾数延迟(remain ms)}
}

不考虑超频的情况下,延迟的最大微秒数为 1.86s 左右,超频的情况下,延迟的最大微秒数为 1.04s 左右;

五、HAL库延时函数HAL_Delay

  HAL 库实现延时功能非常简单,首先定义了一个 32 位全局变量 uwTick,在 Systick 中断服务函数 SysTick_Handler 中通过调用 HAL_IncTick 实现 uwTick 值不断增加,也就是每隔 1ms 增加 uwTickFreq,而 uwTickFreq 默认是 1。而 HAL_Delay 函数在进入函数之后先记录当前 uwTick 的值,然后不断在循环中读取 uwTick 当前值,进行减运算,得出的就是延时的毫秒数。

/*** @brief This function provides minimum delay (in milliseconds) based*        on variable incremented.* @note In the default implementation , SysTick timer is the source of time base.*       It is used to generate interrupts at regular time intervals where uwTick*       is incremented.* @note This function is declared as __weak to be overwritten in case of other*       implementations in user file.* @param Delay specifies the delay time length, in milliseconds.* @retval None*/
__weak void HAL_Delay(uint32_t Delay)
{uint32_t tickstart = HAL_GetTick();uint32_t wait = Delay;/* Add a freq to guarantee minimum wait */if (wait < HAL_MAX_DELAY){wait += (uint32_t)(uwTickFreq);}while ((HAL_GetTick() - tickstart) < wait){}
}
/*** @brief Provides a tick value in millisecond.* @note  This function is declared as __weak to be overwritten in case of other*       implementations in user file.* @retval tick value*/
__weak uint32_t HAL_GetTick(void)
{return uwTick;
}
/*** @brief This function handles System tick timer.*/
void SysTick_Handler(void)
{HAL_IncTick();
}
/*** @brief This function is called to increment  a global variable "uwTick"*        used as application time base.* @note In the default implementation, this variable is incremented each 1ms*       in SysTick ISR.* @note This function is declared as __weak to be overwritten in case of other*      implementations in user file.* @retval None*/
__weak void HAL_IncTick(void)
{uwTick += uwTickFreq;
}

  但是,HAL 库的延时函数在中断服务函数中使用 HAL_Delay 会引起混乱(虽然一般禁止在中断中使用延时函数),因为它是通过中断方式实现,而 Systick 的中断优先级是最低的,所以在中断中运行 HAL_Delay 会导致延时出现严重误差。

  HAL 库的 ms 级别的延时函数 __weak void HAL_Delay(uint32_t Delay);它是弱定义函数,所以用户可以自己重新定义该函数。

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

如若内容造成侵权/违法违规/事实不符,请联系连锁易网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

【Qt6】列表模型——树形列表

QStandardItemModel 类作为标准模型,主打“类型通用”,前一篇水文中,老周还没提到树形结构的列表,本篇咱们就好好探讨一下这货。 还是老办法,咱们先做示例,然后再聊知识点。下面这个例子,使用 QTreeView 组件来显示数据,使用的列表模型比较简单,只有一列。#include &l…

QT QPixmap QImage内存泄漏

无论是在代码中还是在UI中设置icon都会产生内存泄漏 大概看了下,好像是QPixmap的data_ptr的引用计数,到不了1/0(查看引用计数,释放后,理论上应回到1) 试了下,仅以下两种方式不会产生内存泄漏: 1、从 XPM加载: img = QPixmap(result); //result为 static const cha…

抽象CurrentUser适配Http和Job场景

前言 获取当前请求用户的基础信息是很常见的,诸如当前用户Id,角色,有无访问权限等。通常我们可以直接使用HttpContext.User来拿到当前经过认证后的请求人信息。但是这样对于分层应用不太友好,需要安装AspNetCore.Http.Abstractions的包,这样对于这层(非Web层)来讲也有所侵…

使用 AI 编程助手 CodeWhisperer,开发如有神助

前段时间体验了chatGPT,听说它可以写代码,结果发现更多的只是一个对答写小作文的百度助手,虽然也能写代码,但不是我想要的,可以在 idea 中可以快速生成代码块的。一个偶然的机会,从微信群里了解到,由亚马逊云科技推出的 CodeWishPerer 开发插件,可以在多个开发环境中使…

向日葵安装教程

1、官网下载 2、执行安装1、官网下载 向日葵远程桌面连接,监控,维护,管理,客服支持解决方案-贝锐向日葵远程控制管理软件 (oray.com) 2、执行安装 安装后界面 完美。

读高性能MySQL(第4版)笔记17_复制(下)

复制1. 复制切换 1.1. 复制是高可用性的基础 1.1.1. 总是保留一份持续更新的副本数据,会让灾难恢复更简单 1.2. “切换副本”(promoting a replica)和“故障切换”(failing over)是同义词 1.2.1. 意味着源服务器不再接收写入,并将副本提升为新的源服务器 1.3. 计划内切换…

SOC芯片架构技术分析(二)

SOC芯片架构技术分析(二) 2.1 SoC产业链概况2.2 产业链上游概况:设计工具寡头竞争2.2 产业链上游概况:IP核行业行业集中度高1)行业集中度高,国内厂商市占率较低。 2)全球IP核供应商以国外厂商为主,行业集中度相对 较高:国内集成电路设计企业所需的IP核大多来自 境外供…

npm install 报-4048错误

报错原因:有缓存 权限不够 有三种解决方法: 第一种:找到.npmrc文件并删除 在 C:\Users\自己用户的文件夹\ 下找到 .npmrc 文件并删除 注意:这个文件是隐藏的,需要显示隐藏才能看见 第二种方法:直接用命令清理 在控制台上输出 npm cache clean --force 一样可以删除 第三…

Applescript实现无痕检测手机号或邮箱号是否注册iMessage服务,iMessage蓝号检测实现

一、检测数据的两种方式:1.人工筛选,将要验证的号码输出到文件中,以逗号分隔。再将文件中的号码粘贴到iMessage客户端的地址栏,iMessage客户端会自动逐个检验该号码是否为iMessage账号,检验速度视网速而定。红色表示不是iMessage账号,蓝色表示iMessage账号。2.编写脚本控制…

软件工程第三次作业——结对编程

21计科3班 3121005231 王嘉宸 21计科4班 3121005140 邱彦翔前期准备 需求分析 使用 MoSCoW 方法进行需求分析。 Must Have算术题生成器:设:自然数或真分数 $n$ : $0, 1, 2, \cdots$ , $1/2, 1/3, 2/3, \cdots$;运算符 $op$ : $+, -, \times, \div$ ;括号 : $(, )$ ;等号 …

清缓存命令

查看缓存free -m清缓存echo 3 > /proc/sys/vm/drop_caches 清缓存后 #释放物理页缓存 echo 1 > /proc/sys/vm/drop_caches #释放可回收的slab对象,包含inode and dentry echo 2 > /proc/sys/vm/drop_caches #同时释放 页、目录、索引节点缓存: echo 3 > /proc/s…

R语言广义相加(加性)模型(GAMs)与光滑函数可视化|附代码数据

原文链接:http://tecdat.cn/?p=23509 原文出处:拓端数据部落公众号 最近我们被客户要求撰写关于GAMs的研究报告,包括一些图形和统计输出。 我们在研究工作中使用广义加性模型(GAMs)。mgcv软件包是一套优秀的软件,可以为非常大的数据集指定、拟合和可视化GAMs。 这篇文章…

实验1

1. 实验1 实验1_1源代码1 // 打印一个字符小人2 3 #include <stdio.h>4 int main() 5 {6 printf(" O \n");7 printf("<H>\n");8 printf("I I\n");9 10 return 0; 11 } 实验1_1运行结果截图 2. 实验23. 实验3

chapter 7 文件操作chapter 8 使用系统调研进行文件操作

chapter 7 文件操作&chapter 8 使用系统调研进行文件操作 7.1 文件操作 文件操作由五个层次构成,从低到高,如下图所示。 7.1.1 硬件级别 硬件级别的文件操作包括以下程序:fdisk:将硬盘、USB 或 SDC 驱动器分成分区。 mkfs:格式化磁盘分区以准备它们用于文件系统。 fsc…

.NET周刊【9月第3期 2023-09-17】

国内文章 在.NET 8 RC1 版本中 MAUI、ASP.NET Core 和 EF8 的新特性 https://www.cnblogs.com/shanyou/p/17698428.html 从年初2 月份发布第一个预览版,经历7个预览版后,Microsoft 西雅图时间9月13日发布了 .NET 8 RC 1: https://devblogs.microsoft.com/dotnet/announcing-…

手把手教你实现跳表!

一个适用于算法竞赛的跳表实现,附有详细解释发布于我的博客,也许同步更新于博客园 引入 跳表(跳跃表)能够维护一个数的集合(作用类似普通平衡树),查找时间复杂度为 \(\log n\),与平衡树一样基于链表结构。由于不需要平衡树那么多旋转什么的,所以效率比较高,一般认为性…

Strimzi Kafka Bridge(桥接)实战之二:生产和发送消息

最常用最实用的接口,尽在本篇一网打尽,轻松通过http收发kafka消息欢迎访问我的GitHub这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos本篇概览本文是《Strimzi Kafka Bridge(桥接)实战之》系列的第二篇,咱们直奔bridge的重点:常用接口,…

内核模块详细加载/卸载过程

ko文件在数据组织形式上是ELF(Excutable And Linking Format)格式,是一种普通的可重定位目标文件。 这类文件包含了代码和数据,可以被用来链接成可执行文件或共享目标文件,静态链接库也可以归为这一类。 文件开始处是一个ELF头部(ELF Header),用来描述整个文件的组织,这些…
推荐文章