STM32--SYSTICK定时器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32--SYSTICK定时器相关的知识,希望对你有一定的参考价值。

STM32中的SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。

 

Systick定时器是一个24位递减计数器,224=16777216,所以Systick的计数最大值为16777215(从0-16777215),转化为16进制即0xFF FFFF;

           当定时器计到0 时,将从RELOAD 寄存器中自动重装载定时初值,开始新一轮的计数。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。

 

SysTick的时钟源可以是内部时钟(FCLK),也可以是外部时钟的分频(HCLK/8);

          由系统时钟树可以看到,当选择外部8MHZ晶振时,经过9倍频后,系统时钟为72MHz,所以选择外部时钟的分频时,此时SysTick的时钟即为9MHz,也就是SysTick的VAL寄存器每减一,耗时为1/9μs(9MHz的频率即1秒钟震动9,000,000次)。

 

SysTick共有4个寄存器,分别为:

            SysTick->CTRL,         --  控制和状态寄存器

            SysTick->LOAD,        --  重装载寄存器

            SysTick->VAL,           --  当前值寄存器

            SysTick->CALIB,       --  校准值寄存器

技术分享

 

固件库中,关于SysTick的相关函数有一下几句:

1 SysTick_CLKSourceConfig()          //Systick选择时钟源(FWLIB-misc.c文件中)
2 SysTick_Config(uint32_t ticks)     //初始化Systick(CORE-core_cm3.h文件中)

 

分别为:   1、配置SysTick的时钟源      2、配置相关寄存器

 

中断服务函数为:

void SysTick_Handler(void);   //stm32f10x_it

 

首先:

1、SysTick_CLKSourceConfig()函数,我们在misc.c中找到SysTick_CLKSourceConfig()的函数源码:

 1 void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
 2 {
 3   /* Check the parameters */
 4   assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
 5   if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
 6   {
 7     SysTick->CTRL |= SysTick_CLKSource_HCLK;          //内部时钟72M
 8   }
 9   else
10   {
11     SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;     //外部时钟 72/8=9M
12   }
13 }

 

由程序可以看出,在此函数里配置了SysTick->CTRL寄存器。

SysTick_CLKSourceConfig参数的两种情况:     

                  两种时钟源 :        SysTick_CLKSource_HCLK_Div8      外部时钟 72/8=9M 

                                         SysTick_CLKSource_HCLK              内部时钟 HCLK=72M

 

2、SysTick_Config(uint32_t ticks)函数,core_cm3.h中找到SysTick_Config函数源码:

static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);       //ticks参数有效性检查

  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; //设置重装载值
                                                    //-1:装载时消耗掉一个Systick时钟周期

  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); //配置NVIC

  SysTick->VAL   = 0;    //初始化VAL=0,使能Systick后立刻进入重装载
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |      //选择时钟源
                   SysTick_CTRL_TICKINT_Msk   |      //开启Systick中断
                   SysTick_CTRL_ENABLE_Msk;          //使能Systick定时器
  return (0);      /* Function successful */
}

#endif

 

 在这段函数中,对CTRL、LOAD、VAL三个寄存器进行了配置,初始化了SysTick所使用的时钟,清除系统当前值,装入重装值,使能了Systick定时器,开启了SysTick中断;

所以,在主程序中调用SysTick_Configuration(uint32_t ticks),输入重装值即可。

 

 

用SysTick定时器实现延时:

1、初始化延时函数

1 static u8  fac_us=0;           //延时微秒的频率
2 static u16 fac_ms=0;           //延时毫秒的频率
3 
4 void delay_init()
5 {
6     SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择时钟源-外部时钟-HCLK/8
7     fac_us=SystemCoreClock/8000000; // 72/8 9MHz 1s震动9,000,000次,所以延时1微秒(除以1,000,000)9个时钟周期
8     fac_ms=(u16)fac_us*1000;   // 延时1毫秒9000个Cystic时钟周期
9 }

 

 2、微秒μs延时函数:

 1 void delay_us(u32 nus)
 2 {
 3     u32 temp;
 4     //nus*fac_us值最大不能超过SysTick->LOAD(24位)-1
 5     SysTick->LOAD=nus*fac_us;    // 设置重载值:n(us)*延时1us需要多少个SysTick时钟周期
 6     SysTick->VAL=0x00;                       // VAL初始化为0
 7     SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; // 使能SysTick定时器
 8     do
 9     {
10         temp=SysTick->CTRL;
11     }while((temp&0x01)&&!(temp&(1<<16)));    // 等待计数时间到达(位16)
12     SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; // 关闭使能
13     SysTick->VAL =0X00;                      // 重置VAL
14 }

 

 3、毫秒ms延时函数

 

 1 void delay_ms(u16 nms)
 2 {
 3     u32 temp;
 4     SysTick->LOAD=(u32)nms*fac_ms;
 5     SysTick->VAL =0x00;
 6     SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;
 7     do
 8     {
 9         temp=SysTick->CTRL;
10     }while((temp&0x01)&&!(temp&(1<<16)));
11     SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
12     SysTick->VAL =0X00;
13 }

 

 

 

                                                                                                                             2017-10-31      21:42:31

以上是关于STM32--SYSTICK定时器的主要内容,如果未能解决你的问题,请参考以下文章

STM32:SysTick定时器

STM32 SysTick 计数速度是应有的两倍

stm32 systick使用

stm32 systick的默认时钟是多少

STM32 定时器中断

STM32Cubemx——定时器中断