STM32中微秒延时的实现方式

STM32中微秒延时的实现方式

  • 0.前言
  • 一、裸机实现方式
  • 二、FreeRTOS实现方式
  • 三、定时器实现(通用)
  • 4、总结


0.前言

  最近在STM32驱动移植过程中需要用到微秒延时来实现一些外设的时序,由于网上找到的驱动方法良莠不齐,笔者在实现时序过程中也浪费了不少时间。这里就将笔者觉得比较好的几种方式记录一下,方便后续使用,也可以作为参考。

一、裸机实现方式

  在STM32的裸机程序中,实现微秒延时比较简单,通过SysTick计时即可。关于SysTick的相关知识可以站内搜索,这里就不再过多赘述了,相关的delay_us函数参考了正点原子例程中的实现方式:

// 注意:nus的值,不要大于798915us(最大值即2^24/fac_us {fac_us=21})
void delay_us(uint32_t nus)
{uint32_t temp;SysTick->LOAD = nus * fac_us; // 时间加载,fac_us与时钟频率有关,例如:168Mhz时// fac_us=168,168/168M=1usSysTick->VAL = 0x00;                      // 清空计数器SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 开始倒数do{temp = SysTick->CTRL; // 读取控制及状态寄存器的值} while ((temp & 0x01) && !(temp & (1 << 16))); // 等待时间到达,使能且位16为0(未计到0)SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;      // 关闭计数器SysTick->VAL = 0X00;                            // 清空计数器
}

步骤:
1、根据延时时间和定时器所选时钟频率,计算出定时器要计数的时间数值;
2、将该数值加载到重装载寄存器中;
3、将当前值寄存器清零,打开定时器开始计数;
4、等待控制及状态寄存器的位16变为1;
5、关闭定时器,退出。

二、FreeRTOS实现方式

在FreeRTOS中,SysTick定时器的重装载值是固定的,且定时器是一直在工作的。因此像裸机编程中将时间数值加载到重装载寄存器的方法不再适用。经过多方的查找和修改,最终使用的以下的实现方式:

