你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32G4之SysTick系统时钟

[复制链接]
STMCU小助手 发布时间:2022-7-6 14:36
一、SysTick系统滴答定时器% b& A+ e: O. h2 m/ X8 p
SysTick是一个24位定时器,属于Cortex-M4内核中的一个外设,类似NVIC。
* _2 l+ e8 I! x7 ?
" E8 T  `9 C* r& [; I9 V一个周期定时器,用于提供时间基准,多为操作系统所使用,常用于对时间要求严格的情况,意义是很重要的8 R* o7 ]5 N3 z# T
( w7 X8 P/ Z& t" a% f( ?/ j# Z
SysTick定时器一次最多可以计数2^24(24bit)个时钟脉冲,这个脉冲计数值保存在当前计数值寄存器STK_VAL(Systick current value register)中,只能向下计数,也就是倒计数。
0 x6 l$ t) H* X: y8 r* E+ K& |$ e9 M, H) p
每接收到一个时钟脉冲(CPU主频),STK_VAL的值就会向下减1,当减到0时,硬件会自动将重装载寄存器STK_LOAD(可以设定,跟STK_VAL初始值相等)中保存的数值加载到STK_VAL,使其重新计数,并且,系统滴答定时器就产生一次中断,以此循环往复,只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息
* k8 n6 n$ K; H+ ]% u6 R0 o9 n8 [, a2 z* @+ M+ `9 S
Systick相关寄存器0 h5 C" V: T0 |4 B2 M

$ L" g7 \$ ~: ^* E3 f) |% G 6G)86_27MR1RGKTB$)WLQHF.png
+ E; d4 Y4 n& c& h9 K' L ~KI21TGVTKZ87`6~PA3ZZSO.png ; D. ?! r" I6 }0 |8 x% l

* S+ P7 _5 n5 G& o! a$ P! r  N) ?" _- |若VAL中的数值为 80,脉冲频率为 80MHz,则VAL由 80 减到 0 所需要的时间为80/80MHz=1us,并且当减到 0 时会触发中断(相当于 1us 定时器),同时 LOAD 的值也会重新载入到VAL中" @7 l; a% q# M/ I% @3 x

