STM32学习笔记一一SysTick

版权声明:原创文章转载请注明出处。 https://blog.csdn.net/wwt18811707971/article/details/82316850

1.简介

SysTick 定时器被捆绑在 NVIC 中,用于产生 SysTick 异常(异常号:15)。在以前,操作系统和有所有使用了时基的系统,都必须要一个硬件定时器来产生需要的“滴答”中断,作为整个系统的时基。滴答中断对操作系统尤其重要。例如,操作系统可以为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。

Cortex-M3 在内核部分 包含了一个简单的定时器——SysTick timer。SysTick定时器的时钟源可以是内部时钟(FCLK, CM3 上的自由运行时钟),或者是外部时钟(CM3 处理器上的 STCLK 信号)。不过, STCLK 的具体来源则由芯片设计者决定,因此不同产品之间的时钟频率可能会大不相同。因此,需要阅读芯片的使用手册来确定选择什么作为时钟源。在 STM32 中 SysTick 以 HCLK(AHB 时钟)或 HCLK/8 作为运行时钟
ysTick 定时器能产生中断, CM3 为它专门开出一个异常类型。SysTick 定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等。

2.SysTick timer工作原理

SysTick 是一个 24 位的定时器,即一次最多可以计数 2^24 个时钟脉冲,这个脉冲计数值被保存到 当前计数值寄存器 STK_VAL (SysTick current valueregister) 中,只能向下计数,每接收到一个时钟脉冲 STK_VAL 的值就向下减1,直至 0,当 STK_VAL 的值被减至 0 时,由硬件自动把重载寄存器STK_LOAD(SysTick reload value register) 中保存的数据加载到 STK_VAL,重新向下计数。当 STK_VAL 的值被计数至 0 时,触发异常,就可以在中断服务函数中处理定时事件了

3.SysTick timer寄存器

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

这里写图片描述

要使 SysTick 进行以上工作必须要进行 SysTick 进行配置。它的控制只有三个控制位和一个标志位,都位于寄存器 STK_CTRL(SysTick control and status register ) 中,

这里写图片描述

寄存器位 作用
Bit0 ENABLE:SysTick timer 的使能位,此位为 1 的时候使能 SysTick timer,此位为 0 的时候关闭 SysTick timer
Bit1 TICKINT:为此位为 1 并且 STK_VAL 计数至 0 时会触发SysTick 异常,此位被配置为 0 的时候不触发异常
Bit2 CLKSOURCE:为 SysTick 的时钟选择位,此位为 1 的时候 SysTick 的时钟为 AHB 时钟,此位为 0 的时候 SysTick 时钟为 AHB/8(AHB 的八分频)
Bit16 COUNTFLAG为计数为 0 标志位,若 STK_VAL 计数至 0,此标志位会被置 1

4.SysTick timer配置

SysTick timer 理论上它的最小计时单位为AHB 的时钟周期,即 1/72000000 秒, 72 分之一的微秒。

4.1 定时时间的计算:

重装载计数器的参数为: SystemCoreClock / 1000000 , SystemCoreClock 为定义了系统时钟(SYSCLK)频率的宏,即等于 AHB (72M) 的时钟频率, 这个 SystemCoreClock 宏展开为数值 7200 0000。输入参数为 SysTick 将要计的脉冲数,经过 ticks 个脉冲(经过 ticks 个时钟周期)后将触发中断,触发中断后又重新开始计数。

这里写图片描述

ticks:重装载寄存器 LOAD 的赋值;

1/f:SysTick timer 使用的时钟源的时钟周期, f 为该时钟源(72 or 72 / 8)的时钟频率,当时钟源确定后为常数。

定时1us :tibks = 72000000 / 1000000,表示 72 个周期中断一次,所以定时时间 T = 72 * (1/72)= 1us。

SysTick 定时器的定时时间(配置为触发中断,即为中断周期),由 ticks 参数决定,最大定时周期不能超过 2^24个。

5.软件实现

#include "systick.h"

u32 systick;

//系统滴答初始化
void SysTick_Init(void)
{
    SysTick->LOAD = (uint32_t)(SystemCoreClock/1000000-1UL);    //72M时钟,一次1us
    SysTick->VAL = 0UL;
    SysTick-> CTRL = SysTick_CTRL_ENABLE_Msk  | //使能
                     SysTick_CTRL_TICKINT_Msk | //触发异常
                     SysTick_CTRL_CLKSOURCE_Msk;    //时钟源选择
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //关闭滴答定时器
}

void delay_us(u32 time)
{
    (systick) = time;

    SysTick->VAL = 0;
    SysTick-> CTRL |= SysTick_CTRL_ENABLE_Msk;
    while((systick));
    SysTick-> CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

void delay_ms(u32 time)
{
    (systick) = time * 1000;

    SysTick->VAL = 0;
    SysTick-> CTRL |= SysTick_CTRL_ENABLE_Msk;
    while((systick));
    SysTick-> CTRL &= ~SysTick_CTRL_ENABLE_Msk;

}

//滴答中断
void SysTick_Handler(void)
{
    while(systick)
        (systick)--;
}

调用了 delay_us() 函数, SysTick 定时器就被开启,按照设定好的定时周期递减计数, SysTick 的计数寄存器里面的值减为 0 时,就进入中断函数,当中断函数执行完毕之后由重新计时,如此循环,除非它被关闭。


参考:

1.第18章 SysTick—系统定时器

猜你喜欢

转载自blog.csdn.net/wwt18811707971/article/details/82316850