STM32 利用SysTick实现高精度计时

STM32 HAL库利用ARM Cortex-M内核自带的24位递减计数器SysTick(系统节拍),它属于 NVIC的一部分,且可以产生 SysTick 异常(异常类型#15)。通过读取并判断计数值来实现精确延时,从0xFFFFFF向下计数到0。可以用作I2C、SPI通信中的时序控制,RTOS环境中作为心跳时钟。

目录

一、微秒级延时函数 udelay

二、毫秒级延时函数 mdelay

三、获取系统时间函数 

四、函数调用


一、微秒级延时函数 udelay

udelay 函数用于实现微秒级的延时。它利用了 STM32 的 SysTick 定时器,这是一个 24 位的递减计数器。函数首先记录 SysTick 定时器当前的计数值 told 作为计时起点,并获取 SysTick 的重装载值 load。根据 LOAD + 1 个时钟对应 1ms 的关系,计算出输入的微秒数 us 对应的时钟滴答数 ticks。在一个无限循环中,不断获取当前的计数值 tnow,并根据计数值是否溢出计算已经过去的时钟滴答数 cnt。当 cnt 达到或超过 ticks 时,退出循环,延时结束。

/*********************************************************************** 函数名称: udelay* 功能描述: us 级别的延时函数* 输入参数: us - 延时多少 us* 输出参数: 无* 返 回 值: 无* 修改日期        版本号     修改人	      修改内容* -----------------------------------------------***********************************************************************/
void udelay(int us)
{// 记录 SysTick 定时器当前的计数值,作为计时起点uint32_t told = SysTick->VAL;uint32_t tnow;// 获取 SysTick 定时器的重装载值,用于后续计算uint32_t load = SysTick->LOAD;/* LOAD+1 个时钟对应 1ms* n us 对应 n*(load+1)/1000 个时钟*/// 根据输入的 us 数,计算需要的时钟滴答数uint32_t ticks = us*(load+1)/1000;// 用于累计已经过去的时钟滴答数uint32_t cnt = 0;// 进入循环,开始计时while (1){// 获取 SysTick 定时器当前的计数值tnow = SysTick->VAL;if (told >= tnow)// 如果计数值没有溢出,直接计算两次计数值的差值并累加到 cnt 中cnt += told - tnow;else// 如果计数值溢出了,需要加上重装载值来正确计算经过的滴答数cnt += told + load + 1 - tnow;// 更新计时起点为当前计数值told = tnow;if (cnt >= ticks)// 当累计的滴答数达到需要的滴答数时,退出循环,延时结束break;}	
}

二、毫秒级延时函数 mdelay

mdelay 函数用于实现毫秒级的延时。它通过循环调用 udelay 函数,每次延时 1000 微秒(即 1 毫秒),从而实现指定毫秒数的延时。这种设计利用了已实现的微秒级延时函数,提高了代码的复用性。

/*********************************************************************** 函数名称: mdelay* 功能描述: ms 级别的延时函数* 输入参数: ms - 延时多少 ms* 输出参数: 无* 返 回 值: 无* 修改日期        版本号     修改人	      修改内容* -----------------------------------------------***********************************************************************/
void mdelay(int ms)
{// 通过循环多次调用 udelay 函数,每次延时 1000us(即 1ms),实现 ms 级别的延时for (int i = 0; i < ms; i++)udelay(1000);
}

三、获取系统时间函数 

system_get_ns 函数用于获取系统时间,单位为纳秒。它首先获取 SysTick 定时器的重装载值 reload 和系统启动后经过的滴答数(单位为毫秒)ns。然后获取 SysTick 定时器当前的计数值 cnt,将 ns 转换为纳秒,并计算 SysTick 定时器从上次重装载后到现在经过的时间(单位为纳秒),累加到 ns 中,最后返回系统当前的时间。

/*********************************************************************** 函数名称: system_get_ns* 功能描述: 获得系统时间(单位 ns)* 输入参数: 无* 输出参数: 无* 返 回 值: 系统时间(单位 ns)* 修改日期        版本号     修改人	      修改内容* -----------------------------------------------*/uint64_t system_get_ns(void)
{// 用于存储 SysTick 定时器当前计数值和计算过程中的中间结果uint64_t cnt;// 获取 SysTick 定时器的重装载值uint32_t reload = SysTick->LOAD;// 获取系统启动后经过的滴答数,单位是 msuint64_t ns = HAL_GetTick();// 获取 SysTick 定时器当前的计数值cnt = SysTick->VAL;// 将系统启动后经过的时间从 ms 转换为 nsns *= 1000000;// 计算 SysTick 定时器从上次重装载后到现在经过的时间(单位 ns),并累加到 ns 中ns += (reload - cnt) * 1000000 / reload;// 返回系统当前的时间,单位为 nsreturn ns;
}

四、函数调用

在主循环中,代码实现了一个周期性的操作。首先,将 GPIOE 引脚 5 置高电平,点亮连接在该引脚上的设备。然后记录开始时间 start_time,调用 mdelay 函数延时 500 毫秒,再记录结束时间 end_time。通过计算 end_time 和 start_time 的差值,得到 mdelay(500) 函数执行所花费的时间 elapsed_time,并使用 printf 函数将其打印输出。最后,将 GPIOE 引脚 5 置低电平,熄灭连接的设备,再次延时 500 毫秒,完成一个周期的操作。

  while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */// 点亮 GPIOE 引脚 5 连接的设备HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET);// 记录开始时间start_time = system_get_ns();// 延时 500 毫秒mdelay(500);// 记录结束时间end_time = system_get_ns();// 计算从计时起始点到结束点所经过的时间,即代码在 mdelay(500) 执行期间所花费的时间// 将结果存储在 elapsed_time 变量中,单位为纳秒//elapsed_time = end_time - start_time;// 打印延时耗时printf("elapsed_time: %"PRIu64"\r\n", elapsed_time);// 熄灭 GPIOE 引脚 5 连接的设备HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_RESET);// 再延时 500 毫秒mdelay(500);}

五、运行结果

调用500ms延时测的时间是约500337532 ns

综上所述,这段代码通过合理利用 STM32 的 SysTick 定时器,实现了微秒和毫秒级的延时,以及系统时间的获取和代码执行时间的测量,控制 LED 闪烁。

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

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

相关文章

图像金字塔

图像金字塔&#xff08;MATLAB 版本&#xff09; 目录 图像金字塔&#xff08;MATLAB 版本&#xff09;一、 生成图像金字塔二、 Matlab实践操作三、实践问题 一、 生成图像金字塔 在 MATLAB 中&#xff0c;可以使用 impyramid 函数来生成图像金字塔。 代码示例&#xff1a; m…

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷(一)

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷&#xff08;一&#xff09; 第一部分&#xff1a;网络平台搭建与设备安全防护任务书DCRS:DCFW:DCWS:WAF: 第二部分&#xff1a;网络安全事件响应、数字取证调查、应用程序安全任务书任务 1&…

20250212:https通信

1:防止DNS劫持:使用 https 进行通信。 因为是SDK授权开发,需要尽量压缩so库文件和三方依赖。所以第一想法是使用 head only 的 cpp-httplib 进行开发。 cpp-httplib 需要 SSL 版本是 3.0及以上。但本地已经在开发使用的是1.0.2a版本,不满足需求。 方案1:升级OpenSSL 将Op…

一、C#基础入门课程【学习20天】01-07

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…

基于SpringBoot + Vue的共享汽车(单车)管理系统设计与实现+毕业论文+开题报告+指导搭建视频

本系统包含管理员、用户两个角色。 管理员角色&#xff1a;个人中心管理、用户管理、投放地区管理、汽车信息管理、汽车投放管理、汽车入库管理、使用订单管理、汽车归还管理。 用户角色&#xff1a;注册登录、汽车使用下单、汽车归还。 本共享汽车管理系统有管理员和用户。管…

DeepSeek+Kimi生成高质量PPT

DeepSeek与Kimi生成PPT全流程解析 一、工具分工原理 DeepSeek核心作用&#xff1a;生成结构化PPT大纲&#xff08;擅长逻辑构建与内容优化&#xff09;Kimi核心作用&#xff1a;将文本转换为视觉化PPT&#xff08;提供模板库与排版引擎&#xff09; 二、操作步骤详解 1. 通…

Android KMP初探

Android KMP初探 前言&#xff1a; 最近线上听了Kotlin官网举行的KMP会议&#xff0c;感觉听神奇的&#xff0c;于是就把官方demo下载下来尝试了一下&#xff0c;下载插件和所需要的依赖都用了很久&#xff0c;但是发现里面的代码很少&#xff0c;于是尝试自己手写了一下&…

鸿蒙NEXT应用App测试-通用测试

注意&#xff1a;大家记得学完通用测试记得再学鸿蒙专项测试 https://blog.csdn.net/weixin_51166786/article/details/145768653 注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章…

GO 快速升级Go版本

由于底层依赖升级了&#xff0c;那我们也要跟着升&#xff0c;go老版本已经不足满足需求了&#xff0c;必须要将版本升级到1.22.0以上 查看当前Go版本 命令查看go版本 go version [rootlocalhost local]# go version go version go1.21.4 linux/amd64 [rootlocalhost local]# …

Redis——用户签到BitMap,UV统计

目录 BitMap 使用场景 1. 用户签到系统 2. 用户行为标记 3. 布隆过滤器&#xff08;Bloom Filter&#xff09; BitMap介绍 Redis中的使用 Redis功能示例 添加&#xff1a; 获取&#xff1a; 批量获取&#xff1a; java中实现 统计本月连续签到次数 UV统计 UV 统计…

Redis|持久化

文章目录 总体介绍RDB&#xff08;Redis DataBase&#xff09;官网介绍案例演示优势劣势 总体介绍 官网地址&#xff1a;https://redis.io/docs/manual/persistence/ 持久化双雄&#xff1a; RDB&#xff08;Redis DataBase&#xff09;&#xff1a;RDB 是 Redis 默认的持久化…

51单片机编程学习笔记——点亮LED

大纲 器件51单片机开发板总结 安装驱动点亮LED烧录 随着最近机器人爆火&#xff0c;之前写的ROS2系列博客《Robot Operating System》也获得了更多的关注。我决定在机器人领域里再走一步&#xff0c;于是想到可以学习单片机。研究了下学习路径&#xff0c;最后还是选择先从51单…

基于Spring Boot的公司资产网站设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

华为2025年技术发布会:智能汽车核心技术大爆发

近日&#xff0c;华为在鸿蒙智行尊界技术发布会上发布了多项智能汽车核心技术&#xff0c;涵盖智能驾驶、安全防护、通信系统、座舱交互及电池技术等领域&#xff0c;标志着其从“被动智能”向“自主智能”的战略升级。 以下是核心技术的综合梳理&#xff1a; 六大核心创新 途…

ctfshow做题笔记—栈溢出—pwn57~pwn60

目录 前言 一、pwn57&#xff08;先了解一下简单的64位shellcode吧&#xff09; 二、pwn58 三、pwn59&#xff08;64位 无限制&#xff09; 四、pwn60&#xff08;入门难度shellcode&#xff09; 前言 往前写了几道题&#xff0c;与shellcode有关&#xff0c;关于shellc…

测试面试题:以一个登录窗口为例,设计一下登录界面测试的思路和方法

在测试登录窗口时,可以从 表单测试、 逻辑判断和 业务流程三个方面设计测试思路和方法。以下是一个详细的测试方案: 1. 表单测试 表单测试主要关注输入框、按钮等UI元素的正确性和用户体验。 测试点: 输入框测试 用户名和密码输入框是否正常显示。输入框是否支持预期的字符类…

小型字符级语言模型的改进方向和策略

小型字符级语言模型的改进方向和策略 一、回顾小型字符级语言模型的处理流程 前文我们已经从零开始构建了一个小型字符级语言模型,那么如何改进和完善我们的模型呢?有哪些改进的方向?我们先回顾一下模型的流程: 图1 小型字符级语言模型的处理流程 (1)核心模块交互过程:…

基于数据可视化+SpringBoot+安卓端的数字化施工项目计划与管理平台设计和实现

博主介绍&#xff1a;硕士研究生&#xff0c;专注于信息化技术领域开发与管理&#xff0c;会使用java、标准c/c等开发语言&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架…

初识.git文件泄露

.git 文件泄露 当在一个空目录执行 git init 时&#xff0c;Git 会创建一个 .git 目录。 这个目录包含所有的 Git 存储和操作的对象。 如果想备份或复制一个版本库&#xff0c;只需把这个目录拷贝至另一处就可以了 这是一种常见的安全漏洞&#xff0c;指的是网站的 .git 目录…

基于Nanopi duo2的WiFi智能摄像头

1.固件包烧录 https://wiki.friendlyelec.com/wiki/index.php/NanoPi_Duo2/zh#.E8.BF.9E.E6.8E.A5WiFi 固件包链接以及烧录工具都在上面链接中 烧录过程 使用读卡器将SD卡插入到电脑,然后打开烧录工具 2.通过串口工具连接板子使其连接WiFi 对应的串口工具,就是这个HyperT…