7 t5 g( w2 _6 l3 e& H  KSTM32CubeMX系统时钟的配置
9 |3 Z' u3 ]$ o6 P1 E6 f4 u$ a
2 Q) z: h7 `2 R4 o& w3 ~/ k & Y, }& @/ I- j" }0 ?$ G, c8 F
在 STM32CubeMX 中配置好时钟树后,时钟频率会输入到 Cortex System timer内核时钟 。所以, SysTick 的脉冲频率来自于此
' p3 p' g: h! E, g5 k  U  A2 a0 F( z0 `7 e( c' w: ^, B
二、SysTick系统定时器原理: O: h0 n. w  I3 q6 G8 ]3 ~
在HAL_Init()(HAL_Init–>HAL_InitTick–>HAL_SYSTICK_Config–>SysTick_Config) 使用SysTick作为时基源,并配置1ms定时(重置后的默认时钟为 HSI)。但是 HSI 为内部时钟,而我们使用的是外部时钟,这里的1ms定时是不精准的$ R! _( M: q/ M6 Q8 n6 h

4 L( r! r7 ~, R
  1. /* Use SysTick as time base source and configure 1ms tick (default clock after Reset is HSI) */
    5 x3 x. W. j3 F0 V4 A$ r' K4 V. e
  2.   if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)  ~+ Y; r8 I, _1 D6 w5 N
  3.   {; S- L4 g; [$ X  \8 @
  4.     status = HAL_ERROR;
    1 u( r6 p5 Z2 Q/ g% F
  5.   }
复制代码
/ ^2 h% q/ `- O7 L% J* a
精准的1ms定时在系统定时器配置函数SysTick_Config() 在core_cm4.h头文件里面
6 @8 y/ f* A& w; u4 q/ L3 S; o; S( W7 i! H1 p
  1. __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
    + ]/ b0 ~# I2 C
  2. {. ~* K8 c2 k- R* p2 n  h* r% n
  3.   if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)# s6 Y6 {3 Y) H0 L: w
  4.   {: H$ C. v, |  m! Z# N' \% f
  5.     return (1UL);                                                   /* Reload value impossible */
    2 w, |, D" i- E4 F- d
  6.   }5 j6 C1 K# S# a( X  @

  7. : Z% L" p$ J) e7 B3 r
  8.   SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */0 A1 R; r% G9 S9 c% ^3 a: D5 m5 d8 c
  9.   NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */2 z& O7 u/ D+ j9 J; w$ y1 I
  10.   SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */1 C2 B/ k7 z& W3 j$ z. c3 u4 f
  11.   SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |3 W* O' R0 d! V# B  |1 d
  12.                    SysTick_CTRL_TICKINT_Msk   |+ Q- ]  x- [5 Y9 k$ t3 L1 ]
  13.                    SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */! g* @6 `+ g! s5 H
  14.   return (0UL);                                                     /* Function successful */. Y. K# T8 p7 o3 U7 u. ]
  15. }
复制代码

0 [% H( N% `. A! |6 b在这个函数里面进行对系统定时器的寄存器进行配置
5 @& D, j9 f) ^7 t. F
6 s, `8 |' e) C5 ~( n: s; |7 J- ^系统滴答定时器中断服务函数:每隔1ms进入该服务函数
5 f1 O  J6 A3 [7 M. P  q, W
( s/ ?5 L& R  I0 L注:SysTick系统滴答定时器每1ms产生中断
4 w" Z3 g% G' O1 z$ l1 m4 J* E/ u5 q; M
  1. /**6 `9 n. l! d2 n3 _1 t  u
  2.   * @brief This function handles System tick timer.( |0 H9 U& E3 |3 _
  3.   */
    7 R+ @( Y$ n1 _/ y5 J6 r6 s9 W" p
  4. void SysTick_Handler(void)8 J7 F9 M3 a& r6 \
  5. {  g: U, _  K. a  L- Z- D
  6.   /* USER CODE BEGIN SysTick_IRQn 0 */
    + r; X  |% D" U+ s# ?1 a( d

  7. - t& Q- j+ T2 L; \! z
  8.   /* USER CODE END SysTick_IRQn 0 */. F+ I3 _/ n9 q  G6 \/ A' f$ J
  9.   HAL_IncTick();
    # N# {! g9 {/ |+ @! q4 R) Z! G
  10.   /* USER CODE BEGIN SysTick_IRQn 1 */  \- p8 u+ o) s; s- b: e5 }8 z
  11. 1 Y- f0 M+ D$ ]! k6 @6 Z$ P
  12.   /* USER CODE END SysTick_IRQn 1 *// n8 n+ Q* N# G0 f+ R  D1 B
  13. }4 _  o9 k% d+ j7 [/ y/ ?; E7 `
  14. - r& m- @' O9 R
  15. __weak void HAL_IncTick(void)9 X3 i8 n; e7 c) t1 I. D* W
  16. {
      s& k( Q. N- o% J0 G
  17.   uwTick += uwTickFreq; // uwTickFreq = 1
    % a  c9 w* t8 x1 n% Z4 s4 ?" b! {
  18. }
    # N4 @- [3 r  ]
  19. __IO uint32_t uwTick;, x0 ?9 n! v2 R( o5 A
  20. uint32_t uwTickFreq = HAL_TICK_FREQ_DEFAULT;  /* 1K<span style="background-color: rgb(255, 255, 255);">Hz */</span>
复制代码

6 T7 z  s) z3 U- D& \7 m在中断服务函数中 uwTick 会每1ms加1, 一直循环,直到溢出达到232(大约要一直运行40几天)1 g; D4 {* k/ [! C! r1 m" [
' ~6 F) {: b$ G3 z; P
uwTick一般用于计数或者延时函数(HAL_Delay()" N, z; g8 A/ U1 C- _7 U4 W6 _
/ k6 q* X2 }. F
  1. __weak void HAL_Delay(uint32_t Delay)
    ) t7 O+ ~8 z& @, `. Q; X
  2. {
    . L' r4 v4 ]3 g& y/ c' X
  3.   uint32_t tickstart = HAL_GetTick();
    / }6 p! v6 d  K
  4.   uint32_t wait = Delay;
    . e# _7 H) n. R: t1 y  X2 h

  5. ' a8 R6 i' k$ h) Q7 |* p( {+ ]: O* F
  6.   /* Add a freq to guarantee minimum wait */0 g& H: I) K! R1 X  ?- l8 W+ f
  7.   if (wait < HAL_MAX_DELAY)
    0 i5 B: Z8 X' v. z6 `
  8.   {+ @1 i  I" U9 t
  9.     wait += (uint32_t)(uwTickFreq);, \8 l" a5 ?6 h! b
  10.   }2 [0 G: Q, e2 s0 F  l

  11. 9 e  s0 j- f% {, t; [; v
  12.   while ((HAL_GetTick() - tickstart) < wait)4 Z( s3 F% z3 w- a
  13.   {; F5 e1 F8 k+ x9 @( v7 n  q# G3 B. C
  14.   }6 d: z7 \$ @' q$ Q3 T0 g4 h$ f
  15. }6 A: J5 Y3 g2 s$ A$ x

  16. ' L7 g5 e3 t( X% [- o. C
  17. __weak uint32_t HAL_GetTick(void)$ H$ W/ Q$ `9 Q
  18. {
    4 u  M7 R) a& ]4 R" ?/ p# d  A
  19.   return uwTick;8 f3 ~; Q# J& N! m  J
  20. }
复制代码

' Z0 r  n& H. V, _- J/ |HAL_GetTick获取当前uwTick,若传入参数500,tickstart 为 HAL_GetTick() 最初的值(即进入延时时uwTick的值),固定不变。
) y5 n5 ?% N% s5 l2 _HAL_GetTick() 与 tickstart 的差值若小于用户定义的500,则继续循环等待;若超过500,则跳出循环(即跳出HAL_Delay() ),延时结束
& I! S& v9 a. h' B! G$ g: [8 y- T
' ~& ~, y3 r2 D) u- K, w# z总结
# \, @+ Q2 x4 ?$ s  l- Q5 D  }# d提示:这里对文章进行总结:$ o! _/ C) j) x) b/ u' u+ ]9 b
1 R3 j' ~* N0 [1 w+ N) U
Systick的两大作用:
, h( B+ E+ J, U" E1、可以产生精确的延时(HAL_Delay())
7 E4 v) j( p9 k2、可以提供给操作系统一个单独的心跳(时钟)节拍(操作系统时基)4 v: q; }3 B6 Q/ `; K$ [5 H: N5 r
/ `( |; e, x$ T$ A' b

2 |( }# C9 a; l. C/ I
1 v! W  ?. ]' X3 a9 {. T% e
赞 收藏 评论0 发布时间:2022-7-6 14:36

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版