STM32滴答定时器SysTick理解+时基设置

文章介绍了STM32中的滴答定时器(SysTick)的作用,它是系统的心跳,用于提供周期性中断。通过SysTick_Config函数初始化定时器,设置心跳间隔。文章详细讲解了时钟源、四个寄存器的功能,并提供了ms和us延时函数的实现思路,利用中断计数实现延迟。

1.什么是滴答定时器?

Systick,主要的目的是为了给操作系统提供一个硬件上的中断(号称滴答中断),就是系统的心跳,操作系统进行运转的时候,它会根据“心跳”的节拍来工作,该定时器会产生周期性的中断,心跳一次就是中断一次,作为系统的参考时基,我们可以通过初始化这个定时器来改变心跳的间隔时间,其它的延时函数都是通过此定时器产生,如心跳间隔为1us,延时函数可以通过计数心跳次数来实现延时。

2.SysTick定时器初始化,确定心跳间隔

2.1 systick定时器时钟源?

在这里插入图片描述
这里看32的时钟树,32的时钟源有HSE,高速外部时钟,无源晶振(4-16M),通常为8M,当HSE故障时会切换到HSI,高速内部时钟,在芯片内部,8M,一般不会用,
SYSTICK从时钟树上可以看到其来源于PLLCLK锁相环时钟,HSI或HSE,最大为72M,三者其一,一般设置其等于锁相环时钟,通过寄存器的SW位来配置,锁相环时钟由时钟源经过倍频因子得到,一般选为9倍频,得到72M。

2.2定时器四个寄存器

Systick定时器模块中有4个32位寄存器,分别为:**控制及状态寄存器、重载寄存器、计数器、校准寄存器,**想要具体了解的可自己查询,这里总结一下其功能

寄存器总结:寄存器里面有计数器,每计一次数花费时间(1/72M)s,72M是根据时钟源自己选择的,也可以是别的,计数器是24位的,也就是计数值不超过2^24=16777216,计数时间最大为16777216/72000000=233ms,所以系统时基最大不能超过233ms,我们可以通过设置计数值来实现时基设置,如设置计数值72,时基为1us,设置计数值72000,时基为1ms.

2.函数设置

2.1SysTick_Config(uint32_t ticks)函数

此函数在core_cm3.h文件中,不用我们实现,这里是对寄存器操作,看懂就行,参数就是设置的计数值

在这里插入图片描述

2.2 初始化函数

1.SystemCoreClock是系统时钟,为72000000,除以1000000,设置SysTick_Config()函数参数为72,获得1us的时基,除以1000获得1ms的时基。

void SysTick_Init(void)
{
  us_tick = 0;
	/* SystemFrequency / 1000    1ms中断一次
	 * SystemFrequency / 100000	 10us中断一次
	 * SystemFrequency / 1000000 1us中断一次
	 */
	if (SysTick_Config(SystemCoreClock / 1000000))	// ST3.5.0库版本
	{ 
		while (1);
	}
}

3.延时函数实现

在上面设置好时基以后,1us产生一次systick中断,进入对应中断函数SysTick_Handler(void),函数在stm32f10x_it.c里,中断函数都在这,执行函数体。

void SysTick_Handler(void)
{
  us_tick++;
}

3.1ms延时思路及实现

现在设置是1us时基,进一次中断是1us,那我每进一次就计数一次,计1000次不就是1ms吗,类推,以此为基础来实现ms延时函数,

//在sys.c里定义一个全局变量,定时器初始化时将其置为0,启动定时器
__IO uint64_t  us_tick=0;  //#define   __IO    volatile 
//参数为延时的ms数,×1000得到us数,也就是需要中断发生的次
//数,设置目前中断次数+需要的,us_tick会不断+1更新,
//当到了所设置的值后,退出while循环,实现ms延时
void Delay_ms (uint32_t ms)
{ 
	uint32_t target;
	
	target = us_tick + us*1000;
	while(getCurrentMillis() <= target);
} 

//参数为延时的ms数,×1000得到us数,也就是需要中断发生的次
//数,设置目前中断次数+需要的,us_tick会不断+1更新,
//当到了所设置的值后,退出while循环,实现ms延时

3.2 us延时

us延时根本不用去单独实现,因为每中断一次的时间就是1us,直接获取当前us_tick值,在加上想要延时的us数,循环判断就行

void Delay_us(uint32_t us)
{ 
	uint32_t target;
	
	target = us_tick + us;
	while(getCurrentMillis() <= target);
}
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无敌最俊朗-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值