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

【经验分享】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_HSE
    - h- _8 N4 r: t& ?
  2.   uint32_t SystemCoreClock         = SYSCLK_FREQ_HSE;     /*!< System Clock Frequency (Core Clock) */% p( O% j! T* K' D! A7 q
  3. #elif defined SYSCLK_FREQ_24MHz
    ( Y7 o( k& k" d' b
  4.   uint32_t SystemCoreClock         = SYSCLK_FREQ_24MHz;   /*!< System Clock Frequency (Core Clock) */& t: K* f) P- f: f
  5. #elif defined SYSCLK_FREQ_36MHz
    # _9 C: \2 [1 }7 k5 f( k8 G- H
  6.   uint32_t SystemCoreClock         = SYSCLK_FREQ_36MHz;   /*!< System Clock Frequency (Core Clock) */
    / `( i6 l0 C0 I- ]& Y3 Q! {7 f- i
  7. #elif defined SYSCLK_FREQ_48MHz
    / f# a" n8 m+ m2 y) s" e" ^
  8.   uint32_t SystemCoreClock         = SYSCLK_FREQ_48MHz;   /*!< System Clock Frequency (Core Clock) */  w- H6 q7 g6 t% d- R* Y
  9. #elif defined SYSCLK_FREQ_56MHz6 Y3 [7 I3 b4 p. D9 t1 m5 R" t% S
  10.   uint32_t SystemCoreClock         = SYSCLK_FREQ_56MHz;   /*!< System Clock Frequency (Core Clock) */) Z) i2 s7 c$ ^* f  n. P
  11. #elif defined SYSCLK_FREQ_72MHz( b7 Y" J: I/ g& m# s, A& C7 Q
  12.   uint32_t SystemCoreClock         = SYSCLK_FREQ_72MHz;   /*!< System Clock Frequency (Core Clock) */
    . j/ c% D0 Q5 x$ D( m/ t1 v
复制代码
  1. static void SetSysClock(void); f+ D7 a+ \7 r9 N
  2. {
    / U' q4 }# x3 {, ~) U  m2 Z
  3. #ifdef SYSCLK_FREQ_HSE
    1 h# U9 s- c7 F/ Y/ l
  4.   SetSysClockToHSE();
    / ~& y# |6 `8 x) i1 G0 ~9 y( j% e
  5. #elif defined SYSCLK_FREQ_24MHz
    , s6 b$ y: p3 Y) C
  6.   SetSysClockTo24();, [7 \5 R! ^6 k" v3 ?' t3 t0 N
  7. #elif defined SYSCLK_FREQ_36MHz
    7 S! n# b* ?- I. j4 O6 p- _
  8.   SetSysClockTo36();6 F* {  ?4 m3 M* @: Y
  9. #elif defined SYSCLK_FREQ_48MHz- s. U) _, i+ a8 M3 X) j. C
  10.   SetSysClockTo48();4 ?9 w) W( n* N9 `# _3 N0 H
  11. #elif defined SYSCLK_FREQ_56MHz! v/ R1 C5 J4 O' k' |5 B  t3 W
  12.   SetSysClockTo56();  4 G# _: f1 e) ?, ^
  13. #elif defined SYSCLK_FREQ_72MHz
    . M+ p( T# O( P  J
  14.   SetSysClockTo72();( h* S  \8 b$ ?& `
  15. #endif0 Y3 q9 Q% u9 Z9 A: f
复制代码

% {8 u" N$ t: M( L- W4 i9 V
在system_stm32f10x.c文件中可更改宏定义改变系统时钟频率
  1. #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)! l6 E& q2 h& C+ z$ h  V' D2 f( e
  2. /* #define SYSCLK_FREQ_HSE    HSE_VALUE */3 k. B" `: h, ]
  3. #define SYSCLK_FREQ_24MHz  240000001 I0 E" U: C* ^# @! k
  4. #else
    * }" ^# d/ C- f- m: H4 @5 Q& q
  5. /* #define SYSCLK_FREQ_HSE    HSE_VALUE */0 R2 p- g( H2 F4 y- d. m- n" V
  6. /* #define SYSCLK_FREQ_24MHz  24000000 */
    ( \+ A8 C6 A/ h& [* ~  B
  7. /* #define SYSCLK_FREQ_36MHz  36000000 */0 Y9 t6 t' j/ Y; v' ~& G8 m
  8. /* #define SYSCLK_FREQ_48MHz  48000000 */
    0 T! R# q8 s! y7 Q6 R4 u
  9. /* #define SYSCLK_FREQ_56MHz  56000000 */! O/ X, j  B8 r, a$ r$ ^
  10. #define SYSCLK_FREQ_72MHz  72000000
    ) O. S2 q" o' H$ T6 I3 }/ v
  11. #endif
    - Y% j! s; f/ l$ R, W7 k) K
复制代码

* N3 \) q; S( f$ g/ H
9 [9 I8 S% j! a4 n! u; v1、时钟树
2 Z' D, K' [: x  t, _( o, F! ]2 d+ f5 V. f% m
2604878-20220111094549623-739236124.png
* Y  G* L  ~* V+ U
主要时钟! F8 a+ p  s" I3 E' Z' C7 k( F
  • 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]
    8 w: a7 K* O8 [$ ?: @
其他时钟
  • 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配置# B1 X% u9 H4 }

7 f  ~: k6 h0 f+ h* [( E9 ^6 T: Q7 M2、时钟配置9 s+ ?8 F( {( H) ^) V0 p, f( C3 `
2 N% a) c0 _/ B; G
相关库函数8 I4 K4 {) U4 L; I8 X! _' |
配置函数- S6 O0 B1 F6 b- c/ S
  1. /*
    1 b" u( Z* F/ @, r
  2.         将RCC外设初始化为复位状态5 y5 o: \5 @/ \% x4 S, A# u
  3. */# s/ J' j2 h4 }
  4. void RCC_DeInit(void);               
    4 S4 g  @  N; O2 y2 w& F
  5. /*: _2 O; L$ f: _1 W* P
  6.         使能HSE,可选参数RCC_HSE_OFF,RCC_HSE_ON,RCC_HSE_Bypass + J8 w; ~7 i( r& G2 T6 T" W7 o- F
  7. */3 |+ u5 ?  s, O- R, j& y. {3 G; ]  R1 ~
  8. void RCC_HSEConfig(uint32_t RCC_HSE);        ' I; \7 z/ F: Y' A+ a" y
  9. /*
    / n4 Z5 ~- M5 C+ N
  10.         等待时钟源启动稳定,返回SUCCESS,ERROR
    + w) D" p0 f! y: X
  11. */  a5 j2 }1 t3 h1 L  g
  12. ErrorStatus RCC_WaitForHSEStartUp(void);
    % S8 H3 ^# Y4 u' S$ b
  13. /*
    ! e! P3 p/ s1 z" r* @* \9 V9 |
  14.         配置PLL时钟源和PLL倍频因子* m" i. C8 |" h' E* ?
  15.         RCC_RLLSource:RCC_PLLSource_HSE_Div1,RCC_PLLSource_HSE_Div2,RCC_PLLSource_HSI_Div2: b. `* f$ q1 [: {; s
  16.         RCC_PLLMul:RCC_PLLMul_2 [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]! O. o4 E0 N  I/ t1 M* z7 g  A
  17. */# w/ G+ F4 Y; n6 j0 o  T6 O) d
  18. void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul);
    . ^- A$ Z' \' Q' y! {* z4 Z: H
  19. /*# s- q. X  y; q2 s
  20.         配置系统时钟,可选参数RCC_SYSCLKSource_HSI,RCC_SYSCLKSource_HSE,RCC_SYSCLKSource_PLLCLK; m' q' u, t. Z+ d; Z3 e" C  O
  21. */
    + V, B/ @4 r  O0 T0 m5 `+ s6 ~
  22. void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
    . W; n, }; \" X9 G) a
  23. /*+ c6 X4 B5 o, I1 d# k, v4 |
  24.         配置HCLK,可选参数RCC_SYSCLK_Div1 [1,2,4,8,16,64,128,256,512]
    + a9 H# w) V- v. H! Q$ ^& F  N+ n
  25. */" \0 k: M1 }4 m
  26. void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
    ! t" o& G) M0 ~2 H2 b; V" @
  27. /*
    4 [4 b( C, @4 v$ i) E8 h
  28.         配置PCLK1,可选参数RCC_HCLK_Div1 [1,2,4,8,16]. x" F" H5 Q) ?  [/ y9 ^; t" L6 _4 \
  29. */
    7 N4 A$ Q* Q% U7 [7 K# ]
  30. void RCC_PCLK1Config(uint32_t RCC_HCLK);
    5 t8 J$ [% H% V  _
  31. /*: l3 x) R" K+ M# S
  32.         配置PCLK2,可选参数RCC_HCLK_Div1 [1,2,4,8,16]" V% A8 x8 @% G3 ^; F
  33. */) w; A0 i4 i8 K6 v/ `* H* o9 Q, k
  34. void RCC_PCLK2Config(uint32_t RCC_HCLK);  D9 X& S9 Z8 h5 l, S
复制代码

) |% ?; z( }. ~3 C( H3 I
9 Z$ Z( Y, E" T1 {# _使用HSE配置系统时钟
  • 1、开启HSE ,并等待 HSE 稳定
  • 2、设置 AHB、APB2、APB1的预分频因子
  • 3、设置PLL的时钟来源,和PLL的倍频因子,设置各种频率主要就是在这里设置
  • 4、开启PLL,并等待PLL稳定
  • 5、把PLLCK切换为系统时钟SYSCLK
  • 6、读取时钟切换状态位,确保PLLCLK被选为系统时钟
    4 Q/ z" j' p7 \8 r! u1 s2 ?4 _

) w9 Y2 g8 ?1 ?+ g' h( Q使用HSI配置系统时钟
  • 1、开启HSI ,并等待 HSI 稳定
  • 2、设置 AHB、APB2、APB1的预分频因子
  • 3、设置PLL的时钟来源,和PLL的倍频因子,设置各种频率主要就是在这里设置
  • 4、开启PLL,并等待PLL稳定
  • 5、把PLLCK切换为系统时钟SYSCLK
  • 6、读取时钟切换状态位,确保PLLCLK被选为系统时钟
    3 B5 _; @5 m/ u: `
  1. /* 设置 系统时钟:SYSCLK, AHB总线时钟:HCLK, APB2总线时钟:PCLK2, APB1总线时钟:PCLK1
    ( `0 E6 T: T( N; s& P% Y# O3 D; p
  2. * PCLK2 = HCLK = SYSCLK
    . h2 p; C  I# E! n. q- M( {
  3. * PCLK1 = HCLK/2,最高只能是36M* F4 b/ T, n  ]3 g6 @
  4. * 参数说明:pllmul是PLL的倍频因子,在调用的时候可以是:RCC_PLLMul_x , x:[2,3,...16]
    , t3 U3 ^! }$ l' ~) G2 L
  5. * 举例:HSI_SetSysClock(RCC_PLLMul_9);  则设置系统时钟为:4MHZ * 9 = 72MHZ6 B% T1 @( D+ f6 V. R" c( [
  6. *       HSI_SetSysClock(RCC_PLLMul_16); 则设置系统时钟为:4MHZ * 16 = 64MHZ, z3 p: c2 V  B  B# x2 j6 C
  7. *% t1 W. ]$ N6 H# L, ]
  8. * HSI作为时钟来源,经过PLL倍频作为系统时钟,这是在HSE故障的时候才使用的方法
    8 `" A# c& A" v3 x1 i: |% G6 ^8 v, D
  9. * HSI会因为温度等原因会有漂移,不稳定,一般不会用HSI作为时钟来源,除非是迫不得已的情况
    / h" q" [( o+ u+ E9 }/ t
  10. * 如果HSI要作为PLL时钟的来源的话,必须二分频之后才可以,即HSI/2,而PLL倍频因子最大只能是16. D8 c& l  A4 g' H1 }# ]
  11. * 所以当使用HSI的时候,SYSCLK最大只能是4M*16=64M7 U. o" S  e  L: b
  12. */
    6 ]6 V. ~9 e: O8 \% J+ ~" x6 X
  13. void HSI_SetSysClock(uint32_t pllmul)
    : s# w. T! x* v5 ?" g/ w
  14. {: k: Q: J* x! I4 H6 N5 S
  15.     __IO uint32_t HSIStartUpStatus = 0;8 ]- M( A! G+ ^# H$ ~
  16.     // 把RCC外设初始化成复位状态,这句是必须的
    ( W' G! G' p4 a! K. l2 K' S
  17.     RCC_DeInit();
    4 j9 I  m3 [2 z5 J/ T8 l

  18. 6 g5 b, x* K' v9 [: F8 P1 g: S4 |
  19.     //使能HSI/ t# E3 G: _- r6 s5 A7 [
  20.     RCC_HSICmd(ENABLE);
      o4 M2 G/ i, I+ }7 B5 ]. a
  21.     // 等待 HSI 就绪9 }( E3 V6 C" \5 U1 Y4 a7 t
  22.     HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY;, t7 P' k5 ~, D1 C. q9 X2 y
  23.     // 只有 HSI就绪之后则继续往下执行
    5 \3 ~' q# @  O
  24.     if (HSIStartUpStatus == RCC_CR_HSIRDY)
    ( Z# e+ a, ~  q4 ^/ M; C4 D1 x+ E/ \
  25.     {
    - `4 j* e8 a% l' V+ C! k
  26. //----------------------------------------------------------------------//+ B' f- f' \4 ]9 l, s# k/ }, @
  27.         // 使能FLASH 预存取缓冲区! |- r" R6 m6 R; |: @" V9 p3 [
  28.         FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);3 ^$ z, K# y- s. t: L( l
  29.         // SYSCLK周期与闪存访问时间的比例设置,这里统一设置成2
    $ y: X+ h% ]2 w# T9 c" u9 D& t" R
  30.         // 设置成2的时候,SYSCLK低于48M也可以工作,如果设置成0或者1的时候,; B& ^5 J1 Y. ?9 d2 G
  31.         // 如果配置的SYSCLK超出了范围的话,则会进入硬件错误,程序就死了1 R# U8 P5 h/ I- d3 Y
  32.         // 0:0 < SYSCLK <= 24M
    $ m$ F1 q" q7 @. P$ v% ?
  33.         // 1:24< SYSCLK <= 48M
    ( d5 S; _* j0 F# b- u' `: [
  34.         // 2:48< SYSCLK <= 72M+ v# d1 o4 V# d" W3 f3 ~5 m9 l
  35.         FLASH_SetLatency(FLASH_Latency_2);
    3 Y4 @& ^" L- O$ p9 C' V% G9 c
  36. //----------------------------------------------------------------------//
    " s, y2 b" Q1 s3 \* Y8 J$ g3 o7 _
  37.         // AHB预分频因子设置为1分频,HCLK = SYSCLK
    5 i. P; R/ M: F8 A% P- ^
  38.         RCC_HCLKConfig(RCC_SYSCLK_Div1);
    & J  m& e) w: M$ V# ]( l
  39.         // APB2预分频因子设置为1分频,PCLK2 = HCLK
    % ?+ y3 C4 n% ?4 h3 h( |: a6 e; L
  40.         RCC_PCLK2Config(RCC_HCLK_Div1);
    3 F: D6 q- ~; n' B; R
  41.         // APB1预分频因子设置为1分频,PCLK1 = HCLK/2
    * A6 V. U( w4 q3 b% B6 m& r
  42.         RCC_PCLK1Config(RCC_HCLK_Div2);: C6 t3 b: N& H) A, X
  43. //-----------------设置各种频率主要就是在这里设置-------------------//
    8 j4 Y) P6 R6 V2 Q0 I
  44.         // 设置PLL时钟来源为HSE,设置PLL倍频因子% j# q6 \9 j* @2 m
  45.         // PLLCLK = 4MHz * pllmul
    ) K: m6 \! f7 s) p- ?6 Y
  46.         RCC_PLLConfig(RCC_PLLSource_HSI_Div2, pllmul);/ y7 _% s0 @2 u& f/ C5 @
  47. //------------------------------------------------------------------//$ Q- n# E( k. F  O0 S1 U
  48.         // 开启PLL9 J9 D) z/ ^0 ~# b+ w6 E
  49.         RCC_PLLCmd(ENABLE);
    ) F3 R3 S4 B3 R2 J7 z4 ~& |
  50.         // 等待 PLL稳定
    . [/ b7 x; R4 V$ c7 f- ]; t
  51.         while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)! b# p$ R5 @4 ]+ \) J2 M' _. d
  52.         {1 |8 o* A) [# f* I) u2 Z' E
  53.         }% B( r' ]' W8 d2 g2 A' L- `6 V
  54.         // 当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLK
    % @' [7 l$ X! B" D+ h* K3 S
  55.         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    : R# u/ G0 F+ w8 V3 M2 }$ i: A4 T
  56.         // 读取时钟切换状态位,确保PLLCLK被选为系统时钟
    7 t7 {/ v0 S$ O- k5 W0 f
  57.         while (RCC_GetSYSCLKSource() != 0x08)
    . N$ Q8 u+ j. u1 q" l6 x  y5 g! T) h
  58.         {, H) L& g; O  W2 w/ U
  59.         }
    6 D  |* H+ r; T
  60.     }
    ' a1 L; ~1 T: d7 F
  61.     else
    " C5 M/ y$ m; U  I
  62.     {9 V# }3 p3 e0 d% Y+ V
  63.         // 如果HSI开启失败,那么程序就会来到这里,用户可在这里添加出错的代码处理
    6 \! G  q" A2 n
  64.         // 当HSE开启失败或者故障的时候,单片机会自动把HSI设置为系统时钟,# z9 G' e  u/ N7 i. i
  65.         // HSI是内部的高速时钟,8MHZ* e7 P( C% o) f- e
  66.         while (1)
    # P/ q  P! W9 I+ w
  67.         {
    2 V# r$ Z, |! f6 h6 g
  68.         }
    $ K0 U2 V3 C! T% v, y
  69.     }
    / k) g* ~! F7 U7 Y; }* A
  70. }
复制代码
9 x1 v/ P8 ]7 H

$ m$ e$ s/ G5 e4 F) [7 k( n$ yMCO输出
MCO GPIO初始化
  1. /*# n4 g; T, U* \' O  ^: D
  2. * 初始化MCO引脚PA8  r' U# ?6 Y: {$ b+ Y
  3. * 在F1系列中MCO引脚只有一个,即PA8,在F4系列中,MCO引脚会有两个( X+ w0 b  c# N/ L
  4. */
    - Y$ k3 i% F6 O  w
  5. void MCO_GPIO_Config(void)
    2 r: \& C% f& }0 ~5 M8 H2 r# J. a
  6. {
    1 e* R( Z  R) Z3 D; B* b
  7.     GPIO_InitTypeDef GPIO_InitStructure;
    $ H8 t# n9 U3 f: N* b; L' W
  8.     // 开启GPIOA的时钟( W& G' p5 F9 f
  9.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    * }" y+ E- {6 F4 I
  10.     // 选择GPIO8引脚- @- a6 p8 q# C- Z, W* }% N: z
  11.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    1 ]7 q& |( w* H8 V5 |/ Y/ a# ?
  12.     //设置为复用功能推挽输出
    ) a0 C' L3 r3 l5 {3 q! r6 Y5 P
  13.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;% F/ @" j4 |: U* f; \0 A
  14.     //设置IO的翻转速率为50M
    ; n8 I5 ^( o. {0 V, Y6 i) m+ F
  15.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;6 T! t  x1 [8 ~: |' o
  16.     // 初始化GPIOA84 I# U& Q% n1 C% Z( ^) M! m
  17.     GPIO_Init(GPIOA, &GPIO_InitStructure);" B3 u( F* q( _  |& V
  18. }
    ; d+ n& t. L; D1 a$ B! l4 x+ ]. T- w
