Skip to content

SysTick

系统定时器, 24位只能递减计时, 位于内核, 嵌套在NVIC中, 所有的Cortex-M内核

image-20230630162556741

手册中描述很少, 在内核手册中有描述4.5.1

image-20230630162941501

image-20230630162951596

image-20230630170520541

  • STK_CTRL
  • STK_LOAD
  • STK_VAL
  • STK_CALIB 还有一个校准寄存器, 固定值为9000

函数

在文件core_cm3.h文件中

c
typedef struct
{
  __IO uint32_t CTRL;                         /*!< Offset: 0x00  SysTick Control and Status Register */
  __IO uint32_t LOAD;                         /*!< Offset: 0x04  SysTick Reload Value Register       */
  __IO uint32_t VAL;                          /*!< Offset: 0x08  SysTick Current Value Register      */
  __I  uint32_t CALIB;                        /*!< Offset: 0x0C  SysTick Calibration Register        */
} SysTick_Type;
c
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible 传入的数字过大*/
                                                               
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register初始化reload寄存器的值 */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M3 System Interrupts 配置中断优先级, 默认为最低的优先级*/
  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value 初始化计数器为0*/
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
                   SysTick_CTRL_TICKINT_Msk   | 
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer MSK为1设置时钟为72MHz, 产生中断, 使能*/
  return (0);                                                  /* Function successful */
}

配置函数

c
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
  if(IRQn < 0) {
      //内部中断配置的是这个寄存器, 这里使用数组的位数来代表指针进行控制对应的寄存器
    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
  else {
      //外设控制的是NVIC
    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */
}

image-20230630174108808

使用四个位控制优先级SCB_SHPR3

image-20230630174211636

  • 中断优先级对内核和外设的中断优先级同样适用

实际实现

c
void Systick_Delay_us(uint32_t us)
{
	uint32_t i;
	SysTick_Config(72);
	
	for(i=0;i<us;i++)
	{
		while(!(SysTick->CTRL & (1<<16)));
	}
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}


void Systick_Delay_ms(uint32_t ms)
{
	uint32_t i;
	SysTick_Config(72000);
	
	for(i=0;i<ms;i++)
	{
		while(!(SysTick->CTRL & (1<<16)));
	}
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

没有使用中断函数, 也可以使用中断函数来进行SysTick_Handler