美文网首页我爱编程
5.STM32之系统定时器(SysTick)

5.STM32之系统定时器(SysTick)

作者: 东方未曦 | 来源:发表于2016-06-30 11:44 被阅读581次

1.系统定时器介绍

总体概述

SysTick 定时器被捆绑在 NVIC 中,用于产生SysTick异常(异常号:15)。
SysTick 中断对系统尤其重要,操作系统提供的各种定时功能都与这个滴答定时器有关。因此。需要一个定时器来产生周期性的中断,而且最好让用户不能随意访问它的寄存器以维持系统“心跳”的节律。
SysTick 定时器能产生中断,CM3 为它专门开出一个异常类型,并且在向量表中有它的一席之地。它使操作系统和其他系统软件在 CM3 器件之间的移植变得简单,因为在所有的 CM3 产品中,SysTick的处理方式都是相同的。SysTick定时器不仅能服务于操作系统,还能用于延时,闹钟以及测量时间。

原理分析

SysTick 是一个24位的寄存器,因此它一次最多可以计数2的24次方个时钟脉冲。
用户定义一个时钟脉冲的值之后,这个值被送入计数寄存器中,每收到一个脉冲,这个值就减1,当这个值减小到0时就触发异常。

2.程序代码

程序目的:使用 SysTick 延时控制 LED 灯的闪烁。

<------------------------------------------------------------->

systick.h源代码:
#ifndef __SYSTICK_H
#define __SYSTICK_H

#include "stm32f10x.h"

void SysTick_Init(void);

void Delay_ms( __IO u32 nTime );

#endif
systick.c源代码:
/***************************************
程序的本意是想在初始化时关闭滴答定时器
在每次使用延时函数时再把它打开
这两句代码去掉,程序也可以正常运行 
***************************************/
#include "stm32f10x.h"
#include "systick.h"

static __IO u32 TimingDelay;

void SysTick_Init(void)
{
    
    /**********************************
    StstemFrequency / 1000      1ms
    StstemFrequency / 100000    10us
    StstemFrequency / 1000000   1us
    ***********************************/
    
    if( SysTick_Config( SystemCoreClock / 1000 ) )   //ST3.5.0 库版本
    {
        /* Capture error */
        
        while ( 1 );
    }
    
    /* 关闭滴答定时器 */
    //SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_MSK;
    
}

void Delay_ms( __IO u32 nTime )
{
    
    TimingDelay = nTime;
    
    /* 使能滴答定时器 */
    //SysTick->CTRL |= SysTick_CTRL_ENABLE_MSK;
    
    while( TimingDelay != 0 );
    
}

void TimingDelay_Decrement(void)
{
    
    if( TimingDelay != 0x00 )
    {
        TimingDelay --;
    }
    
}
stm32f103x_it.c源代码:
/******************************************************************
在stm32f103x_it.c文件中可以找到 SysTick_Handler 函数
这个函数是系统定义好的,在里面调用 TimingDelay_Decrement 函数即可
因为 TimingDelay_Decrement 函数是在别的地方定义的
所以要在 stm32f103x_it.c 中加上以下声明:
extern void TimingDelay_Decrement(void);
******************************************************************/
void SysTick_Handler(void)
{
    TimingDelay_Decrement();
}
主函数main.c源代码:
#include "stm32f10x.h"
#include "led.h"
#include "systick.h"

int main(void)
{
    LED_Init();
    SysTick_Init();
    LED2(ON);
    
    while(1)
    {
        
        Delay_ms(200);
        LED2_REV;
        LED3_REV;
        
    }
    
}

3.补充

在延时的函数中我们会发现 TimingDelay 这个变量,它的定义是这样的:

static __IO u32 TimingDelay;
static:

static 修饰符好理解,它用来声明静态变量,相当于全局变量。
我们知道,C/C++的变量都有一个作用域。举个例子,一个函数声明的变量只存在于它的执行过程中,这时变量保存在栈里。一旦退出函数,变量也就死亡了。而用 static 修饰的变量是存储在堆里的,知道整个程序结束它才会消失。
因此在我们进行延时的时候,需要让延时剩下的脉冲数一直存在于程序中,这样才能完成延时。

__IO:

__IO 本身是不存在于 C 语言中的,它是一个另一个修饰符的宏定义:

#define     __IO    volatile

如果一个值有可能会被意想不到的改变,那么它有必要被定义为 volatile。
这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

相关文章

网友评论

    本文标题:5.STM32之系统定时器(SysTick)

    本文链接:https://www.haomeiwen.com/subject/ycoxjttx.html