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

【经验分享】STM32 时钟配置与使用

[复制链接]
STMCU小助手 发布时间:2022-1-25 17:00
0、前言
RCC-复位和时钟控制器
可以实现配置系统时钟SYSCLK,配置AHB(HCLK)总线时钟,配置外设APB1(PCLK1)和APB2(PCLK2)时钟
库函数的标准配置为PCLK2=HCLK=SYSCLK=PLLCLK=72M,PCLK1=HCLK/2=36M
系统初始化时会调用函数实现时钟配置。
  1. #ifdef SYSCLK_FREQ_HSE9 S* Q1 N# p* {2 K3 V- V: u! b
  2.   uint32_t SystemCoreClock         = SYSCLK_FREQ_HSE;     /*!< System Clock Frequency (Core Clock) */  u7 x8 B, V) i1 c# V/ W
  3. #elif defined SYSCLK_FREQ_24MHz; a  _9 \& i4 l5 c. c9 E
  4.   uint32_t SystemCoreClock         = SYSCLK_FREQ_24MHz;   /*!< System Clock Frequency (Core Clock) */
    2 k  R7 f) J% s9 [
  5. #elif defined SYSCLK_FREQ_36MHz
    ! \5 N5 P5 P9 c8 x" \3 p0 g
  6.   uint32_t SystemCoreClock         = SYSCLK_FREQ_36MHz;   /*!< System Clock Frequency (Core Clock) */
    & ]( o6 G$ H: G+ V- {/ ^
  7. #elif defined SYSCLK_FREQ_48MHz( b; D( [1 K: N/ Y: ?: w( L
  8.   uint32_t SystemCoreClock         = SYSCLK_FREQ_48MHz;   /*!< System Clock Frequency (Core Clock) */$ d+ b* G/ j2 c3 h+ F# e
  9. #elif defined SYSCLK_FREQ_56MHz
    5 q" s  T+ F9 K  u
  10.   uint32_t SystemCoreClock         = SYSCLK_FREQ_56MHz;   /*!< System Clock Frequency (Core Clock) */
    % x7 {! e" p% k" S% z0 X0 P
  11. #elif defined SYSCLK_FREQ_72MHz
    2 s8 m% F. A; `
  12.   uint32_t SystemCoreClock         = SYSCLK_FREQ_72MHz;   /*!< System Clock Frequency (Core Clock) */
    0 ?4 E( X: g: h# e
复制代码
  1. static void SetSysClock(void)
    ! N4 n& V9 M/ t0 `  ?4 ]" g) l. V
  2. {- h* I: Z% C2 N- @" Z! c4 [1 d
  3. #ifdef SYSCLK_FREQ_HSE
    - N6 _; y8 Y" ?1 ?6 H
  4.   SetSysClockToHSE();0 }# R! s( [; G( `% H: @- \/ @' }
  5. #elif defined SYSCLK_FREQ_24MHz
    : o- p% B; k  y$ x1 ~. v. G1 H
  6.   SetSysClockTo24();0 i! }' q' a$ D) s2 D' a' ^. |
  7. #elif defined SYSCLK_FREQ_36MHz
    1 u3 E: N1 J. i. W3 X+ n
  8.   SetSysClockTo36();- e% G& v  z5 _- T
  9. #elif defined SYSCLK_FREQ_48MHz" |+ l' n' U4 {
  10.   SetSysClockTo48();
    9 l: X, `) Q- A# z$ x( Z. o
  11. #elif defined SYSCLK_FREQ_56MHz& x; O* T4 z3 V5 V: C- m
  12.   SetSysClockTo56();  
    7 r" s% b3 @' G" L
  13. #elif defined SYSCLK_FREQ_72MHz2 O# u. s, q  ~$ @2 U/ z
  14.   SetSysClockTo72();
    5 @' G* k7 i5 [9 S" n
  15. #endif, ]8 Q2 f4 Q) v" c" Y% F
复制代码
0 u! E- m( W" S' f
在system_stm32f10x.c文件中可更改宏定义改变系统时钟频率
  1. #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL), l, X7 L7 Z- L$ D
  2. /* #define SYSCLK_FREQ_HSE    HSE_VALUE */# n: N# B$ K3 i8 O" H9 u: ?0 K
  3. #define SYSCLK_FREQ_24MHz  240000004 n+ S) E/ W! u# [
  4. #else7 }: X# U: V1 g3 Z2 T
  5. /* #define SYSCLK_FREQ_HSE    HSE_VALUE */
    2 J/ J$ g2 b/ ?1 s+ U: G# z
  6. /* #define SYSCLK_FREQ_24MHz  24000000 */ 4 s8 M. ^) F# W$ y/ [
  7. /* #define SYSCLK_FREQ_36MHz  36000000 */
    6 @8 G5 N" i- b' m  Q" h5 x6 ?$ n3 w
  8. /* #define SYSCLK_FREQ_48MHz  48000000 */
    * u0 X+ Z# |( I7 v# }/ t, Z: `
  9. /* #define SYSCLK_FREQ_56MHz  56000000 */
    8 U1 C9 V, Y! [' ?+ R7 V$ _
  10. #define SYSCLK_FREQ_72MHz  72000000' Z  c+ L7 a1 m0 g; S
  11. #endif$ f0 U8 O6 k6 Q4 o5 b7 J
复制代码

' }, m, L1 U* v" }2 o' O# r, I, g" d5 |2 d9 j; N2 f
1、时钟树; Q6 R1 y6 [* R
5 s  h1 |2 T, h, X6 H, r0 \$ \
2604878-20220111094549623-739236124.png ( B0 j' Q% Z3 S. D
主要时钟" @1 Q. ~  W9 g4 A0 m1 m; L
  • HSE:高速外部时钟,可由有源晶振或无源晶振提供,4-16MHz
    PLL以HSE为来源时可设置不分频或2分频
  • PLL:锁相环时钟源,可配置来自HSE或HSI/2
  • PLLCLK:锁相环时钟,可设置倍频[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
  • SYSCLK:系统时钟
  • HCLK:AHB总线时钟,系统时钟经AHB预分频得到,分频因子[1,2,4,8,16,64,128,256,512]
  • PCLK1:APB1总线时钟,由HCLK通过低速APB1预分频得到,分频因子[1,2,4,8,16]
  • PCLK2:APB2总线时钟,由HCLK通过高速APB2预分频得到,分频因子[1,2,4,8,16]

    " m' \5 m$ P5 O" I
其他时钟
  • USB时钟:由PLLCLK通过USB预分频器得到,分频因子[1,1.5]
  • Cortex系统时钟:由HCLK8分频得到,用来驱动内核的系统定时器SysTick
  • ADC时钟:由PCLK2经ADC预分频得到,分频因子[2,4,6,8]
  • RTC时钟:由HSE/128或LSE或LSI得到
  • MCO时钟:输出时钟,可由PLLCLK/2,HSI,HSE,SYSCLK配置" C9 z, O! @) x( R
+ U/ i5 W8 W: n1 Q# I0 L, n
2、时钟配置
" H4 j% t" u. B3 x( o1 h3 `$ J

. \& R. ?: W- Y) X. j$ N0 X相关库函数
7 \& P! h) [6 T$ b配置函数
! J3 G7 k, m( ^- x, T, }
  1. /*
    8 h* x* d: m  h
  2.         将RCC外设初始化为复位状态
    # F6 h+ }, B: T3 y5 b% l
  3. */
    0 P; V" R# U/ r. C( Z* r( s2 P
  4. void RCC_DeInit(void);               
    ( j& H4 R9 ]$ V$ r/ \5 X) C
  5. /*
    * ?( ]$ J6 ~0 G6 ?0 i9 J6 w
  6.         使能HSE,可选参数RCC_HSE_OFF,RCC_HSE_ON,RCC_HSE_Bypass
    5 a, B9 U, b$ V6 H
  7. */1 v* f" q4 `! W$ b
  8. void RCC_HSEConfig(uint32_t RCC_HSE);        
    * j  e$ n0 {$ b" i/ n# {
  9. /*, A! O2 Z5 s/ @  c0 B$ K
  10.         等待时钟源启动稳定,返回SUCCESS,ERROR8 ^8 N  R% i& i% f
  11. */3 Z! q+ W& w# x' S" b* G9 _5 q
  12. ErrorStatus RCC_WaitForHSEStartUp(void);
    & I5 a  e1 l4 m1 |7 W) {, I
  13. /** G1 b7 q; N% Y! A. w1 r( V8 M
  14.         配置PLL时钟源和PLL倍频因子
    - p9 f7 s. @; n. ?' k: l2 L% Q
  15.         RCC_RLLSource:RCC_PLLSource_HSE_Div1,RCC_PLLSource_HSE_Div2,RCC_PLLSource_HSI_Div2
      w- I! u# j+ G
  16.         RCC_PLLMul:RCC_PLLMul_2 [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
    . o) Z1 }& o2 y4 w8 T1 [
  17. */
    ) w" m+ K6 u; l1 v# m6 C) r
  18. void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul);
    - D7 \4 g* n& \. n1 H8 ^3 ~! O# J
  19. /*" K; D2 r6 ?9 S8 u" ]3 w
  20.         配置系统时钟,可选参数RCC_SYSCLKSource_HSI,RCC_SYSCLKSource_HSE,RCC_SYSCLKSource_PLLCLK" z3 f; o& n% Y; O
  21. */
    4 Q: p8 p; m" W( Z( N! g3 \
  22. void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);1 R- c' ]" z: f* K& K
  23. /*) k* T( D# `8 a4 h- A+ w7 r! y: F
  24.         配置HCLK,可选参数RCC_SYSCLK_Div1 [1,2,4,8,16,64,128,256,512]
    ( h$ i- F' q# s2 ^1 O, t& l& _
  25. */: h  ]1 W- m8 a! c6 B% {
  26. void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
    0 @" U# m$ ]$ V1 V. e4 j. h3 b
  27. /*
    6 Q5 Z1 T4 @; v3 [  u
  28.         配置PCLK1,可选参数RCC_HCLK_Div1 [1,2,4,8,16]$ H% @* I& {8 N! ~- \. W( T
  29. */' a+ F2 E$ ]: [) ^, t
  30. void RCC_PCLK1Config(uint32_t RCC_HCLK);: K4 T  d( t" R; j) P* C
  31. /*
    ' ~  j3 o. {3 y6 _5 C6 i
  32.         配置PCLK2,可选参数RCC_HCLK_Div1 [1,2,4,8,16]
    ' L& k) @1 R4 K5 Z/ }. ?- |  h- x
  33. */
    ! ]+ @+ U* W5 q. o
  34. void RCC_PCLK2Config(uint32_t RCC_HCLK);
    ; d& ~6 d$ g. E1 a* l3 x' `4 \0 v7 q' s
复制代码

7 r6 d4 k& g% O4 O6 |, Y1 y& f* t# h2 \, \# ]; s
使用HSE配置系统时钟
  • 1、开启HSE ,并等待 HSE 稳定
  • 2、设置 AHB、APB2、APB1的预分频因子
  • 3、设置PLL的时钟来源,和PLL的倍频因子,设置各种频率主要就是在这里设置
  • 4、开启PLL,并等待PLL稳定
  • 5、把PLLCK切换为系统时钟SYSCLK
  • 6、读取时钟切换状态位,确保PLLCLK被选为系统时钟* k  e# Z- n1 D, H' [/ W1 e
! b) ^+ q% q" L
使用HSI配置系统时钟
  • 1、开启HSI ,并等待 HSI 稳定
  • 2、设置 AHB、APB2、APB1的预分频因子
  • 3、设置PLL的时钟来源,和PLL的倍频因子,设置各种频率主要就是在这里设置
  • 4、开启PLL,并等待PLL稳定
  • 5、把PLLCK切换为系统时钟SYSCLK
  • 6、读取时钟切换状态位,确保PLLCLK被选为系统时钟
    8 R# ]$ k8 C( ~5 y$ {% I! i
  1. /* 设置 系统时钟:SYSCLK, AHB总线时钟:HCLK, APB2总线时钟:PCLK2, APB1总线时钟:PCLK1
    * d; H9 y0 C* Z, `! L
  2. * PCLK2 = HCLK = SYSCLK
    ! K3 w2 |2 ^/ a+ {" ?! E
  3. * PCLK1 = HCLK/2,最高只能是36M4 C0 _9 H5 T! B* {9 ^4 Q0 p2 _
  4. * 参数说明:pllmul是PLL的倍频因子,在调用的时候可以是:RCC_PLLMul_x , x:[2,3,...16]
    5 P' E- }; E7 O9 I& x
  5. * 举例:HSI_SetSysClock(RCC_PLLMul_9);  则设置系统时钟为:4MHZ * 9 = 72MHZ% _% `5 q; Y6 @$ D1 ], s
  6. *       HSI_SetSysClock(RCC_PLLMul_16); 则设置系统时钟为:4MHZ * 16 = 64MHZ
    8 d  W+ x; k7 R) k7 |. [- I
  7. *1 X! \9 G" G$ L
  8. * HSI作为时钟来源,经过PLL倍频作为系统时钟,这是在HSE故障的时候才使用的方法
    : M, o2 _" I8 q% h$ a  C
  9. * HSI会因为温度等原因会有漂移,不稳定,一般不会用HSI作为时钟来源,除非是迫不得已的情况
      I+ N. l/ A' Z# A, S
  10. * 如果HSI要作为PLL时钟的来源的话,必须二分频之后才可以,即HSI/2,而PLL倍频因子最大只能是16
    ; s9 Q' U$ `# \5 h# L: s) d, }  h4 C* S
  11. * 所以当使用HSI的时候,SYSCLK最大只能是4M*16=64M6 Q7 K4 K# M, g: b* ?
  12. */
    2 q: B# H9 N/ e4 }7 b% M
  13. void HSI_SetSysClock(uint32_t pllmul)
    # A/ o' G. @/ _8 N: O3 `- P
  14. {
    % N. J) X8 @$ J1 x
  15.     __IO uint32_t HSIStartUpStatus = 0;, a8 i  V- x1 C# M
  16.     // 把RCC外设初始化成复位状态,这句是必须的
    : o0 ]5 W2 Q7 U0 m; D8 J
  17.     RCC_DeInit();. u0 l- N' M- M- V; G2 C

  18. 7 P* S7 d& O1 Q$ i
  19.     //使能HSI9 ~  ~3 R( P& T- {6 V5 I. g
  20.     RCC_HSICmd(ENABLE);
    ; M0 T- O) |* L  l( N2 @
  21.     // 等待 HSI 就绪
    0 G# z4 R: Z5 \+ J
  22.     HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY;
    . I7 J9 h$ h! \; S# g5 ~2 M3 X
  23.     // 只有 HSI就绪之后则继续往下执行
    8 J# C; P) g3 Z* [
  24.     if (HSIStartUpStatus == RCC_CR_HSIRDY)
    7 [, T0 w+ i* H9 n* m9 h' a8 u
  25.     {
    * i% {* S' S- a% Y$ I
  26. //----------------------------------------------------------------------//
    : H; D/ A/ f. j9 X
  27.         // 使能FLASH 预存取缓冲区9 ?/ b4 d1 a; Y  m6 i# o
  28.         FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    ) U4 f0 P% z5 Q9 r: x! T8 w3 q
  29.         // SYSCLK周期与闪存访问时间的比例设置,这里统一设置成2
    - Y8 H: a; @- U& y0 B# d
  30.         // 设置成2的时候,SYSCLK低于48M也可以工作,如果设置成0或者1的时候,
    $ V+ J! V, G6 A* v
  31.         // 如果配置的SYSCLK超出了范围的话,则会进入硬件错误,程序就死了
    : R: R2 {! F# C
  32.         // 0:0 < SYSCLK <= 24M
    ! J% S! H( g/ Q; s0 f
  33.         // 1:24< SYSCLK <= 48M
    - \3 M; g% i* Y* S2 u
  34.         // 2:48< SYSCLK <= 72M& K: x8 m4 ]( Z& N. X* N$ {0 H
  35.         FLASH_SetLatency(FLASH_Latency_2);5 l" l3 G3 ?6 R$ h4 o) {9 h
  36. //----------------------------------------------------------------------//6 p1 e: B* R$ s' D' H
  37.         // AHB预分频因子设置为1分频,HCLK = SYSCLK
    ! u3 ?7 @! G! Q5 T/ _
  38.         RCC_HCLKConfig(RCC_SYSCLK_Div1);+ l. k: e" _; N7 q: M
  39.         // APB2预分频因子设置为1分频,PCLK2 = HCLK
    / R* K+ R7 ?7 G
  40.         RCC_PCLK2Config(RCC_HCLK_Div1);
    4 {/ V0 f% T+ w1 w/ k
  41.         // APB1预分频因子设置为1分频,PCLK1 = HCLK/2
    % ]* h5 D. i+ w5 O/ B
  42.         RCC_PCLK1Config(RCC_HCLK_Div2);+ t+ Y+ c. }$ F
  43. //-----------------设置各种频率主要就是在这里设置-------------------//$ u1 l1 B5 N5 [* q0 j6 J6 H+ o' L
  44.         // 设置PLL时钟来源为HSE,设置PLL倍频因子
    9 S9 A. P3 E, G7 C0 c
  45.         // PLLCLK = 4MHz * pllmul/ s( l! u5 t, C% F  a8 [9 r' o. m
  46.         RCC_PLLConfig(RCC_PLLSource_HSI_Div2, pllmul);3 M) p( ?' c  y, X
  47. //------------------------------------------------------------------//2 o3 D$ B0 [' f# z  K, L, ^- b
  48.         // 开启PLL
    % ~. u  {3 t+ E6 `. ?; P' l6 {# i+ x
  49.         RCC_PLLCmd(ENABLE);
    6 J! m. I% k3 _! J
  50.         // 等待 PLL稳定
    * X/ x. z% x: `. _* p
  51.         while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)9 y# @* s* ~3 e* w9 E4 l
  52.         {. k# E, b% m" U* A. F- o( L1 _6 C
  53.         }
    * k! Q$ Y- X* {6 s
  54.         // 当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLK
    : E" f6 g( X( n1 Q
  55.         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    3 ^7 }. k6 e4 p9 M: o0 Q' p
  56.         // 读取时钟切换状态位,确保PLLCLK被选为系统时钟+ L7 U  g1 _! X! t* D
  57.         while (RCC_GetSYSCLKSource() != 0x08)' n1 k/ j2 b# o5 V
  58.         {
    # `! d; ^- |1 t# E) D2 v
  59.         }
    8 P2 d3 E& J  A/ s% r+ ?
  60.     }% u8 S8 [  G3 o: F9 ~6 J
  61.     else: j' P/ W* \% f# Y7 j
  62.     {/ e" j" R. a3 g: ^2 p
  63.         // 如果HSI开启失败,那么程序就会来到这里,用户可在这里添加出错的代码处理
    * Q/ K) t3 I* A! b) E* ]
  64.         // 当HSE开启失败或者故障的时候,单片机会自动把HSI设置为系统时钟,
    & H+ @0 f& n" Q: _! i
  65.         // HSI是内部的高速时钟,8MHZ
    " b: |  r) y7 o; H; o
  66.         while (1)/ R4 R4 l8 y3 r2 r2 S
  67.         {/ q2 F" d) `* R6 d0 g
  68.         }" U& N; d; `/ C$ [* E8 T
  69.     }
    - T! |; P) o/ H- }8 U' v" \
  70. }
