• SysTick系统时钟是属于Cortex-M内核中的一个外设。内嵌在NVIC中
  • SysTick系统定时器含有一个计数宽度为24bit的向下递减的自动重装载计数器,计数器每计数一次时间为1.CLKSource。一般我们设置CLKSource为系统时钟。以F103为例,CLKSource可以配置为72MHz。
    • 计数宽度: 24bit存储数据,2^24 = 16777216
  • 当重载数值起存其的值递减到0的时候,SysTick系统定时器可以配置产生一次中断,以此循环往复
    • 向下递减: 计数器的工作模式
  • SysTick系统定时器是属于Cortex-M内核的外设,所以一般基于Cortex-M内核的单片机都具有这个系统定时器。这使得软件在Cortex-M内核的单片机都具有这个系统定时器,这使得软件在Cortx-M单片机中可以很容易的移植
    • 1/CLKSource(时钟源),1/72MHz = 1/72000000

      16777216 向下递减1/72000000的时间计数器都会向下递减16777216

计算公式 1/72000000 2^24得出结论的单位是*秒

SysTick定时器的功能

  • SysTick系统定时器可以用于操作系统,用于产生时基维持操作系统的心跳。一般操作都需要一个时基,进行任务调度、同步等功能实现
  • SysTick系统定时器最常用的功能,还是计数。比如用来进行微妙、毫秒延时,以此产生特定时许

SysTick寄存器介绍

寄存器名称 寄存器描述
CTRL SysTick控制及状态寄存器
LOAD SysTick重装载数值寄存器
VAL SysTick数值寄存器
CALIB SysTick校准数值寄存器

控制及状态寄存器
位段 名称 类型 复位值 描述
16 COUNTFLAG R/W 0 如果在上次读取本寄存器后。SysTick已经计到了0,则该位为1
2 CLKSOURCE R/W 0 时钟源选择位,0=外部时钟;1=处理器时钟AHB
1 TICKINT R/W 0 1=SysTick倒数计数器到0时产生SysTick异常请求。0=数到0时无动作。也可以通过读取COUNTFLAG标志位来确定计数器是否递减到0
0 ENABLE R/W 0 SysTick定时器使能位

SysTock 重装载数值寄存器
位段 名称 类型 复位值 描述
23:0 RELOAD R/W 0 当倒数计数至0时,将被重装在的值

SysTick当前数值寄存器
位段 名称 类型 复位值 描述
23:0 CURRENT R/W 0 读取时返回当前倒计数的值,写它则使之清零,同时还会清除在SysTick控制器中的COUNTFLAG标志

实验工程

image.png
image.png
就是时钟来源

HAL_Delay()使用的就是HAL库的SysTick

  • 1、初始化系统时钟
    1. /* Private function prototypes -----------------------------------------------*/
    2. void SystemClock_Config(void);
  1. /**
  2. * @brief System Clock Configuration
  3. * @retval None
  4. */
  5. void SystemClock_Config(void)
  6. {
  7. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  8. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  9. /** Initializes the RCC Oscillators according to the specified parameters
  10. * in the RCC_OscInitTypeDef structure.
  11. */
  12. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  13. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  14. RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  15. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  16. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  17. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  18. RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  19. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  20. {
  21. Error_Handler();
  22. }
  23. /** Initializes the CPU, AHB and APB buses clocks
  24. */
  25. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  26. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  27. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  28. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  29. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  30. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  31. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  32. {
  33. Error_Handler();
  34. }
  35. }
  • 2、GPIO的初始化
    1. MX_GPIO_Init();
    通过GPIO板级支持包来提供支持的

可以自定义SysTick板级支持包

HAL库函数实现

路径: system_stm32f1xx.c -> stm32f1xx.h -> 芯片相应的头文件包(stm32f103xe.h) -> core_cm3.h

  1. __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
  2. {
  3. if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
  4. {
  5. return (1UL); /* Reload value impossible */
  6. }
  7. SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
  8. NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
  9. SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
  10. SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
  11. SysTick_CTRL_TICKINT_Msk |
  12. SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
  13. return (0UL); /* Function successful */
  14. }