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

文章目录

  • 1.什么是滴答定时器?
  • 2.SysTick定时器初始化,确定心跳间隔
    • 2.1 systick定时器时钟源?
    • 2.2定时器四个寄存器
    • 2.函数设置
      • 2.1SysTick_Config(uint32_t ticks)函数
      • 2.2 初始化函数
  • 3.延时函数实现
    • 3.1ms延时思路及实现
    • 3.2 us延时

1.什么是滴答定时器?

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

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

2.1 systick定时器时钟源?

STM32滴答定时器SysTick理解+时基设置_第1张图片
这里看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文件中,不用我们实现,这里是对寄存器操作,看懂就行,参数就是设置的计数值

STM32滴答定时器SysTick理解+时基设置_第2张图片

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);
}

你可能感兴趣的:(stm32,单片机,嵌入式硬件)