延时函数是怎么来的?频率和滴答计数之间的计算?(无ucos,小白向)

延时函数是怎么来的?频率之间的计算?(无ucos,小白向)


可以参考:定时器TIM配置微妙延时函数


以 stm32f103芯片,外接8MHz晶振 为例


延时函数Delay:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这几个函数相比几乎人人在使用
但是很多小白都只会用不知道含义是什么?
怎么写出来的?

当我从标准库转到HAl库的时候,再次移植了这个DELAY文件,这些函数引起了我的兴趣
我就想要知道这些函数具体是怎么操作时钟频率的

诶,会用,不会写,诶,老经典了


Systick定时器

Systick定时器就是系统滴答定时器,一个 24 位的倒计数定时器,计到 0 时,将从 RELOAD寄存器 中自动重装载定时初值。
只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。

Systick定时器,是一个简单的定时器,对于CM3,CM4内核芯片,都有Systick定时器。
Systick定时器常用来做延时,或者实时系统的心跳时钟。
可以节省MCU资源,不用浪费一个通用定时器。

SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。
Systick中断的优先级也可以设置。

4个Systick寄存器

CTRL             SysTick 控制和状态寄存器  
LOAD             SysTick 自动重装载除值寄存器 
VAL              SysTick 当前值寄存器
CALIB            SysTick 校准值寄存器

1、CTRL - SysTick 控制和状态寄存器

《Cortex-M3 权威指南》SysTick定时器:在这里插入图片描述
常用到的是以上四位:
位0:是否使能
位1:是否产生中断
位16:第一次读到置0,第二次置1,第三次置0……(以此类推)
位2:选择时钟源
对于STM32,外部时钟源是 HCLK(AHB总线时钟)的1/8
内核时钟是 HCLK时钟

实际应用:
代码位置::SysTick_CTRL_ENABLE_Msk
在这里插入图片描述

2、VAL - SysTick 当前值寄存器

《Cortex-M3 权威指南》SysTick定时器:
在这里插入图片描述

代码位置:
计数前后均要,清零
在这里插入图片描述

3、LOAD - SysTick 重装载数值寄存器

用来装载重装载值,前24位有效(如果有更高的位数的话)
在这里插入图片描述
代码位置:
在这里插入图片描述

4、CALIB - SysTick 校准数值寄存器(了解)

用的比较少
在这里插入图片描述

Systick库函数

固件库中的Systick相关函数:
//Systick时钟源选择 m i s c . c misc.c misc.c 文件中
SysTick_CLKSourceConfig()
//初始化systick,时钟为HCLK,并开启中断,位于core_cm3.h/core_cm4.h$文件中
SysTick_Config(uint32_t ticks)
//Systick中断服务函数
void SysTick_Handler(void)


void delay_init()函数剖析(计算)

在这里插入图片描述

void delay_init()
{
	/* 选择8分频 */
	HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8); //选择外部时钟  HCLK/8
	/* fac_us 微秒计数值 */
	fac_us = SystemCoreClock/8000000;				//为系统时钟的1/8
	/* fac_ms 毫秒计数值 */
	fac_ms = (u16)fac_us*1000;					//非OS下,代表每个ms需要的systick时钟数
}	

/*
* 标准库函数接口是SYSTICK_CLKSourceConfig()
* HAL库在前面加了HAL_,就成了HAL_SYSTICK_CLKSourceConfig()
*/

为什么 S y s t e m C o r e C l o c k SystemCoreClock SystemCoreClock 除于的是 8000000?

首先要明确几个已知条件:
系统频率 S y s t e m C o r e C l o c k = 72 M SystemCoreClock =72M SystemCoreClock=72M
分频数( n u m num num)是8分频
需要1微妙延时的计数值( a r r arr arr
计数值 ∗ 1 频率 = 1 微妙 计数值 * \frac{1}{频率} = 1微妙 计数值频率1=1微妙
频率 = 系统频率 / 分频数 频率 = 系统频率 / 分频数 频率=系统频率/分频数

列出公式:
计数值 / 系统频率 分频数 = 1 微妙 计数值 / \frac{系统频率}{分频数} = 1微妙 计数值/分频数系统频率=1微妙

代入: a r r / 72 M 8 = 1 / 1000000 arr / \frac{72M}{8} = 1 / 1000000 arr/872M=1/1000000

化简得: a r r = 72 M 8000000 arr = \frac{72M}{8000000} arr=800000072M

即 fac_us = S y s t e m C o r e C l o c k 8000000 \frac{SystemCoreClock}{8000000} 8000000SystemCoreClock

所以 S y s t e m C o r e C l o c k SystemCoreClock SystemCoreClock 除于的是 8000000

通过计算你可以发现 a r r = S y s t e m C o r e C l o c k n u m ∗ 1000000 arr = \frac{SystemCoreClock}{num * 1000000} arr=num1000000SystemCoreClock

这便就是1微妙需要滴答时钟计数arr次

而且 a r r = 9 arr = 9 arr=9,即滴答定时器每跳9次为1微妙延时

PS:时间戳

时间戳通常指的是表示某一时刻的时间标记,它可以是一个绝对时间点,也可以是一个相对于某个起始点的偏移量。
在计算机科学中,时间戳往往用来记录事件发生的时间顺序,或者用于同步和测量时间。
时间戳可以是简单的整数或浮点数,表示从某个固定的起始点以来的经过的秒数或微秒数。
(例如1970年1月1日00:00:00 UTC,即Unix时间)

在不同的上下文中,时间戳有不同的表现形式和用途。
例如,在网络通信中,时间戳可能用于确保数据包的有序到达;
在数据库中,时间戳可能用于记录记录最后更新的时间;
在编程中,时间戳可以用来创建一个唯一的标识符,或者作为算法的一部分来同步进程和设备。


┈┈┈┈▕▔╲┈┈┈┈┈┈┈ ┈┈┈┈▕▔╲┈┈┈┈┈┈┈ ┈┈┈┈▕▔╲┈┈┈┈┈┈┈┈
┈┈┈┈┈▏▕┈┈┈┈┈┈┈ ┈┈┈┈┈▏▕┈┈┈┈┈┈┈ ┈┈┈┈┈▏▕┈┈┈┈┈┈┈ ┈
┈┈┈┈┈▏ ▕▂▂▂▂▂┈┈┈┈┈┈┈▏ ▕▂▂▂▂▂┈┈┈┈┈┈┈▏ ▕▂▂▂▂▂┈┈┈
▂▂▂▂╱┈┈▕▂▂▂▂▏┈ ▂▂▂▂╱┈┈▕▂▂▂▂▏┈ ▂▂▂▂╱┈┈▕▂▂▂▂▏┈┈
▉▉▉┈┈┈┈▕▂▂▂▂▏ ┈ ▉▉▉┈┈┈┈▕▂▂▂▂▏ ┈ ▉▉▉┈┈┈┈▕▂▂▂▂▏ ┈
▉▉▉┈┈┈┈▕▂▂▂▂▏ ┈ ▉▉▉┈┈┈┈▕▂▂▂▂▏ ┈ ▉▉▉┈┈┈┈▕▂▂▂▂▏ ┈
▔▔▔▔╲▂▂▕▂▂▂▂▏┈ ▔▔▔▔╲▂▂▕▂▂▂▂▏┈ ▔▔▔▔╲▂▂▕▂▂▂▂▏┈┈

如果对你有帮助,就点赞收藏把!(。・ω・。)ノ♡

  • 21
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值