STM32 learning experience nine: Systick timer tick interpretation and delay function

Record it, to facilitate future ~ read
main content:
. 1) and associated registers Systick timer;
2) Systick correlation function and interpret the function code delay.
Official information: - "The Definitive Guide to Chinese Cortex-M3" Chapter 8, the last section --Systick timer
What 1. Systick timers are?
1.1 Systick timer is a simple timer, for CM3, CM4 chip core, has Systick timer;
1.2 Systick commonly used to delay timers, real-time system clock or heartbeat. This saves MCU resources, do not waste a timer;
1.3 Systick system tick timer is a timer, a 24-bit count down timers, counters to 0, from the auto-reload register RELOAD timing of the initial value. As long as it does not enable bit in the control and status register SysTick cleared, not cease, but also can operate in a sleep mode;
1.4 SysTick timer is tied in the NVIC, for generating SYSTICK abnormality (abnormality No: 15 );
1.5 Systick interrupt priority can also be set.
2. Systick associated registers
2.1 CTRL (SysTick Control and Status Register)
Here Insert Picture Description
1.1.1 For the STM32, an external clock source is HCLK (the AHB bus clock) 1/8, a core clock HCLK clock;
1.1.2 Configuration Function: SysTick_CLKSourceConfig () ;
2.2 the lOAD (the SysTick auto-reload register value addition)
Here Insert Picture Description
2.3 VAL (the SysTick current value register)
Here Insert Picture Description
2.4 CALIB (SysTick Calibration Value Register)
Here Insert Picture Description
2.4.1 Calibration Value Register allow the system to run on different CM3 products, can produce a constant frequency SysTick interrupt. The simplest approach is: write directly to the value TENMS reload register, so that, as long as no breakthrough system limits, will be able to do it once every 10ms SysTick exception. If other anomalies SysTick period, the ratio can be calculated based on the value of TENMS. But, in a few cases, the chip may not provide CM3 TENMS values (e.g., CM3 calibration input signal is pulled low) accurately, for insurance purposes, preferably using a reference manual TENMS before checking device.
3. Systick library functions
3.1 firmware library Systick correlation function:
3.1.1

SysTick_CLKSourceConfig()        //Systick时钟源选择(在misc.c文件中)//

3.1.2

SysTick_Config(uint32_t ticks)      //初始化systick,时钟为HCLK,并开启中断(在core_cm3.h/core_cm4.h文件中)

3.2 Systick interrupt service function:
3.2.1

void SysTick_Handler(void);

3.3 SysTick_CLKSourceConfig function:

void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)    //该函数在misc.c文件中//
{
/*Check the parameters */
assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
if
(SysTick_CLKSource == SysTick_CLKSource_HCLK)
{
SysTick->CTRL |= SysTick_CLKSource_HCLK;                   /*SysTick_CLKSource_HCLK 为0x00000004*/
}
Else
{
SysTick->CTRL &=
SysTick_CLKSource_HCLK_Div8;                               /* SysTick_CLKSource_HCLK_Div8为0xFFFFFFFB)*/
}
}

3.4 SysTick_Config function:

/* @brief  Initialize and start the SysTick counter and its interrupt.*/
/* @param  ticks   number of ticks between two interrupts*/
/* @return  1 = failed, 0 = successful*/
/* Initialise the system tick timer and its interrupt and start the system tick timer / counter in free running mode to generate periodical interrupts.*/
static __INLINE uint32_t SysTick_Config(uint32_t ticks)  //该文件位于core_cm3.h中,内核级别//
{ 
if (ticks >SysTick_LOAD_RELOAD_Msk)  return(1);               /* Reload value impossible */ 
/*SysTick_LOAD_RELOAD_Pos    0;*/  
/*SysTick_LOAD_RELOAD_Msk (0xFFFFFFul<<SysTick_LOAD_RELOAD_Pos);*/
/*将SysTick_LOAD_RELOAD_Msk的值设为0xFFFFFF*/
/* set reload register */                                                            
SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; 
/*set Priority for Cortex-M0 System Interrupts */
NVIC_SetPriority (SysTick_IRQn,(1<<__NVIC_PRIO_BITS) - 1);    /*设置优先级,暂时不细讲*/
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 */
/*SysTick_CTRL_CLKSOURCE_Pos          2;                                      */
/*SysTick_CTRL_CLKSOURCE_Msk         (1ul <<SysTick_CTRL_CLKSOURCE_Pos);      */
/*SysTick_CTRL_TICKINT_Pos            1;                                      */
/*SysTick_CTRL_TICKINT_Msk           (1ul<< SysTick_CTRL_TICKINT_Pos);        */
/*SysTick_CTRL_ENABLE_Pos             0;                                      */
/*SysTick_CTRL_ENABLE_Msk            (1ul<< SysTick_CTRL_ENABLE_Pos);         */
return (0);                                            /* Function successful */
}

3.5 Delay manner to achieve delay interrupted

