SysTick—系统定时器

SysTick简介

SysTick—系统定时器是属于 CM3 内核中的一个外设,内嵌在 NVIC 中。系统定时器是一个 24bit
的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般我们设置系统时钟 SYSCLK
等于 72M。当重装载数值寄存器的值递减到 0 的时候,系统定时器就产生一次中断,以此循环往
复。
因为 SysTick 是属于 CM3 内核的外设,所以所有基于 CM3 内核的单片机都具有这个系统定时器,
使得软件在 CM3 单片机中可以很容易的移植。系统定时器一般用于操作系统,用于产生时基,维
持操作系统的心跳

SysTick作用与优势

SysTick使用基于硬件的计数器来实现周期性的中断,可用于实现系统的延时、定时、多任务调度等功能。

SysTick的作用

        实现系统延时:通过配置SysTick的计数器和中断,可以实现精确的微秒级别延时。这在许多嵌入式系统应用中非常重要,例如控制电机速度、等待传感器响应等。

        实现系统定时:通过SysTick中断触发周期性事件,可以实现周期性任务的调度。这对于需要定期执行某些操作的应用非常有用,例如LED闪烁、传感器采集等。

        实现多任务调度:通过SysTick中断触发任务切换,可以实现简单的多任务系统。这对于需要同时运行多个任务的应用非常有用,例如控制飞行器深度、高度和姿态等。

SysTick优势

        硬件支持:SysTick是处理器内置的硬件模块,无需外部器件支持,具有较高的可靠性和稳定性。

        高精度:SysTick计数器精度较高,通常为微秒级别,可满足大多数应用的需要。

        灵活配置:SysTick可以配置为不同的时钟源和计数器值,以满足各种应用需求。这使得它非常适合不同嵌入式系统和实时操作系统中的使用场景。

        节省功耗:SysTick可以在空闲状态下进入低功耗模式,以节省能源并延长电池寿命。这对于需要追求低功耗的嵌入式系统应用非常有帮助。

SysTick定时时间计算 

SysTick 寄存器介绍

 SysTick—系统定时器有 4 个寄存器,简要介绍如下。在使用 SysTick 产生定时的时候,只需要配
置前三个寄存器,最后一个校准寄存器不需要使用。

编程 (编写毫秒延时函数和微妙延时函数)

1.了解SysTick 配置库函数

__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
 // 不可能的重装载值,超出范围
 if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) {
 return (1);
 }

// 设置重装载寄存器
 SysTick->LOAD = (uint32_t)(ticks - 1);

 // 设置中断优先级
 NVIC_SetPriority (SysTick_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
 // 设置当前数值寄存器
 SysTick->VAL = 0;
 // 设置系统定时器的时钟源为 AHBCLK=72M
 // 使能系统定时器中断
 // 使能定时器
  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
  SysTick_CTRL_TICKINT_Msk |
  SysTick_CTRL_ENABLE_Msk;
  return (0);
 }

用固件库编程的时候我们只需要调用库函数 SysTick_Config() 即可,形参 ticks 用来设置重装载寄
存器的值,最大不能超过重装载寄存器的值 2^24,当重装载寄存器的值递减到 0 的时候产生中断,然后重装载寄存器的值又重新装载往下递减计数,以此循环往复。紧随其后设置好中断优先级,最后配置系统定时器的时钟等于 AHBCLK=72M,使能定时器和定时器中断,这样系统定时器就配置好了,一个库函数搞定。

2.了解SysTick中断优先级

static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
  if(IRQn < 0) {
    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
  else {
    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */
}

函数首先先判断形参 IRQn 的大小,如果是小于 0,则表示这个是系统异常,系统异常的优先级
由内核外设 SCB 的寄存器 SHPRx 控制,如果大于 0 则是外部中断,外部中断的优先级由内核外
设 NVIC 中的 IPx 寄存器控制。
因为 SysTick 属于内核外设,跟普通外设的中断优先级有些区别,并没有抢占优先级和子优先
级的说法。在 STM32F103 中,内核外设的中断优先级由内核 SCB 这个外设的寄存器: SHPRx
(x=1.2.3)来配置。

SPRH1-SPRH3 是一个 32 位的寄存器,但是只能通过字节访问,每 8 个字段控制着一个内核外设
的中断优先级的配置。在 STM32F103 中,只有位 7:4 这高四位有效,低四位没有用到,所以内核
外设的中断优先级可编程为: 0~15,只有 16 个可编程优先级,数值越小,优先级越高。如果软
件优先级配置相同,那就根据他们在中断向量表里面的位置编号来决定优先级大小,编号越小,
优先级越高。

在系统定时器中,配置优先级为 (1 « __NVIC_PRIO_BITS) - 1),其中宏 __NVIC_PRIO_BITS为 4,那计算结果就等于 15,可以看出系统定时器此时设置的优先级在内核外设中是最低的,如果要修改优先级则修改这个值即可,范围为: 0~15。

3.编写延时函数

 void SysTick_Delay_us(uint32_t us)
{
	uint32_t i ;
	SysTick_Config(72);//延时1us
	for(i=0;i<us;i++)
	{
// 当计数器的值减小到 0 的时候, CRTL 寄存器的位 16 会置 1
		while(!((SysTick->CTRL)&(1<<16)));
	}
// 关闭 SysTick 定时器
	SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}

 void SysTick_Delay_ms(uint32_t ms)
{
	uint32_t i ;
	SysTick_Config(72000);//延时1ms
	for(i=0;i<us;i++)
	{
// 当计数器的值减小到 0 的时候, CRTL 寄存器的位 16 会置 1
		while(!((SysTick->CTRL)&(1<<16)));
	}
// 关闭 SysTick 定时器
	SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值