(整理笔记)stm32 systick 的 研究和使用

来源:互联网 发布:淘宝店铺刷销量和好评 编辑:程序博客网 时间:2024/06/10 17:45

一、SysTick定时器的概念

 

Sys  系统 ,tick 滴答声 ,系统滴答滴答很形象地表示了它是一个系统节拍器。SysTick 是一个24 位的倒计数定时器,当计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。

二、SysTick定时器的作用

 

(1)产生操作系统的时钟节拍

SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。SysTick的最大使命,就是定期地产生异常请求,作为系统的时基。OS都需要这种“滴答”来推动任务和时间的管理。

(2)便于不同处理器之间程序移植。

CortexM3处理器内部包含了一个简单的定时器。因为所有的CM3芯片都带有这个定时器,软件在不同 CM3器件间的移植工作得以化简。该定时器的时钟源可以是内部时钟(FCLK,CM3上的自由运行时钟),或者是外部时钟( CM3处理器上的STCLK信号)。不过,STCLK的具体来源则由芯片设计者决定,因此不同产品之间的时钟频率可能会大不相同,你需要检视芯片的器件手册来决定选择什么作为时钟源。SysTick定时器能产生中断,CM3为它专门开出一个异常类型,并且在向量表中有它的一席之地。它使操作系统和其它系统软件在CM3器件间的移植变得简单多了,因为在所有CM3产品间对其处理都是相同的。

(3)作为一个闹铃测量时间。

SysTick定时器还可以用作闹钟,作为启动一个特定任务的时间依据。它作为一个闹铃,用于测量时间。要注意的是,当处理器在调试期间被喊停(halt)时,则SysTick定时器亦将暂停运作。

三、SysTick 的用法

 

SysTick有4个寄存器 :

寄存器                       描述

CTRL           SysTick 控制和状态寄存器

LOAD          SysTick 重装载值寄存器

VAL             SysTick 当前值寄存器

CALIB                SysTick 校准值寄存器

对应地在固件函数库中定义了这个东西

typedef struct

{

vu32 CTRL;

vu32 LOAD;

vu32 VAL;

vuc32 CALIB;

} SysTick_TypeDef;

在这背后,已经对定义的寄存器进行了一个地址映射。当我们操控我们定义的寄存器时实际上已是通过那种映射关系操控了芯片内部的值。其实在STM32中对寄存器的操作都是通过这种方式进行的。

具体的映射过程如下,我们可以看一下:

#define SCS_BASE ((u32)0xE000E000)

#define SysTick_BASE (SCS_BASE + 0x0010)

#ifndef DEBUG

...

#ifdef _SysTick

#define SysTick ((SysTick_TypeDef *) SysTick_BASE)

#endif /*_SysTick */

...

#else /* DEBUG */

...

#ifdef _SysTick

EXT SysTick_TypeDef *SysTick;

#endif /*_SysTick */

...

#endif

#ifdef _SysTick

SysTick = (SysTick_TypeDef *) SysTick_BASE;

#endif /*_SysTick */

为了访问SysTick寄存器,, _SysTick必须在文件“stm32f10x_conf.h”中定义如下:

#define _SysTick

映射过程就不作讨论了。总这这样映射的结果是我们能直接使用SysTick。那就来看一下有关寄存器的设置。

             

在最新的STM32固件库中的core_cm3.c中提供了这样一个函数来供我们配置SysTick,当我们须要用到SysTick时调用它就可以了:

static __INLINE uint32_t SysTick_Config(uint32_t ticks)//ticks是要重装载的值

{

if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);           

/* Reload value impossible 检查重装值是否可用 */

SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;     

/* set reload register */

/*

往LOAD寄存器中写入重装值,前面提到了我们可以直接使用SysTick,这里就可以看出来,我们要使用SysTick结构中的LOAD寄存器,于是我们就直接用到SysTick->LOAD

在core_cm3.c中也可以找到SysTick_LOAD_RELOAD_Msk的值为0xFFFFFFFFul,即unsigned long int 0xFFFFFFFF,请注意这样一句话:SysTick 是一个24 位的倒计数定时器,当计到0 时,将从RELOAD 寄存器中自动重装载定时初值。假设是你单独思考你会想到重装值是多少吗。为什么是ticks要减1,而不是ticks次。我们可以发现它是倒数到0的,也可以理解成从0计数到设定值的,所以它是ticks-1次。

*/

NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);

/* set Priority for Cortex-M0 System Interrupts */

SysTick->VAL   = 0;                                         

/* Load the SysTick Counter Value */

/* 装载系统当前值 */

SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |

SysTick_CTRL_TICKINT_Msk   |

SysTick_CTRL_ENABLE_Msk;                   

/* Enable SysTick IRQ and SysTick Timer */

/*

对CTRL进行配置,在core_cm3.c中有如下定义:

#define SysTick_CTRL_CLKSOURCE_Pos     2                                            

#define SysTick_CTRL_CLKSOURCE_Msk          (1ul<<SysTick_CTRL_CLKSOURCE_Pos)           

#define SysTick_CTRL_TICKINT_Pos        1                                            

#define SysTick_CTRL_TICKINT_Msk       (1ul << SysTick_CTRL_TICKINT_Pos)            

#define SysTick_CTRL_ENABLE_Pos       0                                        

#define SysTick_CTRL_ENABLE_Msk       (1ul <<SysTick_CTRL_ENABLE_Pos)

即有:SysTick_CTRL_CLKSOURCE_Msk = 0x00000004     clksource使用内部FCLK

  SysTick_CTRL_TICKINT_Pos    = 0x00000002        响应SysTick中断

SysTick_CTRL_ENABLE_Pos     = 0x00000001        使能SysTick

*/

return (0);             /* successful */ /*初始化成功返回值为0 */

}

总结:在配置过程对CTRL//LOAD/VAL三个寄存器进行了配置,初始化了SysTick使用的时钟,清除系统当前值,装入重装值,使能SysTick,使SysTick能响应中断,说了半天其实就这一句话。在主程序中调用SysTick_Configuration( uint32_t ticks ),输入重装值就配置完成了。

 

函数原型为void SysTick_Handler(void)

{

// user code

}

用户只要把须要处理的程序填入这里就完成啦。

 

原创粉丝点击