STM32中的Systick的使用
SysTick,全称System Tick Timer,是Cortex-M microcontrollers内核中提供的一个简单而有效的系统定时器,设计用来给操作系统提供时间基准,或用于生成周期性的中断。STM32系列微控制器,作为基于ARM Cortex-M内核的设备,也内置了这一功能模块。
主要特点
24位递减计数器:SysTick是一个24位自动重载的递减计数器,达到0时,计数器会自动重新装载预设的值,并且可以产生一个可选的中断。
-
灵活的时钟源选择:SysTick定时器可以选择内核时钟(processor clock)或内核时钟的1/8作为其时钟源。这给了开发者根据实际需求选择时钟速度的灵活性。
-
简单易用:对于简单的延时生成、操作系统的节拍(timer tick) 或任何需要定时的任务,SysTick提供了一个简单而有效的解决方案,而不需要复杂的定时器配置。
-
固定的中断优先级:SysTick的中断优先级是在Cortex-M内核中固定的,这意味着开发者不能改变它。这为操作系统的设计提供了一定的便利,因为SysTick通常被用作系统的心跳或时间管理。
-
无需外部硬件:与其他外部或外围定时器不同,SysTick是内核内置功能,不需要其他外部硬件,可以保持系统的精简。
实现延时
开发者经常利用SysTick实现毫秒级的延时功能,这是通过配置SysTick的重载值(LOAD寄存器),并启用SysTick定时器和它的中断来实现的。每次SysTick定时器到达零,SysTick定时器会重新装载预设的值,并且可以触发中断(如果已经启用)。在中断服务程序(ISR)中可以执行相关的周期任务或标记一个周期的结束。
使用场景
- 操作系统节拍:实时操作系统(RTOS)常用SysTick定时器作为系统的基础节拍源,用于任务调度、时间管理等。
- 程序延时:在不需要精确时间管理的应用中,SysTick可以用来实现简易的延时功能,例如等待硬件准备好或实现非阻塞延迟。
- 时间测量:SysTick也可以用于程序执行时间的测量,从而帮助开发者优化代码。
总之,SysTick是Cortex-M系列微控制器中非常实用的功能,对于需要精确时间管理或操作系统支持的应用来说尤其重要。
如何初始化systick定时器
为了初始化SysTick定时器,通常需要设置定时器的重载值,选择时钟源,并可选地使能SysTick中断。以下步骤展示了如何在裸机编程中初始化SysTick定时器,不依赖特定的硬件抽象层(HAL)或类似库
步骤1: 选择SysTick时钟源
SysTick定时器可以选择使用核心时钟或核心时钟的1/8作为其时钟源。这个设置通过SysTick控制和状态寄存器(SysTick CTRL)中的CLKSOURCE位来控制。一般情况下,我们通常使用核心时钟为SysTick定时器提供时钟,以达到更高的时间精度。
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
步骤2: 设置重载值(Reload Value)
SysTick的重载值决定了定时器计数到0所需要的时钟周期数。这个值根据定时器所需的时间间隔来计算,并设置在SysTick重载值寄存器(SysTick LOAD)中。重载值计算公式如下,假设您要设置的定时时间是time_ms
毫秒。
uint32_t reloadValue = (SystemCoreClock / 1000) * time_ms - 1;
SysTick->LOAD = reloadValue;
这里SystemCoreClock
变量表示系统的核心时钟频率,它需要根据实际的系统核心时钟进行设
步骤3: 使能SysTick定时器和中断(可选)
使能SysTick定时器,选择是否使能中断。如果需要定时器到0时产生中断,还需要使能SysTick中断。
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; // 使能SysTick中断
SysTick->VAL = 0; // 清空计数器
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 启动SysTick定时器
步骤4: 实现SysTick_Handler中断服务例程(如果使能了中断)
如果你使能了SysTick中断,你需要实现SysTick_Handler()
中断服务例程(ISR)来处理中断。这个函数在SysTick计数到0时被调用。
void SysTick_Handler(void) {// 处理中断。例如,更新定时器标志,执行定时任务等。
}
以上就是初始化SysTick定时器的基本步骤。这个过程允许你根据需要配置SysTick定时器,来实现周期性的任务调度或生成准确的延时。
如何计算SysTick定时器的重载值?
计算SysTick定时器的重载值需要知道你想要定时器溢出的时间间隔以及定时器的时钟频率。以下是计算过程:
-
确定时钟频率:
- 主时钟频率 (
SystemCoreClock
): 如果你选择的是处理器的核心时钟(通常情况下)。 - 分频后的时钟频率: 如果你选择的是分频后的时钟频率,例如核心时钟频率的1/8。
- 主时钟频率 (
-
计算时间间隔对应的时钟周期数:
根据定时器的时间间隔以及定时器的时钟频率,计算出所需的时钟周期数。如果定时器的时间间隔是T
秒,定时器的时钟频率是f_clock
赫兹,则对应的时钟周期数N
可用以下公式计算:N = T * f_clock
例如,如果你需要1毫秒的时间间隔,并且SysTick的时钟频率是
SystemCoreClock
,则N = 0.001 * SystemCoreClock
- 计算重载值:
SysTick是一个24位的递减到零计数器,计数从重载值开始,并每个时钟周期递减一直到0。因此,重载值应是计数周期数减1。如果重载值设为R
:R = N - 1
这是因为从
R
递减到0正好是R + 1
个计数周期。 - 考虑24位计数器的最大值:
由于SysTick是24位的,其最大计数值是0xFFFFFF
(即16,777,215)。所以,要确保计算得出的R
不要超出这个范围。
示例:
假设:
核心时钟频率 SystemCoreClock
= 72 MHz
需要的定时器周期 T
= 1 ms(0.001秒)
计算周期数 N
为
N = 0.001 * 72 MHz = 72,000
你可以将这个值写入SysTick加载值寄存器(LOAD)来设置定时器每1毫秒溢出一次。
代码实现将类似于:
SysTick->LOAD = (uint32_t)(N - 1);
SysTick->VAL = 0x0; // 清空计数器
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; // 使能定时器
确保你选择对的时钟源(核心时钟,或核心时钟的1/8),因为这将直接影响上面的计算。如果你决定使用分频后的时钟源,你需要在计算时将 SystemCoreClock
替换为 SystemCoreClock / 8
。
如何使用systick实现delay功能
要使用SysTick定时器实现延时(delay)功能,你需要设置SysTick以适当的速率递减,并在递减到零时进行等待或触发中断。下面是实现delay
功能的基本步骤,不使用中断,而是使用轮询的方式。
轮询方式实现:
首先你需要正确配置SysTick定时器,包括选择时钟源,设置重载值等。
配置SysTick重载值:
计算并设置SysTick重载值,以匹配你需要的延时长度。例如,如果你的核心时钟是72MHz,你想要延时1毫秒:
uint32_t ticks = SystemCoreClock / 1000;
SysTick->LOAD = ticks - 1;
SysTick->VAL = 0; // 清除当前值及计数器
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; // 选择核心时钟并启动
实现delay
函数:
编写一个延时函数,该函数重复地加载重载值并等待SysTick递减到零
void delay_ms(uint32_t ms) {// 计算重载值(假设已经减去1且 SysTick->LOAD 直接可以使用)uint32_t ticks = (SystemCoreClock / 1000) * ms;SysTick->LOAD = (uint32_t)(ticks - 1UL);SysTick->VAL = 0UL; // 清除计数器// 等待计时器倒数到0while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) {// 该位在倒数到0时会设置,此处空循环直到满足该条件}
}
使用以上delay_ms()
函数可以实现毫秒延时。请注意,这里SysTick是设置了一次并等待它完成。如果延时时间长,你可以设置SysTick只延时1毫秒,然后在循环中多次调用该延时函数。
注意事项:
- 使用该轮询方法实现
delay
将阻塞CPU执行直到延时完成; - 确保在使用前SysTick 定时器尚未被操作系统或其它库使用;
- 在多任务或中断驱动的环境中,使用SysTick的方式可能会影响系统中断的响应性能;
- 上述示例假设
SystemCoreClock
已定义并且与实际的系统核心时钟同步。在实际项目中SystemCoreClock
往往是由系统初始化代码更新的全局变量,它通常在启动文件进行赋值。 - 如果需要长时间延时,确保重载值乘以延时毫秒数不会超过SysTick定时器的最大值。
对于具有实时操作系统(RTOS)的系统,最好利用操作系统提供的延时函数,因为这些函数更加精准且不会影响操作系统的性能。
相关文章:
STM32中的Systick的使用
SysTick,全称System Tick Timer,是Cortex-M microcontrollers内核中提供的一个简单而有效的系统定时器,设计用来给操作系统提供时间基准,或用于生成周期性的中断。STM32系列微控制器,作为基于ARM Cortex-M内核的设备&a…...
做一个桌面悬浮翻页时钟
毛玻璃效果翻页桌面悬浮时钟,TopMost(Topmost“True”),不在任务栏显示(ShowInTaskbar“False”),在托盘区显示图标,双击托盘区图标实现最小化和还原,右键托盘图标可选“…...

Transformers中加载预训练模型的过程剖析(一)
使用HuggingFace的Transformers库加载预训练模型来处理下游深度学习任务很是方便,然而加载预训练模型的方法多种多样且过程比较隐蔽,这在一定程度上会给人带来困惑。因此,本篇文章主要讲一下使用不同方法加载本地预训练模型的区别、加载预训练模型及其配置的过程,藉此做个记…...

数据可视化的艺术:使用Matplotlib和Seaborn揭示数据故事
引言 数据可视化是数据分析中的关键一环,它帮助我们理解数据模式、趋势和异常。在Python中,Matplotlib和Seaborn是两个流行的数据可视化库,它们提供了丰富的图表和图形选项,使数据的可视化变得简单而强大。 Matplotlibÿ…...

2024全新小狐狸AI免授权源码
源码安装说明: 下 载 地 址 : runruncode.com/php/19757.html 1. 在宝塔新建一个站点,选择 PHP 版本为 7.2、7.3 或 7.4。将压缩包上传到站点的根目录,并设置运行目录为 /public。 2. 导入数据库文件,该文件位于 …...

Python基础详解四
目录 一,Json解析 二,pyecharts模块 三,类和对象 四,类型注解 一,Json解析 字典转换为JSON: import jsondata [{"name":"袁震","age":20},{"name":"张三&…...
es6新语法和ajax和json
es6新语法 1.定义变量:let 2.定义常量:const <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…...

Hadoop3:HDFS副本节点选择逻辑讲解
一、副本节点选择(机架感知) 说明 第一个副本,因为我们的client可能是web页,也可能是shell终端。 如果是web页,则随机选取一个节点,如果是shell终端,则选择当前shell终端所在的节点。 节点距离最…...
Java 高级面试问题及答案 更新(二)
Java 高级面试问题及答案 以下是几个常见的Java高级面试问题及其答案,这些问题覆盖了Java语言的核心概念和高级特性。 问题1: 什么是Java内存模型(JMM),它在并发编程中扮演着什么角色? 答案: Java内存模型(JMM)是一个抽象的概念…...
MacOS安装Go
下载 Go 安装包: 访问 Go 官方网站的下载页面,找到适合 macOS 系统的 Go 安装包,并下载 go1.20.2.darwin-amd64.pkg(假设你的 macOS 是 64 位系统)。 安装 Go: 打开下载的安装包 go1.20.2.darwin-amd64.pk…...

【微服务最全详解】
文章目录 微服务微服务的介绍微服务服务架构演变 微服务网关微服务的负载均衡微服务的容灾机制服务崩溃服务容灾机制微服务熔断机制微服务限流Sentinel怎么实现限流微服务限流算法1.令牌桶算法2.漏斗桶算法 服务监控日志收集 微服务 微服务的介绍 微服务是一种软件架构风格&a…...

如何在云电脑实现虚拟应用—数据分层(应用分层)技术简介
数据分层(应用分层)技术简介 近几年虚拟化市场实现了非常大的发展,桌面虚拟化在企业中应用越来越广泛,其拥有的如下优点得到大量企业的青睐: 数据安全不落地。在虚拟化环境下面数据保存在中心服务器上面,…...

【动态规划五】回文串问题
目录 leetcode题目 一、回文子串 二、最长回文子串 三、分割回文串 IV 四、分割回文串 II 五、最长回文子序列 六、让字符串成为回文串的最少插入次数 leetcode题目 一、回文子串 647. 回文子串 - 力扣(LeetCode)https://leetcode.cn/problems/…...

【C++杂货铺铺】AVL树
目录 🌈前言🌈 📁 概念 📁 节点的定义 📁 插入 📁 旋转 1 . 新节点插入较高左子树的左侧---左左:右单旋 2. 新节点插入较高右子树的右侧---右右:左单旋 3. 新节点插入较高左…...

【R语言】生存分析模型
生存分析模型是用于研究时间至某个事件发生的概率的统计模型。这个事件可以是死亡、疾病复发、治疗失败等。生存分析模型旨在解决在研究时间相关数据时的挑战,例如右侧截尾(右侧截尾表示未观察到的事件发生,例如研究结束时还未发生事件&#…...

「AIGC」Python实现tokens算法
本文主要介绍通过python实现tokens统计,避免重复调用openai等官方api,开源节流。 一、设计思路 初始化tokenizer使用tokenizer将文本转换为tokens计算token的数量二、业务场景 2.1 首次加载依赖 2.2 执行业务逻辑 三、核心代码 from transformers import AutoTokenizer imp…...
【Unity】编程感悟20240510
【背景】 这一点感悟是过去有所认识,但是最近写Unity项目,涉及UDP通信需要持续监听逻辑时更加感受深刻的。 选用合适的触发点,用明确的逻辑避免循环处理 尽量采用明确的触发点使逻辑清晰,规避一定时间刷新这类的逻辑。 比如UDP…...

C#【进阶】泛型
1、泛型 文章目录 1、泛型1、泛型是什么2、泛型分类3、泛型类和接口4、泛型方法5、泛型的作用思考 泛型方法判断类型 2、泛型约束1、什么是泛型2、各泛型约束3、约束的组合使用4、多个泛型有约束思考1 泛型实现单例模式思考2 ArrayList泛型实现增删查改 1、泛型是什么 泛型实现…...

50. UE5 RPG FGameplayEffectContext
接下来,我想实现处理完伤害时,将伤害的触发格挡或者触发暴击时的逻辑传递到数据集的PostGameplayEffectExecute里面,这样,在处理IncomingDamage时,我们可以通过释放触发格挡或者触发暴击在UI上面进行对应的效果表现。 …...
Golang 的 unmarshal 踩坑指南
文章目录 1. 写在最前面2. 字段区分出空字段还是未设置字段2.1 问题描述2.2 解决 3. 字段支持多种类型 & 按需做不同类型处理3.1 问题描述3.2 解决 4. 碎碎念5. 参考资料 1. 写在最前面 笔者最近在实现将内部通知系统的数据定义转化为产品定义的对外提供的数据结构。 举例…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...
WEB3全栈开发——面试专业技能点P7前端与链上集成
一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...

图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...