SysTick定时器

一、SysTick概述

  1.SysTick timer(STK)是一个 24 位的倒计数定时器,当计到 0 时,将从 RELOAD 寄存器中自动重装载定时初值。只要不把它在 SysTick 控制及状态寄存器中的使能位清除,就永不停息。

        2.利用 STM32的内部 SysTick (on-chip)来实现延时,这样既不占用中断,也不占用系统定时器。

        3.SysTick定时器被捆绑在NVIC(内嵌向量中断控制器Nested Vectored Interrupt Controller)中,用于产生SYSTICK异常(异常号:15)。

        4.SysTick中断的优先级可以被设置。

二、SysTick相关寄存器

(一)SysTick控制和状态寄存器(SysTick Control and Status Register)

1. 第一位TICKINT表示是否产生中断

2.对于stm32,外部时钟源是HCLK(AHB总线时钟)的1/8,内核时钟是HCLK时钟

3.配置函数:SysTick_CLKSourceConfig();

(二)SysTick重装载数值寄存器(SysTick Reload Value Register)

(三)SysTick当前数值寄存器(SysTick Current Value Register)

static void SetSysClockTo72(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    
  /* 使能HSE */    
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
  /* 等待HSE就绪并做超时处理 */
  do
  {
    HSEStatus = RCC->CR & RCC_CR_HSERDY;//如果标志位为1,则HSEStatus为1
    StartUpCounter++;  
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
 
  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  {
    HSEStatus = (uint32_t)0x01;
  }//再判断一遍
  else
  {
    HSEStatus = (uint32_t)0x00;
  }  
   
  //HSE启动成功则继续往下执行
  if (HSEStatus == (uint32_t)0x01)
  {
   //使能预处理指令,即一条指令取出另一条指令已经准备好被取
    FLASH->ACR |= FLASH_ACR_PRFTBE;
 
    /* Flash 2 wait state */  
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    
 
 
    /* HCLK = SYSCLK = 72M*/
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
      
    /* PCLK2 = HCLK = 72M*/
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    
    /* PCLK1 = HCLK = 36M*/
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
 
/*#ifdef STM32F10X_CL
    /* Configure PLLs ------------------------------------------------------*/
    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
        
    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
  
    /* Enable PLL2 */
    RCC->CR |= RCC_CR_PLL2ON;
    /* Wait till PLL2 is ready */
    while((RCC->CR & RCC_CR_PLL2RDY) == 0)
    {
    }
    
   
    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 
    RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
                            RCC_CFGR_PLLMULL9); */
    **上面的宏未定义不执行**
#else    
    /*  配置锁相环: PLLCLK = HSE * 9 = 72 MHz */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                        RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL */
 
    /*使能锁相环 */
    RCC->CR |= RCC_CR_PLLON;
 
    /* 等待PLL稳定*/
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
    
    /*选项PLLCLK作为系统时钟*/
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    
 
    /* 等待PLLCLK切换为系统时钟 */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    }
  }
  else//启动失败,用户可以在这里定义错误处理代码
  { /* If HSE fails to start-up, the application will have wrong clock 
         configuration. User can add here some code to deal with this error */
         
  }
}
#endif