关于SystemInit()与滴答定时器在stm32f103中的使用说明如下

SysTick定时器:系统滴答定时器是一个非常基本的24位倒计时定时器,每隔一定的时间产生一个中断,即使是系统在睡眠模式下也能工作,它使得OS在各CM3器件间的移植过程中不必修改系统定时器的代码,将移植变得简单。SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。例如,为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。

下面介绍STM32中的systick,Systick 部分内容属于NVIC控制部分,一共有4个寄存器,名称和地址分别是:

SysTick_CTRL,        0xE000E010  --  控制以及状态寄存器
SysTick_LOAD,        0xE000E014  --  重载寄存器
SysTick_VAL,           0xE000E018  --  当前值寄存器
SysTick_CALIB,       0xE000E01C  --   校准值寄存器

首先看STK_CTRL控制寄存器:寄存器内有4个位具有意义
第0位:ENABLE,Systick 使能位  (0:关闭Systick功能;1:开启Systick功能)
第1位:TICKINT,Systick 中断使能位    (0:关闭Systick中断;1:开启Systick中断)
第2位:CLKSOURCE,Systick时钟源选择  (0:使用外部时钟作为Systick时钟,也就是使用HCLK/8 ;1:使用处理器时钟,也就是HCLK作为Systick时钟)
第3位:COUNTFLAG,Systick计数比较标志,如果在上次读取本寄存器后,SysTick 已经数到了0,则该位为1。如果读取该位,该位将自动清零

在arm出的《Cortex™-M3 Devices Generic User Guide》 (DUI0552A)里面很清楚在SYST_CSR描述里面[2] CLKSOURCE Indicates the clock source:

0 = external clock  默认复位后为0,使用外部时钟源STCLK,使用HCLK/8 作为Systick时钟;AHB/8
1 - processor clock.

该定时器的时钟源可以是外部时钟( CM3处理器上的STCLK信号),或者是内部时钟(FCLK,CM3上的自由运行时钟)。具体来源则由芯片设计者决定。

 

 

 

 

 在V3.5库函数中,有关SysTick的相关配置在core_cm3.h中:

  1. /**
  2.  * @brief Initialize and start the SysTick counter and its interrupt.
  3.  *
  4.  * @param ticks number of ticks between two interrupts
  5.  * @return 1 = failed, 0 = successful
  6.  *
  7.  * Initialise the system tick timer and its interrupt and start the
  8.  * system tick timer / counter in free running mode to generate
  9.  * periodical interrupts.
  10.  */
  11. static __INLINE uint32_t SysTick_Config(uint32_t ticks)
  12. {
  13.   if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */重装值超过24位,失败返回0
  14.                                                                
  15.   SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ 设置重装数值寄存器72000
  16.   NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */设置中断优先级
  17.   SysTick->VAL = 0; /* Load the SysTick Counter Value */                                               装载计数器数值当前清零
  18.   SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
  19.                    SysTick_CTRL_TICKINT_Msk |
  20.                    SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */  使能中断请求与滴答定时器
  21.   return (0); /* Function successful */
  22. }

 从上面可以看出,V3.5库函数默认使用HCLK作为SysTick时钟,执行SysTick_Config(72000)也就是SysTick->LOAD =72000, SysTick_CTRL初值为0x0007,开启Systick功能,开启Systick中断,使用HCLK作为Systick时钟。

注意:SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);此函数意思,仅仅用来设置SysTick_CTRL滴答控制器0x0004,选择内部时钟还是外部时钟。SysTick_Config()则是完整的函数。SysTick如果选用HCLK/8作为其时钟(也就是如果选择外部时钟)。那么可以执行SysTick_Config(9000)也就是SysTick->LOAD =9000,也就是计数9000以后产生1ms的时间基准。很难理解的一点,此刻函数delay_us(u32 nus) //装载计数SysTick->LOAD=9*nus,而不是装载计数SysTick->LOAD=72*nus。

void SysTick_Configuration(void)
{
  if (SysTick_Config(SystemCoreClock / 1000))                //SysTick配置函数
  {
       while (1);
  }  
  NVIC_SetPriority(SysTick_IRQn, 0x0);                            //SysTick中断优先级设置为0最高
}

关于SysTick_Config(SystemCoreClock / 1000)的理解
该函数的作用是打开计数器,设置计数周期,并使能中断。他所传入的参数,即计数周期。
周期计算方法是:默认情况下处理器在初始化时会调用SystemInit(),把系统频率设为72Mhz,即SystemCoreClock=72000000
          可以简单理解为系统一秒数72000000次,那么如果我需要1ms的定时周期,只需要让重载数为72000,就可达到要求
NVIC_SetPriority(SysTick_IRQn, 0x0); 设置优先级为最高,应根据自己的需要进行调整。最后就是进入中断处理函数了。

关于SysTick_Config(SystemCoreClock / 1000)返回值的理解。返回值0代表成功,返回值1代表失败。


void SysTick_Handler(void)
{
   ;
}

posted on 2020-03-29 17:14  一郎哥哥  阅读(1026)  评论(0编辑  收藏  举报

导航