Stm32延时与计时方法(HAL库)

2023-05-16

文章目录

  • 一.延时的3种方法
    • 1.循环延时
    • 2.定时器中断延时与非中断延时
  • 三.定时器中断式计时与延时
  • 二.定时器非中断式延时
  • 四.代码例程
  • 五.同系列博客

一.延时的3种方法

首先,先了解一下什么延时。顾名思义,延时即是延长一段时间。

1.循环延时

这是最简单的延时方法,让单片机做一些无关紧要的工作来打发时间,这里通过循环的方式实现。但是,这种方法想到做到精准延时是需要经过不断测试的。

void delay_ms(u16 time)

{    
   u16 i=0;  
   while(time--)
   {
      i=12000;  //自己定义
      while(i--) ;    
   }
}

2.定时器中断延时与非中断延时

在实际应用中,我们常采用的是定时器延时。定时器延时分为中断延时与非中断延时。两种方法在延时效果上是一样的,只是实现的过程不一样。

中断延时通过在中断中的计数值的不断递减来达到精确延时,而非中断则通过在循环里不停查询寄存器数值来达到精确延时。前者因为中断的存在,不利于在其他中断中调用延时函数。在很多延时教程中,都喜欢推荐非中断式的延时。不过对于非特殊情况,两者的效果是一样的。反而非中断延时需要操作寄存器,反而更难理解。

三.定时器中断式计时与延时

首先,需要用CubeMX配置一个定时器(以TIM4为例),配置如下:
在这里插入图片描述
步骤:

    1. 打开TIM4,将分频系数设置为71(我使用的是STM32F103C8,高速外部晶振为72MHz,分频后所得频率即为1MHz,换句话说定时器每次计数的时间间隔为1us)。分频系数的需要视自己选择的芯片而定。

   2. 重转载值设定为最大值65535,同时打开中断。定时器每次计数的时间间隔是1us,而计数到65536将会溢出产生中断,所以每一次中断的时间间隔为65535us。

   3. 已知每次中断的时间间隔(65535us),同时记录下中断的次数(TimerCnt),再加上定时器当前计数值(CNT),便能得到系统的绝对时间了。即:

SystemTimer=TimerCnt*65535+CNT

以上就是利用定时器计时的原理,他能够记录你的单片机从开机后每一刻的绝对时间。下面给出实现的代码:

volatile uint32_t TimerCnt; //定时器中断的次数(设为全局变量)

void delay_Init() //定时器初始化
{
	HAL_TIM_Base_Start_IT(&htim4); //使能定时器中断
	HAL_TIM_Base_Start(&htim4);  //启动定时器
}

uint32_t Get_SystemTimer(void)//获取系统时间的函数
{
	return htim4.Instance->CNT + SystemTimerCnt * 0xffff;
	//系统时间=定时器当前计数值+65535*定时器中断次数
}


//CubeMX生成的TIM4中断服务函数,在stm32f1xxit.c中
void TIM4_IRQHandler(void)  
{
  /* USER CODE BEGIN TIM4_IRQn 0 */
  /* USER CODE END TIM4_IRQn 0 */
  HAL_TIM_IRQHandler(&htim4);
  /* USER CODE BEGIN TIM4_IRQn 1 */
	TimerCnt++;  //每中断一次TimerCnt计数值+1
  /* USER CODE END TIM4_IRQn 1 */
}

下面是我测试时的效果,Stm32从定时器初始化后开始不停得计时,计时精度还是挺高的。
在这里插入图片描述

计时记录的是单片机开机后的绝对时间,那么以此为时间轴,延时也就很容易完成了。只要记录下你延时开始的时间,然后在你预定的延时时间里用循环来阻塞就可以了。在上述的基础上加上如下代码;

//微秒延时
void delay_us(uint32_t delay_time)
{
	uint32_t temp = delay_time  + Get_SystemTimer();
	while(temp >= Get_SystemTimer());
}