复制代码

9 o6 ^* E. J$ V2 E+ ]
输出
  1. // MCO 引脚初始化
    8 e" S$ o% m! y) |9 r, g0 K8 O3 H+ s% k
  2. MCO_GPIO_Config();
    9 M6 Y0 D* u1 Q% L3 v: g
  3. // 设置MCO引脚输出时钟,用示波器即可在PA8测量到输出的时钟信号,2 t, I  N/ {0 R: ^# m. d) W
  4. // 我们可以把PLLCLK/2作为MCO引脚的时钟来检测系统时钟是否配置准确) r. i: N" I$ r; _
  5. // MCO引脚输出可以是HSE,HSI,PLLCLK/2,SYSCLK1 p" U" C6 c9 w1 r) x* A
  6. //RCC_MCOConfig(RCC_MCO_HSE);
    . T/ q: [3 M9 |9 ~  n% H& s
  7. //RCC_MCOConfig(RCC_MCO_HSI);
    9 d0 i6 I/ s$ g" P$ |: [" R
  8. //RCC_MCOConfig(RCC_MCO_PLLCLK_Div2);
    , A% k) G! k- }, Z6 }+ B7 x
  9. RCC_MCOConfig(RCC_MCO_SYSCLK);
复制代码

! E- |- {: J5 r
) |( M- d$ C  X- r1 fSystick系统定时器简介
SysTick——系统定时器是属于 CM3 内核中的一个外设,内嵌在 NVIC 中。
系统定时器是一个 24bit 的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般我们设置系统时钟 SYSCLK 等于 72M。当重装载数值寄存器的值递减到 0 的时候,系统定时器就产生一次中断,以此循环往复。
因为 SysTick 是属于 CM3 内核的外设,所以所有基于 CM3 内核的单片机都具有这个系统定时器,使得软件在 CM3 单片机中可以很容易的移植。系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。
相关库函数
  • SysTick配置函数
    1. static __INLINE uint32_t SysTick_Config(uint32_t ticks)
      1 F  {# F8 t; L( ~! t- G
    2. {
      : o6 L6 G# S9 p7 S  Y7 ?8 @
    3.   if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */& U9 b6 V7 Z$ m" c, @) j
    4.                                                                
      # |0 ], f) G8 c$ G" K
    5.   SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register *// g# d! z: O4 q& \
    6.   NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
      * L) B8 v5 P( ~/ f( u
    7.   SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */7 [) _% |7 G: ~1 }2 _" x# d
    8.   SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 9 l6 ~: P( k# j
    9.                    SysTick_CTRL_TICKINT_Msk   |   X" U3 G& [9 y0 p( z4 d+ n. M
    10.                    SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
      4 }' _7 k3 h5 V; E7 y( W6 y
    11.   return (0);                                                  /* Function successful */  ]# k# E! b: Y% r2 T
    12. }
      5 z' u& n+ K& }: Y
    复制代码

    2 [$ g% }6 s, h! a. T6 F
    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);6 l5 @1 H' H+ d; @  w; C
    复制代码

    7 b- }! x4 G. U& o5 `. e4 a
  • 对应中断函数
    1. void SysTick_Handler(void)- H" I" |0 e2 d; V' U% n/ ^. e. A
    2. {( b. h+ r! r: q
    3.     5 t6 X, f7 X) P: |; A
    4. }
      ! w" s  x5 U  j
    复制代码

    3 _& X1 h$ G+ n. J; {

    : K  |2 L* M, d
( _4 V, c. D( C* D/ N" ^+ y

8 i2 N$ @  u% G' X* S; {; z; R! b0 H
( f3 z/ E. J7 @) Q& E: o4 @! H& K! {5 f" x
* F3 [' S8 j$ o( B4 i' }0 s
收藏 评论0 发布时间:2022-1-25 17:00

举报

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