static __IO uint32_t TimingDelay;
void Delay(__IO uint32_t nTime)              /*申明Delay()函数*/
{   
TimingDelay = nTime;  
while(TimingDelay != 0);
}
void SysTick_Handler(void)                   /*申明SysTick_Handler()函数,作用每隔1ms运行该函数*/
{
    if
(TimingDelay != 0x00)                        /*如果TimingDelay不等于0*/
     {       
TimingDelay--;                               /*则TimingDelay减1*/
     }
}
 int main(void)
 {if (SysTick_Config(SystemCoreClock/ 1000))    //systick时钟为HCLK,中断时间间隔1ms//
/*SysTick_Config()函数位于core_cm3.h中,请参考3.4小节,内核级别,若systick时钟选择为HCLK,不分频,则SystemCoreClock时钟频率为72MHz,因此SysTick_Config(72000),意思是以72MHz频率计数72000个ticks需要1ms*/
     {   
while (1);
     }   
while(1)
     {
Delay(200);                                 //延时200ms//}
}

3.6 delay_init () function read:

void delay_init()
{
//**#if SYSTEM_SUPPORT_OS**//                                            //如果需要支持OS.//
//**u32 reload;**//                
//**#endif**//                  
  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);                 //选择外部时钟  HCLK/8//
//**SysTick_CLKSource_HCLK_Div8为0xFFFFFFFB,选择外部时钟源的1/8,请参考3.3小节**//
  fac_us=SystemCoreClock/8000000;                                       //为系统时钟的1/8//  
//**SystemCoreClock时钟频率=HCLK=72MHz,SysTick时钟频率为9MHz,则1us时间内SysTick计数9次**//
//**#if SYSTEM_SUPPORT_OS                                               //如果需要支持OS.//
//**     reload=SystemCoreClock/8000000;                                //每秒钟的计数次数 单位为M//  
//**     reload*=1000000/delay_ostickspersec;                           //根据delay_ostickspersec设定溢出时间//
//reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右//
//**     fac_ms=1000/delay_ostickspersec;                               //代表OS可以延时的最少单位//          
//**     SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;                       //开启SYSTICK中断//
//**     SysTick->LOAD=reload;                                          //每1/delay_ostickspersec秒中断一次//      
//**     SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;                        //开启SYSTICK//    
#else
  fac_ms=(u16)fac_us*1000;                                              //非OS下,代表每个ms需要的systick时钟数//   
#endif
}       

3.7 void delay_us () function read:

//延时nus,nus为要延时的us数.  //   
void delay_us(u32 nus)
{              
  u32 temp;                   
  SysTick->LOAD=nus*fac_us;                                      //时间加载//                    
  SysTick->VAL=0x00;                                             //清空计数器//
  SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;                       //使能SysTick定时器//         
/*SysTick_CTRL_ENABLE_Pos              0;                                      */
/*SysTick_CTRL_ENABLE_Msk             (1ul<< SysTick_CTRL_ENABLE_Pos);         */  
  do
  {
         temp=SysTick->CTRL;
  }while((temp&0x01)&&!(temp&(1<<16)));                          //等待时间到达//  
//**temp为xxxx xxxx xxxx xxxx | xxxx xxxx xxxx xxx1,因此跟0x01与运算后,其值肯定不是0,而跟(1<<16)与运算后,不确定,若不为0,则说明COUNTFLAG值为1,经逻辑非运算符!后,值为0,则while(0),跳出循环。否则,while(1)**//
  SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;                       //关闭计数器//
  SysTick->VAL =0X00;                                            //清空计数器//       
}

3.8 void delay_ms () function read:

//延时nms//
//SysTick->LOAD为24位寄存器,所以,最大延时为: nms<=0xffffff*8*1000/SYSCLK//
//SYSCLK单位为Hz,nms单位为ms,对72M条件下,nms<=1864 //
void delay_ms(u16 nms)
{                            
  u32 temp;                 
  SysTick->LOAD=(u32)nms*fac_ms;                                     //时间加载(SysTick->LOAD为24bit)//
  SysTick->VAL =0x00;                                                //清空计数器//
  SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;                           //使能SysTick定时器// 
/*SysTick_CTRL_ENABLE_Pos              0;                                   */
/*SysTick_CTRL_ENABLE_Msk             (1ul<< SysTick_CTRL_ENABLE_Pos);      */
  do
  {
         temp=SysTick->CTRL;
  }while((temp&0x01)&&!(temp&(1<<16)));                              //等待时间到达//   
//**temp为xxxx xxxx xxxx xxxx | xxxx xxxx xxxx xxx1,因此跟0x01与运算后,其值肯定不是0,而跟(1<<16)与运算后,不确定,若不为0,则说明COUNTFLAG值为1,经逻辑非运算符!后,值为0,则while(0),跳出循环。否则,while(1)**//
  SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;                           //关闭计数器//
  SysTick->VAL =0X00;                                                //清空计数器//               
} 
#endif

Knowledge
1) register Systick familiar with their associated timer function;
2) review relevant knowledge clock system, reference may STM32 learning experience VII: Interpretation STM32 clock system block diagram related functions and
3) review the name mapping register address, refer STM32 learn experience six: C-related language learning and reading register address mapping name

Published 24 original articles · won praise 2 · Views 4123

Guess you like

Origin blog.csdn.net/Leisure_ksj/article/details/105273110