SysTick:系统滴答定时器

    技术2023-11-16  99

    SysTick讲解

    前言1.SysTick 寄存器介绍1.1 CTRL SysTick 控制及状态寄存器1.2 LOAD SysTick 重装载数值寄存器1.3 SysTick 当前数值寄存器1.4 SysTick 校准数值寄存器 2.SysTick 定时时间计算3.SysTick 寄存器结构体4.SysTick配置库函数5.函数设计5.1 微秒延时函数5.1 毫秒延时函数 后记

    前言

    SysTick—系统定时器是属于 CM3 内核中的一个外设,内嵌在 NVIC 中。为操作系统服务。

    放在了NVIC中,主要的目的是为了给操作系统提供一个硬件上的中断(号称滴答中断)。滴答中断?这里来简单地解释一下。操作系统进行运转的时候,也会有“心跳”。它会根据“心跳”的节拍来工作,把整个时间段分成很多小小的时间片,每个任务每次只能运行一个“时间片”的时间长度就得退出给别的任务运行,这样可以确保任何一个任务都不会霸占整个系统不放。或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。

    系统定时器是一个 24bit 的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般我们设置系统时钟 SYSCLK 等于 72M。当重装载数值寄存器的值递减到 0 的时候,系统定时器就产生一次中断,以此循环往复。

    1.SysTick 寄存器介绍

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

    1.1 CTRL SysTick 控制及状态寄存器

    1.2 LOAD SysTick 重装载数值寄存器

    1.3 SysTick 当前数值寄存器

    1.4 SysTick 校准数值寄存器

    统定时器的校准数值寄存器在定时实验中不需要用到。有关各个位的描述这里引用手册里面的英文版本,比较晦涩难懂,暂时不知道这个寄存器用来干什么。

    2.SysTick 定时时间计算

    t:一个计数循环的时间,跟reload和CLK有关 CLK:72M或者9M,由CTRL寄存器配置 RELOAD:24位,用户自己配置

    t = reload*( 1/clk ) Clk = 72M时,t = (72) *(1/ 72 M )= 1US Clk = 72M时,t = (72000) *(1/ 72 M )= 1MS 时间单位换算: 1s = 1000ms = 1000 000 us = 1000 000 000ns

    3.SysTick 寄存器结构体

    在固件库文件:core_cm3.h中定义 这里注意,配置结构体,其实就相当于配置寄存器。

    4.SysTick配置库函数

    这个是库函数中的东西,早core_cm3.h中,我们可以直接拿来用。

    //函数前面的是防止对寄存器进行优化 static __INLINE uint32_t SysTick_Config(uint32_t ticks) { // 判断 tick 的值是否大于 2^24,如果大于,则不符合规则 if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); // 初始化reload寄存器的值 SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; // 配置中断优先级,配置为15,默认为最低的优先级 NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); // 初始化counter的值为0 SysTick->VAL = 0; // 配置 systick 的时钟为 72M // 使能中断 // 使能systick SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; return (0); }

    5.函数设计

    5.1 微秒延时函数

    void SysTick_Delay_us(uint32_t us) { uint32_t i; SysTick_Config(72); for(i=0; i<us; i++) { while( !((SysTick->CTRL) & (1<<16)) ); } SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk; }

    5.1 毫秒延时函数

    void SysTick_Delay_ms(uint32_t ms) { uint32_t i; SysTick_Config(72000); for(i=0; i<ms; i++) { while( !((SysTick->CTRL) & (1<<16)) ); } SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk; }

    后记

    可以实现灯的精确闪烁: main.c:

    #include "stm32f10x.h" // 相当于51单片机中的 #include <reg51.h> #include "bsp_led.h" #include "bsp_systick.h" void Delay( uint32_t count ) { for(; count!=0; count--); } int main(void) { // 来到这里的时候,系统的时钟已经被配置成72M。 LED_GPIO_Config(); while(1) { //GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN); LED_G(OFF); //Delay(0xFFFFF); SysTick_Delay_ms(500); //GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN); LED_G(ON); //Delay(0xFFFFF); SysTick_Delay_ms(500); } }
    Processed: 0.028, SQL: 10