//毫秒延时
void delay_ms(uint32_t delay_time)
{
		uint32_t temp = delay_time * 1000 + Get_SystemTimer();
		while(temp >= Get_SystemTimer());
}

二.定时器非中断式延时

以系统滴答计时器为例(代码来自网络,亲测有效)

//微秒延时
void delay_us(uint32_t nus)
{
 uint32_t temp;
 SysTick->LOAD = 9*nus;
 SysTick->VAL=0X00;//清空计数器
 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
 do
 {
  temp=SysTick->CTRL;//读取当前倒计数值
 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
     SysTick->CTRL=0x00; //关闭计数器
    SysTick->VAL =0X00; //清空计数器
}

//毫秒延时
void delay_ms(uint16_t nms)
{
 uint32_t temp;
 SysTick->LOAD = 9000*nms;
 SysTick->VAL=0X00;//清空计数器
 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
 do
 {
  temp=SysTick->CTRL;//读取当前倒计数值
 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
    SysTick->CTRL=0x00; //关闭计数器
    SysTick->VAL =0X00; //清空计数器
}

四.代码例程

已经把我写好代码上传到CSDN上,已经调试好,亲测有效。(代码例程)

五.同系列博客

  1. GPIO相关函数解析(HAL库)
  2. Stm32延时与计时方法(HAL库)
  3. 串口通讯知识梳理及在Stm32上的应用(HAL库)
  4. 串口DMA知识梳理以及在Stm32的应用(HAL库)
  5. CAN通信知识梳理及在Stm32上的应用(HAL库)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Stm32延时与计时方法(HAL库) 的相关文章

随机推荐

  • Visual Studio安装教程

    本文章主要记录Visual Studio2019的安装过程 xff0c 由于只用于开发C C 43 43 xff0c 因此关于其它语言支持将不安装 xff0c 仅供参考 一 下载 1 下载地址在微软官网 xff1a 微软官网 2 选择菜单栏
  • CAN波形解析实例(1)

    这里的CAN数据波形抓取的是两个STM32F103设备通过CAN通信一方发送另一方接收 xff0c CAN收发器使用的是TJA1051 xff08 扩展帧发送数据ID 61 0x18DAF110 Data 61 0x06 0x08 xff0
  • GPIO推挽输出和开漏输出模式区别详解

    以STM32参考手册中的GPIO输出配置图为例 xff1a 看到输出驱动器虚线框中的内容 xff0c 输出驱动器中的P MOS和N MOS两个MOS管就是实现推挽输出和开漏输出的关键 推挽输出模式下 xff0c P MOS和N MOS都正常
  • 树莓派新手入门教程

    截至目前 20210405 xff0c 树莓派最新版本为4B xff0c 如下图所示 xff1a 树莓派3B 43 的主要的部件位置 xff1a 下载最新Raspbian系统镜像 1 首先进入树莓派官网 xff1a https www ra
  • 公司研发工具链体系化建设,帮助公司从混乱走向正规

    一 软件发布平台 没办法对外提供二进制库下载便捷方式不方便部署 xff0c 不同版本之间预览和说明性欠缺问题 可以参考的解决方案 xff1a https www cnblogs com djlsunshine p 11164770 html
  • 关于写代码的几个看法

    最近在新公司负责bug的修复 xff0c 发现很多的代码逻辑理解起来有些困难 现在将其中观察到的现象列出来 xff0c 谈谈自己的看法 1 类过大 对于代码来说 xff0c 我们在编写的时候最好做到SRP Single Responsibi
  • 树莓派VNC server设置开机自启动

    目前已测试OK的几个方法 xff1a 方法1 xff08 作为服务自启动 xff09 xff1a 在 etc init d 中创建一个文件 例如tightvncserver xff1a span class token function s
  • 一个结构体 = 另一个结构体(同类型结构体之间可直接赋值操作)

    两个同类型结构体变量可以直接赋值 xff0c 不同类型结构体不能直接赋值 span class token macro property span class token directive hash span span class tok
  • FreeRTOS任务切换过程深层解析

    FreeRTOS 系统的任务切换最终都是在 PendSV 中断服务函数中完成的 xff0c uCOS 也是在 PendSV 中断中完成任务切换的 为什么用PendSV异常来做任务切换 PendSV 可以像普通中断一样被 Pending xf
  • QT C++入门学习(1) QT Creator安装和使用

    Qt官方下载 Qt 官网有一个专门的资源下载网站 xff0c 所有的开发环境和相关工具都可以从这里下载 xff0c 具体地址是 xff1a http download qt io 进入链接后 xff0c 是一个文件目录 xff0c 依次进入
  • QT初体验:手把手带你写一个自己的串口助手

    前言 本文记录一下用QT Creator 写一个基本功能齐全的串口助手的过程 xff0c 整个工程只有几百行代码 xff0c 跟着做下来对新手来说可以更快了解整个QT项目的开发过程和一些常用控件的使用方法 对新手学习QT能增强信心 xff0
  • QT如何打包生成独立可执行.exe文件

    一 将QT程序使用Release编译 二 新建一个文件夹 xff0c 将Release编译生成的exe文件复制到新建文件夹中 先找到Release编译生成的exe文件夹位置 xff0c 与项目创建的文件夹有关 xff1a 临时文件夹 rel
  • 利用OpenCV识别不规则图形轮廓并找其中心点和角度

    关于寻找图形的轮廓 xff0c 想来大家都不陌生 但平常寻找并进行识别的轮廓都是较为标准的图形 xff0c 如圆形 xff0c 矩形等 但在一些特殊情况下 xff0c 我们所检测的图形并不是理想的标准图形 比如说我们检测元件的引脚 xff0
  • 神经网络学习小记录21——InceptionV3模型的复现详解

    神经网络学习小记录21 InceptionV3模型的复现详解 学习前言什么是InceptionV3模型InceptionV3网络部分实现代码图片预测 学习前言 Inception系列的结构和其它的前向神经网络的结构不太一样 xff0c 每一
  • Ubuntu的快乐学习3——ros的launch用法

    Ubuntu的快乐学习3 ros的launch用法 学习前言launch是什么launch的使用方法一 简单使用二 常用标签1 launch标签2 node标签3 include标签4 remap标签5 param标签6 rosparam标
  • 三周年创作纪念日

    机缘 不知不觉已经开始分享三周年了 xff0c 最开始什么都不懂 xff0c 作为自动化的学生 xff0c 以为学点算法就可以变得厉害一些 xff0c 于是学了点C 43 43 相关就开始分享 后来立志于研究深度学习算法 xff0c 感觉强
  • win10+vs2017+opencv4.0.1+opencv_contrib-4.0.1详细教程

    最近想好好认真学习一下opencv4 0 xff0c 需要用到contrib扩展库 xff0c 配置完记录下 先写一下版本信息 xff1a opencv4 0 1 xff0c vs2017和 win10 其他opencv版本安装和配置原理一
  • OpenHD---低成本开源高清数字图传

    转载注明出处 文章目录 一 前言二 OpenHD简单介绍三 图传材料准备1 树莓派2 摄像头 排线 SD卡 读卡器4 网卡 四 硬件连接五 镜像刷写六 通电测试七 系统参数设置八 连接飞控九 关于二次开发十 最后 一 前言 这篇文章是对树莓
  • PS2手柄通讯协议解析---附资料和源码

    文章目录 一 PS2介绍二 PS2通讯协议介绍 xff08 1 xff09 PS2端口介绍 xff08 2 xff09 PS2通讯过程 三 基于STM32的PS2通信源码四 文档与源码下载链接 一 PS2介绍 今天就带大家来认识一下PS2的
  • Stm32延时与计时方法(HAL库)

    文章目录 一 延时的3种方法1 循环延时2 定时器中断延时与非中断延时 三 定时器中断式计时与延时二 定时器非中断式延时四 代码例程五 同系列博客 一 延时的3种方法 首先 xff0c 先了解一下什么延时 顾名思义 xff0c 延时即是延长