#include "main.h"
#include "FreeRTOSConfig.h"extern void vPortSetupTimerInterrupt( void );void delay_us(uint32_t nus)
{uint32_t ticks;uint32_t told, tnow, reload, tcnt = 0;if ((0x0001 & (SysTick->CTRL)) == 0) { // 定时器未工作vPortSetupTimerInterrupt();      // 初始化定时器}reload = SysTick->LOAD;                    // 获取重装载寄存器值ticks = nus * (SystemCoreClock / 1000000); // 计数时间值told = SysTick->VAL;                       // 获取当前数值寄存器值(开始时数值)while (1){tnow = SysTick->VAL; // 获取当前数值寄存器值if (tnow != told)    // 当前值不等于开始值说明已在计数{if (tnow < told) {        // 当前值小于开始数值,说明未计到0tcnt += told - tnow; // 计数值=开始值-当前值} else {                              // 当前值大于开始数值,说明已计到0并重新计数tcnt += reload - tnow + told; // 计数值=重装载值-当前值+开始值  (已从开始值计到0)}told = tnow; // 更新开始值if (tcnt >= ticks) {break; // 时间超过/等于要延迟的时间,则退出.}}}
}// SystemCoreClock为系统时钟(system_stmf1xx.c中),通常选择该时钟作为systick定时器时钟,根据具体情况更改

步骤:
1、根据延时时间和定时器所选时钟频率,计算出定时器要计数的时间数值;
2、获取当前数值寄存器的数值;
3、以当前数值为基准开始计数;
4、当所计数值等于(大于)需要延时的时间数值时退出。
注:由于笔者使用STM32CubeIDE中通过CMSIS封装后的FreeRTOS API,所以需要额外extern引入与初始化定时器相关的API。如果使用原生FreeRTOS API,则需要根据情况引入。

三、定时器实现(通用)

  这种方式的优点就是简单且易用,直接使用一个闲置定时器分频后即可。在CubeMX中配制定时器,笔者选择基本定时器 TIM7,预分频PSC设置为(TIM总线时钟 - 1),分频后频率为1MHz,即每次计数累加1/1000000秒 = 1us,计数区间65535,单次定时最长65535微秒,计数模式为up 向上计数,是否自动重新加载选disable,一次计数满后不再重新计数。
在这里插入图片描述

void  delay_us(uint16_t nus)
{__HAL_TIM_SetCounter(&htim7,0);__HAL_TIM_ENABLE(&htim7);while(__HAL_TIM_GetCounter(&htim7)<nus);__HAL_TIM_DISABLE(&htim7);
}

步骤:
1、首先对定时器中的计数器进行置0;
2、使能定时器;
3、循环等待;
4、关闭定时器退出;

4、总结

  由于微秒延时间隔较短,所以在FreeRTOS中使用时最好避免内核对该线程进行调度,否则调度到其他线程可能要等到下一个时间片才能恢复运行。笔者对这部分还没有仔细了解,如有条件最好还是对相关线程添加关闭和恢复线程调度的操作。

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

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

相关文章

【数据结构】败者树的建树与比较过程

文章目录 前置知识归并段 建树过程比较过程疑问为什么比较次数减少了&#xff1f;如果某个归并段的元素一直获胜&#xff0c;没有元素了怎么办&#xff1f;处理方法 1处理方法 2 前置知识 归并段 外部排序算法通常用于处理大规模数据&#xff0c;其中数据量远超过计算机内存的…

修改一下第二次课服务枚举等问题

关于AutoRuns 的总结里面&#xff0c;有个错误&#xff0c;Image hijacks 这个准确的描述应该是镜像劫持 和系统运行相关的image&#xff0c;我们通常指的是二进制镜像文件 Image hijacks镜像劫持 简单来说就是&#xff0c;在注册表中&#xff0c;有部分设置&#xff0c;是规…

产品经理入门学习(五):思维导图 原型设计

参考引用 黑马-产品经理入门基础课程 1. 思维导图的作用和应用场景 什么是思维导图&#xff1f; 思维导图是一种将思维进行可视化的实用工具。具体实现方法是用一个关键词去引发相关想法&#xff0c;再运用图文并茂的技巧把各级主题的关系用相互隶属的层级表现出来&#xff0c;…

Flutter笔记:发布一个模块 scale_design - (移动端)设计师尺寸适配工具

Flutter笔记 发布一个模块scale_design设计师尺寸适配工具与常用组件库 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/a…

容器核心技术-Namespace

一、容器 基于Linux 内核的 Cgroup&#xff0c; Namespace&#xff0c;以及Union FS等技术&#xff0c;对进程进行封装隔离&#xff0c;属于操作系统层面的虚拟化技术&#xff0c;由于隔离的进程独立于宿主和其它的隔离的进程&#xff0c;因此也称其为容器。 1.1 容器主要特性…

中国电子学会主办 第四届ATEC科技精英赛报名启动

11月1日由中国电子学会主办的第四届ATEC科技精英赛&#xff08;ATEC2023&#xff09;正式启动报名。 ATEC科技精英赛是主要面向中国籍计算机等专业在校学生、人工智能及网络安全行业研究者和从业者的一场高水平的智能科技挑战赛&#xff0c;意在贯彻落实党中央、国务院关于推动…

性能优化之懒加载 - 基于观察者模式和单例模式的实现

一、引入 在前端性能优化中&#xff0c;关于图片/视频等内容的懒加载一直都是优化利器。当用户看到对应的视图模块时&#xff0c;才去请求加载对应的图像。 原理也很简单&#xff0c;通过浏览器提供的 IntersectionObserver - Web API 接口参考 | MDN (mozilla.org)&#xff0c…

SpringSecurity全家桶 (二) ——实现原理

1. SpringSecurity的强大之处 当我们并未设置登录页面时&#xff0c;我们只需要导入SpringSecurity的依赖就可以令我们的界面进入保护状态&#xff0c;由下面例子可以凸显出&#xff1a; 随便写个接口 RequestMapping("/hello")public String hello(){return "H…

旧手机搭建linuxcentos

centos服务器搭建termux搭建centos旧手机搭建linux服务器ubuntu旧手机搭建网站旧手机搭建linux debian ubuntu centos 旧手机搭建宝塔搭建 32位Linux搭建宝塔 Linuxdeploy搭建宝塔 旧手机搭建服务器有需要的来 包答疑包售后 Linuxdeploy需要root mobile搭建服务器 脚本/工具

03 矩阵与线性变换

矩阵与线性变换 线性变换如何用数值描述线性变换特殊的线性变换反过来看总结 这是关于3Blue1Brown "线性代数的本质"的学习笔记。 线性变换 如果一个变换具有以下两个性质&#xff0c;我们就称它是线性的&#xff1a; 一是直线在变换后仍然保持为直线二是原点必须…

网安新旅程

网安新旅程 将近四个月没发博客了&#xff0c;今天交代一下最近发生的事情和规划。 TryHackMyOffsecBox QQ交流 君羊&#xff1a;751273347 近期的事情 6月开始我进入htb学院学习CPTS&#xff0c;7月左右我完成了95%左右的内容。7-8月份我基本都在做C#相关的开发&#xff0c…

【KVM】KVM介绍及功能概述

前言 大家好&#xff0c;我是秋意零。 今天介绍的内容是KVM的概述&#xff0c;以及它所支持的基本功能。 &#x1f47f; 简介 &#x1f3e0; 个人主页&#xff1a; 秋意零&#x1f525; 账号&#xff1a;全平台同名&#xff0c; 秋意零 账号创作者、 云社区 创建者&#x1f…

NTFS文件系统解析(三)

1、引言 对于NTFS文件系统而言&#xff0c;无论文件内容本身&#xff0c;抑或真实的文件属性&#xff0c;都被称之为属性。 而正如前文说到的&#xff0c;NTFS预定义了16种属性用于文件系统的管理。 而通常情况下&#xff0c;往往只需要关注其中的某些属性即可。 2、属性头 …

【AI】Stable-Diffusion-WebUI使用指南

注&#xff1a;csdn对图片有审核&#xff0c;审核还很奇葩&#xff0c;线稿都能违规&#xff0c;为保证完整的阅读体验建议移步至个人博客阅读 最近AI绘画实现了真人照片级绘画水准&#xff0c;导致AI绘画大火&#xff0c;公司也让我研究研究&#xff0c;借此机会正好了解一下…

一个JS版寻路的实现

js版的寻路的测试 20231104_161146 path get_v8: function (x_inc, y_inc) {if (x_inc 0) {if (y_inc < 0) {return [[0, -1], [-1, -1], [1, -1], [-1, 0], [1, 0], [-1, 1], [1, 1], [0, 1]];} else if (y_inc > 0) {return [[0, 1], [-1, 1], [1, 1], [-1, 0], [1, 0…

090基于web+springboot的中小企业设备管理系统

欢迎大家关注&#xff0c;一起好好学习&#xff0c;天天向上 文章目录 一项目简介技术介绍 二、功能组成三、效果图四、 文章目录 一项目简介 本中小企业设备管理系统管理员有个人中心&#xff0c;用户管理&#xff0c;员工管理&#xff0c;设备信息管理&#xff0c;配件信息管…

c++类和对象(八) static成员 友元

1.1 概念 声明为static的类成员称为类的静态成员&#xff0c;用static修饰的成员变量&#xff0c;称之为静态成员变量&#xff1b;用static修饰的成员函数&#xff0c;称之为静态成员函数。静态成员变量一定要在类外进行初始化。 面试题&#xff1a;实现一个类&#xff0c;计算…

【深度学习】pytorch——快速入门

笔记为自我总结整理的学习笔记&#xff0c;若有错误欢迎指出哟~ pytorch快速入门 简介张量&#xff08;Tensor&#xff09;操作创建张量向量拷贝张量维度张量加法函数名后面带下划线 _ 的函数索引和切片Tensor和Numpy的数组之间的转换张量&#xff08;tensor&#xff09;与标量…

2.10 CSS BFC

1.简介 BFC是Block Formatting Context(块级格式上下文)&#xff0c;可以理解成元素的一个“特异功能”。该“特异功能”&#xff0c;在默认的情况下处于关闭状态;当元素满足了某些条件后&#xff0c;该"特异功能被激活。所谓激活"特异功能”&#xff0c;专业点说就…