复制代码

8 \& ^2 F% t3 [: o% B$ _1 U/ Z& |
% C7 A8 S; L$ `MCO输出
MCO GPIO初始化
  1. /*( u) i/ I! ?3 @; }0 C
  2. * 初始化MCO引脚PA8
    & h4 v1 X2 Q; ^0 Z
  3. * 在F1系列中MCO引脚只有一个,即PA8,在F4系列中,MCO引脚会有两个  d$ _6 k6 X1 K
  4. */! X* q& J4 ?8 _2 G3 o6 H! |9 L- P
  5. void MCO_GPIO_Config(void)) a7 J( r$ s/ `0 a
  6. {* U5 r, G# w/ V, S
  7.     GPIO_InitTypeDef GPIO_InitStructure;5 e5 G- c- l( b- l  z
  8.     // 开启GPIOA的时钟- m# l) Z8 a$ i7 r$ n6 y
  9.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);6 U3 K( r$ m' O6 H3 t7 n
  10.     // 选择GPIO8引脚
    4 `/ _0 l* D2 B1 P
  11.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    * R0 x; M) {4 t' C( z6 S" c3 X. P
  12.     //设置为复用功能推挽输出' c0 ?& b0 s6 h0 a, f
  13.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;0 W3 G4 _8 }" v, y: L
  14.     //设置IO的翻转速率为50M
    1 x* @+ `. p" T) T$ r: f
  15.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  A/ j3 B% G  W! S
  16.     // 初始化GPIOA8
    " k9 T$ O! L( x0 }/ I9 }$ e# ]
  17.     GPIO_Init(GPIOA, &GPIO_InitStructure);  k, c  ^  ~3 l4 b( [: q. D2 E* F
  18. }
      B; X5 ~5 y4 r: f
复制代码

  z: G5 o4 _" v8 a: s+ }
输出
  1. // MCO 引脚初始化
    " J- \3 Z/ A3 b# V6 {) R
  2. MCO_GPIO_Config();
      R0 l. {* K. Y6 s
  3. // 设置MCO引脚输出时钟,用示波器即可在PA8测量到输出的时钟信号,! _! |4 w" d+ [  ^
  4. // 我们可以把PLLCLK/2作为MCO引脚的时钟来检测系统时钟是否配置准确7 G" X2 }$ b8 p. c! {( J$ y+ [- P
  5. // MCO引脚输出可以是HSE,HSI,PLLCLK/2,SYSCLK5 _9 y* M# B$ X( Q
  6. //RCC_MCOConfig(RCC_MCO_HSE);4 K. k) ?+ ^! K$ Z6 [$ e% P
  7. //RCC_MCOConfig(RCC_MCO_HSI);) `: b: I& z/ V2 Z) H
  8. //RCC_MCOConfig(RCC_MCO_PLLCLK_Div2);5 c2 }0 Q, E4 x- t
  9. RCC_MCOConfig(RCC_MCO_SYSCLK);
复制代码
( O3 x+ u8 }8 f
0 n% {; w' E9 p; {  w- t0 A
Systick系统定时器简介
SysTick——系统定时器是属于 CM3 内核中的一个外设,内嵌在 NVIC 中。
系统定时器是一个 24bit 的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般我们设置系统时钟 SYSCLK 等于 72M。当重装载数值寄存器的值递减到 0 的时候,系统定时器就产生一次中断,以此循环往复。
因为 SysTick 是属于 CM3 内核的外设,所以所有基于 CM3 内核的单片机都具有这个系统定时器,使得软件在 CM3 单片机中可以很容易的移植。系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。
相关库函数
  • SysTick配置函数
    1. static __INLINE uint32_t SysTick_Config(uint32_t ticks)0 Y  B5 Z" @$ E9 H+ {
    2. {
      9 G( Q9 P; K( `4 G
    3.   if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
      ' ~: i$ \2 m  |' @
    4.                                                                8 `5 ]9 ?% L3 V- h- g7 M1 Z$ l
    5.   SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
      * q, B1 K8 j; D9 V' d6 x
    6.   NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */3 j1 g: H1 ^( H7 c) T/ i8 H. c
    7.   SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
      : s( a% b& F8 L( W
    8.   SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 3 r; x% [: S6 D9 T; Y
    9.                    SysTick_CTRL_TICKINT_Msk   | / I  j* _4 I- k$ X; Z4 n* g
    10.                    SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */; Q% m" N# a& P* F7 B" a  p; M4 j
    11.   return (0);                                                  /* Function successful */
        c7 t" E; |* p7 ~# t: D$ n
    12. }. t* f- X& N1 E, h  i9 f! o  [
    复制代码

      t, C& Z. r; G' a. ?
    ticks用来设置重载寄存器的值,最大不超过 B3@0${X[3K]3($GOL5KF~TF.png ,当寄存器值递减到0时产生中断,随后重载、递减,循环往复。
    每一个tick对应1/SYSCLK 秒
    每次中断间隔时间为 WAU946P@$BUWH_~)IV}WJMA.png
  • ,当寄存器值递减到0时产生中断,随后重载、递减,循环往复。
  • 修改系统定时器中断优先级(非必要)
    1. NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
      0 r% b4 |5 c5 n1 v/ {
    复制代码
    8 @: Q* X6 f. e5 K
  • 对应中断函数
    1. void SysTick_Handler(void)* y, |9 h7 r% R; |. ?9 e
    2. {8 L  }, e: ~. M" I  u, Z9 e% T  N
    3.    
      2 O( g# J7 _7 \
    4. }& Y1 z. o' j8 r: Z
    复制代码
    / v  v! }# D( i# k
    * O# d2 M  e. j+ S8 `% x6 `

4 O3 Y; {  |0 e4 R# `% d
* }( g3 F' D& @2 n2 z" |
7 g. ?6 M- [/ Y; s4 ?) _; E3 R9 {; Z0 R
收藏 评论0 发布时间:2022-1-25 17:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版