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

基于STM32的SYSTICK应用详解

[复制链接]
又是一年春来到 发布时间:2016-6-15 15:51
什么是SYSTICK:
9 j* A7 p; e* l/ B$ ~
这是一个24位的系统节拍定时器system tick timer,SysTick,具有自动重载和溢出中断功能,所有基于Cortex_M3处理器的微控制器都可以由这个定时器获得一定的时间间隔。
作用:
在单任务引用程序中,因为其架构就决定了它执行任务的串行性,这就引出一个问题:当某个任务出现问题时,就会牵连到后续的任务,进而导致整个系统崩溃。要解决这个问题,可以使用实时操作系统(RTOS).
因为RTOS以并行的架构处理任务,单一任务的崩溃并不会牵连到整个系统。这样用户出于可靠性的考虑可能就会基于RTOS来设计自己的应用程序。这样SYSTICK存在的意义就是提供必要的时钟节拍,为RTOS的任务调度提供一个有节奏的“心跳”。
微控制器的定时器资源一般比较丰富,比如STM32存在8个定时器,为啥还要再提供一个SYSTICK?原因就是所有基于ARM Cortex_M3内核的控制器都带有SysTick定时器,这样就方便了程序在不同的器件之间的移植。而使用RTOS的第一项工作往往就是将其移植到开发人员的硬件平台上,由于SYSTICK的存在无疑降低了移植的难度。

# D  G% ^: g! G$ r8 x, I
  SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等。
要注意的是,当处理器在调试期间被喊停(halt)时,则SysTick定时器亦将暂停运作。

. H: m  Q+ o2 X" {% W) L. u
时钟的选择:
用户可以在位于Cortex_M3处理器系统控制单元中的系统节拍定时器控制和状态寄存器(SysTick control and status register ,SCSR)选择systick 时钟源。如将SCSR中的CLKSOURCE位置位,SysTick会在CPU频率下运行;而将CLKSOUCE位清除则SysTick会以CPU主频的1/8频率运行。
3.5版本的库函数与以往的有所区别
不存在stm32f10x_systick.c文件,故原来的一些函数也不存在,比如SysTick_SetReload(u32 reload);SysTick_ITConfig(FunctionalState NewState);等

, p7 a+ v; G  Q1 N
在3.5版本的库函数中与systick相关的函数只有两个
第一个,SysTick_Config(uint32_t ticks),在core_cm3.h头文件中进行定义的。
第二个,void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource),在misc.c文件中定义的。
% z( L6 u; p2 F. g) I4 v
SysTick_Config(uint32_t ticks),在core_cm3.h
主要的作用:
1、初始化systick
2、打开systick
3、打开systick的中断并设置优先级
4、返回一个0代表成功或1代表失败
注意:
Uint32_t ticks  即为重装值,
这个函数默认使用的时钟源是AHB,即不分频。
要想分频,调用void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource),
但是要注意函数调用的次序,先SysTick_Config(uint32_t ticks),
后SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
) T5 v7 K' f% Q2 s0 o3 v  q函数说明:* J  C0 p' |2 l! v
  1. <span style="background-color: White;"><font color="Black">/**
    " O/ K1 r1 ^% G. I; L4 G8 x2 f/ q
  2. * [url=home.php?mod=space&uid=247401]@brief[/url]  Initialize and start the SysTick counter and its interrupt.3 |: N1 a$ v; F5 M* J6 a/ v
  3. *! M9 B# }/ p! u: K
  4. * @param   ticks   number of ticks between two interrupts
    4 v# U2 ^6 E; u$ o9 M- R% b; P
  5. * [url=home.php?mod=space&uid=266161]@return[/url]  1 = failed, 0 = successful" d0 u, b# M7 [7 P# g& P6 ^
  6. *; t: |2 R1 ^" V
  7. * Initialise the system tick timer and its interrupt and start the' P9 f4 V3 X' K- j  Y
  8. * system tick timer / counter in free running mode to generate
    - s. M2 f* {2 I. n* y
  9. * periodical interrupts.
    * e7 Y$ e- ]% H
  10. */1 P" a0 W; C) [* n0 ^
  11. static __INLINE uint32_t SysTick_Config(uint32_t ticks)
    " p2 _+ m$ H) J3 w" e  B
  12. {
    2 x* C. w5 D! d  c3 V8 k  W
  13.   if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            
    . [' A. a: j/ L( x! z6 T
  14.   /* Reload value impossible */重装载值必须小于0XFF FFFF,为什么,这是一个24位的递减计数器。! H! l8 \+ v# ~0 R) M5 i& H$ N
  15. - O  `/ ^; o/ X
  16.   SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
    ; a; P# `' Y  b  @! g7 b) h
  17.      /* set reload register */设置重装载值,SysTick_LOAD_RELOAD_Msk定义见后面
    & k9 I5 g9 h" i$ b# m7 F! c- [( e7 J
  18.   NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);& _) }8 }) M  a, [( r
  19. /* set Priority for Cortex-M0 System Interrupts */
    , D2 ]3 }! r* }( ^# q6 }
  20.   SysTick->VAL   = 0;& {$ f' o3 f! u" f" r( ]
  21.   /* Load the SysTick Counter Value */. S0 S7 x) Q/ C! U* H. G0 g! M9 R
  22.   SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
    - D7 k# m# V7 D2 U
  23.                    SysTick_CTRL_TICKINT_Msk   |/ c: s4 n) a+ y- c0 b
  24.                    SysTick_CTRL_ENABLE_Msk;                  
    + O6 b" C( H0 t2 B7 U
  25. /* Enable SysTick IRQ and SysTick Timer */$ Y" i4 h4 J6 c4 ~5 q
  26.   return (0);, b7 W  f5 ^$ n- S4 l0 l6 v; \/ j" T
  27.   /* Function successful */' {1 R: y% z: g& v; \  \* I
  28. }% O8 g. u! N, _6 w$ m
  29. #endif
    2 i& G' w. R& j' S; \
  30. 与systick相关的寄存器定义
    9 u, H( ?! e( Z
  31. /** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick. T5 e7 ]& S2 B  c- K
  32.   memory mapped structure for SysTick- b" T# ~& f5 U9 ^6 k6 F
  33.   @{- W3 p  C* T0 u. w, L
  34. */* y: }/ [) ~0 @3 O
  35. typedef struct
    2 ?  l& K- h/ c: }
  36. {
    ) V+ L3 N+ }) g0 y$ v, {* X: q2 z
  37.   __IO uint32_t CTRL; /*!< Offset: 0x00  SysTick Control and Status Register */
    ' g- A7 E1 |; _0 U3 r- R) a/ z: i
  38.   __IO uint32_t LOAD; /*!< Offset: 0x04  SysTick Reload Value Register       */
    : ^+ `! _  ]  X3 G' l! B# `$ w
  39.   __IO uint32_t VAL; /*!< Offset: 0x08  SysTick Current Value Register      */
    0 Z3 Q) E6 b8 ?
  40.   __I  uint32_t CALIB; /*!< Offset: 0x0C  SysTick Calibration Register        */
    ) h% U  N: }- r8 q$ h
  41. } SysTick_Type;8 ?+ V& i& j: z3 [" \6 S" o; ^) S
  42. 5 w: q/ B$ F6 n$ \* k- A2 ^
  43. 与systick寄存器相关的寄存器及位的定义
    6 ~! }3 D8 ^1 O8 G! w1 l

  44. + J! V* f3 E  t- _: P, `" t
  45. /* SysTick Control / Status Register Definitions */控制/状态寄存器
    8 ~+ O1 C7 w  H; _
  46. #define  SysTick_CTRL_COUNTFLAG_Pos  16      /*!< SysTick CTRL: COUNTFLAG Position */
    1 O% U% M* Y7 G  G  r+ j; J
  47. #define SysTick_CTRL_COUNTFLAG_Msk         (1ul << SysTick_CTRL_COUNTFLAG_Pos)         
    ; M; u$ r% N+ {" X5 _# m9 I% y
  48. /*!< SysTick CTRL: COUNTFLAG Mask */ 溢出标志位  [) D, Y1 V# E' U/ q. T9 ?* l
  49. - G# j5 H8 Z# L* l% _, D. r
  50. #define SysTick_CTRL_CLKSOURCE_Pos   2       /*!< SysTick CTRL: CLKSOURCE Position */
    " p4 I: B5 i6 G) d! j' j
  51. #define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)  
    ! }" E/ ~. ]8 C
  52. /*!< SysTick CTRL: CLKSOURCE Mask */时钟源选择位,0=外部时钟;1=内核时钟
    # [" v. ]' j" \/ Y8 w* V

  53. . c. p* J$ p4 `, u# K
  54. #define SysTick_CTRL_TICKINT_Pos      1        /*!< SysTick CTRL: TICKINT Position */0 h) P/ v3 Q- o& b( S/ [! ^6 F8 t
  55. #define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)         7 C+ G# u2 g, F
  56. /*!< SysTick CTRL: TICKINT Mask */异常请求位- J; s3 v0 T, g, A+ I' X

  57. 0 `5 b3 [2 x5 W" }
  58. #define SysTick_CTRL_ENABLE_Pos             0       /*!< SysTick CTRL: ENABLE Position */
      g4 g3 e5 P3 [9 J, B( X) k
  59. #define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos)               
    * p1 U8 Y6 p( _9 M+ K
  60. /*!< SysTick CTRL: ENABLE Mask */使能位4 |* H8 e9 x  O% S, l/ j0 ^3 j
  61. 6 i4 F7 ^2 u3 c! _3 R
  62. /* SysTick Reload Register Definitions */
    1 r" H7 V" v4 Z% g" }' I
  63. #define SysTick_LOAD_RELOAD_Pos             0    /*!< SysTick LOAD: RELOAD Position */1 l( \2 C% g8 d" ]( K& h
  64. #define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        
    6 w, m. P1 J7 _# f7 E
  65. /*!< SysTick LOAD: RELOAD Mask */
    ! e. y) K9 j3 Q) c

  66. % d2 I8 v, E5 i6 Q; [
  67. /* SysTick Current Register Definitions */' h* ^* g( F0 j  ]6 K
  68. #define SysTick_VAL_CURRENT_Pos             0       /*!< SysTick VAL: CURRENT Position */
      k$ O: B7 y- x
  69. #define SysTick_VAL_CURRENT_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        
    $ J- ?+ K6 p/ J7 U0 {2 [
  70. /*!< SysTick VAL: CURRENT Mask */( s; `2 o3 Y# i, x' x
  71. 7 i: d) s) B% s3 x' _$ _- v  ]
  72. /* SysTick Calibration Register Definitions */
    6 f; T6 \4 M, a3 t
  73. #define SysTick_CALIB_NOREF_Pos            31      /*!< SysTick CALIB: NOREF Position */
    . _- X9 q$ p" l4 y8 U
  74. #define SysTick_CALIB_NOREF_Msk            (1ul << SysTick_CALIB_NOREF_Pos)              ; {; s/ B- i, L1 H
  75. /*!< SysTick CALIB: NOREF Mask */
    $ q+ Q5 }4 b' d7 Y) Q

  76. ( e+ q$ ^) K+ i
  77. #define SysTick_CALIB_SKEW_Pos             30       /*!< SysTick CALIB: SKEW Position */
    - }5 y& G" |5 C- X1 U) [
  78. #define SysTick_CALIB_SKEW_Msk             (1ul << SysTick_CALIB_SKEW_Pos)               
    6 K: M- l' {( O
  79. /*!< SysTick CALIB: SKEW Mask */, ^2 n, G" E: W8 r

  80. : ^) @4 @$ m- T/ d
  81. #define SysTick_CALIB_TENMS_Pos             0       /*!< SysTick CALIB: TENMS Position */
    2 e( H5 e# x& [6 M
  82. #define SysTick_CALIB_TENMS_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */! G" H5 N' o9 F* Z/ B! l, o
  83. /*@}*/ /* end of group CMSIS_CM3_SysTick */</font></span>
复制代码

) q; z2 m8 k6 X3 X8 d+ J# ?6 n( B! i: y: e  w$ f6 W0 {2 }
与systick相关的寄存器的说明5 F7 b& K) B7 W) s; g' \
31.jpg ; b# J0 C: [* a: g

% X2 Z5 D: g3 S 32.jpg 3 }2 Q5 L5 I% M3 t4 u# t

! X$ Z! P1 ?$ ]6 L" o4 x' n 33.jpg ' |2 h8 r8 T; k8 T. F3 {9 r% _
+ Z' s2 p9 J; p6 {! G6 B
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
作用:
选择systick的时钟源,AHB时钟或AHB的8分频
默认使用的是AHB时钟,即72MHz9 p9 _, x+ l! ?% _

( t7 S( {( _0 q; g1 v4 @函数说明:
: {# F# W- }  ~, ^' @6 s* q$ l/ K
  1. <span style="background-color: White;"><font color="Black">/**
      G3 ?3 |- `) }8 G9 K  v' L' t# r
  2.   * @brief  Configures the SysTick clock source.
    ! n& E2 Y& B3 J- l, _
  3.   * @param  SysTick_CLKSource: specifies the SysTick clock source.; \3 q9 d$ C4 N! u
  4.   *   This parameter can be one of the following values:
    $ J. R) x; w8 q- J/ D
  5.   *     @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.  Z  L3 ~2 M& Y. s) n- `5 D
  6.   *     @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.7 V% I* |; k* r/ T9 t6 D
  7.   * @retval None2 C, B) S# B6 P- {% J5 R) f
  8.   */% a7 A9 N+ s$ h6 O
  9. void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
    * R# P2 k8 S; \+ ?5 c8 k6 ^
  10. {
    8 g# @; p. {1 S4 G. i9 q1 g* \
  11.   /* Check the parameters */
    % G- l* n4 D8 h0 [, Q
  12.   assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
    4 c: U8 U4 @0 X6 B( @* @  |
  13.   if (SysTick_CLKSource == SysTick_CLKSource_HCLK)9 Q# q8 x) |0 @" s
  14.   {
    ' j# T& k9 F6 Q5 U( r' B
  15.     SysTick->CTRL |= SysTick_CLKSource_HCLK;/ o* W" ~* ?' P* P) z
  16.   }
    ) h5 E8 J8 o  U/ @* }0 Y
  17.   else
    " X# V1 f4 W5 a
  18.   {
    1 ]) U% U# c1 o- h$ Z$ ]
  19.     SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
    + `% C/ U! b5 i& {+ P
  20.   }
    : |& W# d( n: k3 r
  21. }3 P  C1 `/ P% d0 W9 Z0 k
  22. , ~6 m9 A8 b; o

  23. & s* Y8 \" s6 ~5 h" a& l
  24. Systick时钟源的定义:  _& q0 }# m& m3 b
  25. /** @defgroup SysTick_clock_source
    4 U% h+ |" b- V9 ]; ~
  26.   * @{
    ; U1 ?  C; T) ^$ P; g4 B
  27.   */
    7 c( O0 p- D4 f  L8 C( _
  28. 3 S: A, \- r7 O1 u" f0 K
  29. #define SysTick_CLKSource_HCLK_Div8    ((uint32_t)0xFFFFFFFB)//将控制状态寄存器的第二位置0,即用外部时钟源
    8 {2 X" G* l7 @- Y( U% K
  30. #define SysTick_CLKSource_HCLK         ((uint32_t)0x00000004)//将控制状态寄存器的第二位置1,即用内核时钟2 r4 j. d4 I+ m9 `+ l: N
  31. #define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \( F4 A- b4 s" @0 h9 M  z' x
  32.                                        ((SOURCE) == SysTick_CLKSource_HCLK_Div8))</font></span>
复制代码
7 p$ j3 f0 R4 S% |- S
Systick定时时间的设定:
- Q% P# ^( `& ~. I& J+ n& _, e; f
重装载值=systick 时钟频率(Hz)X想要的定时时间(S)
如:时钟频率为:AHB的8分频;AHB=72MHz那么systick的时钟频率为72/8MHz=9MHz;要定时1秒,则
重装载值=9000000X1=9000000;
定时10毫秒
重状态值=9000000X0.01=90000
Systick的中断处理函数,
在startup_stm32f10x_hd.s启动文件中有定义。
DCD     SysTick_Handler            ; SysTick Handler
根据需要直接编写中断处理函数即可:
Void SysTick_Handler (void)
{ ;}
注意:
如果在工程中,加入了stm32f10x_it.c,而又在主函数中编写中断函数,则会报错。! Y4 a: R- k) H$ W% N% z" O

0 q2 ~6 U* u" L4 E( n5 I 34.jpg " Z( M* X6 E+ b4 P

( g9 ~( r: ~0 J* Y
因为在stm32f10x_it.c文件中,也有这个中断函数的声明,只是内容是空的。3 k- X0 X$ P0 d$ A( h  o

. n# O% A  R$ y/ N# X5 ?' k
  1. <span style="background-color: White;"><font color="Black">/**
    ) [. ~# F% V  A) e5 [! X: y
  2.   * @brief  This function handles SysTick Handler.+ \7 k. C/ s7 B6 k( g
  3.   * @param  None
    , d) \2 H+ F& c2 h/ a3 U
  4.   * @retval None" O6 ^7 V9 e2 O2 H
  5.   */
    ( G$ q6 b8 @6 m
  6. void SysTick_Handler(void)6 I, w7 \# V6 T, @# Z$ Y' Q
  7. {1 X. G* Y5 W+ }0 L9 M
  8. }</font></span>
复制代码

/ o$ w3 t  S, K( b6 S
中断优先级的修改
在调用SysTick_Config(uint32_t ticks)之后,调用 void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)。这个函数在core_cm3.h头文件中。
具体内容如下:2 d6 t' }, t% J0 a) n( T
  1. <span style="background-color: White;"><font color="Black">/**  [, a0 q5 }1 E( ^+ _
  2. * @brief  Set the priority for an interrupt0 l: j8 H; c. [7 c
  3. *, r; B; [2 |. V9 w9 s! ^/ L9 B9 S
  4. * @param  IRQn      The number of the interrupt for set priority
    - g9 G' ^- V- N  F# v. k5 ?
  5. * @param  priority  The priority to set
    ' O2 {4 ^) a1 c; i$ X% F" M
  6. *7 |9 v, N. u) e, t
  7. * Set the priority for the specified interrupt. The interrupt
    # T6 F: y: t7 W6 `% ^
  8. * number can be positive to specify an external (device specific)7 Y7 [6 V$ ~! t
  9. * interrupt, or negative to specify an internal (core) interrupt.1 {4 d, g. @( V2 H$ d. F( ]; h
  10. */ X9 J' ^' ]" a  I' l
  11. * Note: The priority cannot be set for every core interrupt.- d: X5 w  R2 T4 g* H8 z$ L
  12. */
    + g. ]) G  w9 I  r( B6 K: a" u; w
  13. ) P2 B& ^8 o' j3 V
  14. 1 n2 `# ]- t7 }1 f3 m$ `

  15. # G0 I  O& a: u+ O( W

  16. 7 I+ [6 Y0 m0 B, Y. o6 ^6 J$ n6 t
  17. static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)2 ]7 A/ T) p. w( g
  18. {5 r6 e1 b) B4 u' Q& }
  19.   if(IRQn < 0) {8 C7 y+ @; o, b7 E2 o" X, ]6 c0 V1 o; m/ _
  20.     SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
    9 i) g' V: V. ]( \! k
  21.   else {1 ]: F2 X4 ^+ c1 N9 y( s
  22.     NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */
    , I5 w/ n) ]& w- [4 z
  23. }</font></span>
复制代码
' [! o, `+ B* ?9 q- B; e
下面以一个实例来说明:
利用systick来实现以1秒的时间间隔,闪亮一个LED指示灯,指示灯接在GPIOA.8,低电平点亮。/ y) j7 d/ \& q$ v
  1. <span style="background-color: White;"><font color="Black">#include "stm32f10x.h"
    4 f5 @# F8 r5 ~$ K7 n" _+ v
  2. //函数声明. z: H& Z% F9 l" |7 E8 E
  3. void GPIO_Configuration(void);//设置GPIOA.8端口
    0 |  p' x: D, c- {
  4. u32 t;//定义一个全局变量8 f* Y0 W' w/ M% C% J, Y, C# G
  5. int main(void); j- j: Y2 I  l) |# E% g$ g
  6. {: }1 ]% E; x. e
  7. // SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
    4 [9 l2 t% [0 U* M3 N' l
  8.        SysTick_Config(9000000);
    . P6 W9 D% [0 y. R% B- O
  9.        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
    0 V4 Q& ]1 l( t7 u! X
  10.        GPIO_Configuration();
    * Z' S5 h" {- }, x  B
  11.        while(1);      & ^4 a4 Q: |0 {; ~6 b$ N" U& _3 k
  12. }
    5 d/ Q( s* w3 o$ |4 u! z. U
  13. , r5 k. y* E! V6 f7 e
  14. //GPIOA.8设置函数3 E4 T4 f7 y$ j6 r
  15. void GPIO_Configuration(void)+ Z  F0 r6 Q+ i  I' K, I
  16. {7 G( o2 U6 N! E: r( J: V9 n
  17. GPIO_InitTypeDef  GPIO_InitStruct;//定义一个端口初始化结构体/ f9 t) p9 L: Q4 i/ S. Z4 |  b
  18.        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//打开GPIOA口时钟
    . n9 u1 ^3 E& ^8 }
  19.        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//设置为推挽输出' j7 d6 k5 f: Q7 D
  20.        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//设置输出频率50M
    - d( t1 ?( C( V# O9 @& P
  21.        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;//指定第8脚
    ( p5 Y0 }; I; X9 F) W
  22.        GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化GPIOA.8      
    + T! A* Y3 }- B- E
  23.        GPIO_SetBits( GPIOA,  GPIO_Pin_8);//置高GPIOA.8,关闭LED' ~0 @# n* v9 |5 o6 n; x- M3 R1 p3 j
  24. }
    7 a7 J' ?2 s, i  f" \
  25. //systick中断函数9 W  F0 M$ a; D! y. `
  26. void SysTick_Handler(void)" q' g1 |( b3 z% }! ?* {
  27. {
    . I/ ^' G1 l. i& Q2 E' y
  28. t++;
    & {( _3 G+ ~: S/ N" s
  29.        if(t>=1)
    # C' E* L6 O2 d0 M
  30.        {
      x0 j4 t- Y' t: I* H
  31.               if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1)
    ' ^: y" s7 @: x
  32.               {GPIO_ResetBits( GPIOA, GPIO_Pin_8);}      9 f7 [9 N: L; k0 o# d& K/ P
  33.        }* O! v/ [7 i/ C3 W
  34.        if(t>=2)
    6 G2 d( ~* H# Z
  35.        {! S' p( }: n& J7 w( t2 g& C
  36.               if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==0)
    ( u' e4 X% ^$ {$ O* q3 K9 _
  37.                      {GPIO_SetBits( GPIOA, GPIO_Pin_8);}$ L: }6 D$ s; r1 e/ X& r) ^- t6 a7 u
  38.                      t=0;" o( t( z! w0 y3 Q* a: h
  39.        }$ t$ h8 m9 P, `' W% h& i
  40. }</font></span>
复制代码

! V6 ?; F0 U# |, f$ L1 M; E' v0 p, B$ y/ y, n" {, O

! D0 D9 `- v" {4 }3 r
模拟后的结果
1、8分频后结果% r, k! }/ a* o5 f) a2 t3 i
35.jpg ) B1 t& `: |/ Q1 {
# u% }& U0 ~+ o- A
2、直接调用SysTick_Config(9000000);即不分频的结果,间隔为1/8=0.125s
% \' Y; ]2 g/ u2 E 36.jpg # M1 X' o* h; W# `# ~3 l$ M5 X
! m' [0 K" G6 p' `: N+ `  o
7 f2 k" p* p7 d
5 G6 U4 ]  @' u* L" R, _

& d3 Z; }, m1 x3 y: x

! b. T/ C1 N$ f% g; o

5 `) `* h+ b7 l$ {% K
收藏 3 评论5 发布时间:2016-6-15 15:51

举报

5个回答
又是一年春来到 回答时间:2016-6-15 15:51:47
总结:! p( H3 A. `* J- U  z  c2 `
1、要使用systick定时器,只需调用SysTick_Config(uint32_t ticks)函数即可,% y( w2 S% V3 a2 \3 r% W. l+ k, z
   自动完成了,重装载值的装载,时钟源选择,计数寄存器复位,中断优先级的设置(最低),开中断,开始计数的工作。- I- E' G$ Z& s( H# b
2、要修改时钟源调用SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)。
; f$ h! }* T+ x$ e1 I3、要修改中断优先级调用7 y* c# }& x1 g3 N
     void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
0 k: F, c' P7 k; [3 Q' [应用说明:
% n6 ]* U' q* N$ P+ Y+ ?9 X1、因systick是一个24位的定时器,故重装值最大值为2的24次方=16 777 215,
6 t! H3 W6 z' r3 i" I6 \   要注意不要超出这个值。
0 k/ i. E. t$ z, g2、systick是cortex_m3的标配,不是外设。故不需要在RCC寄存器组打开他的时钟。
8 l' h% P. \0 {7 \, B2 @4 K0 ?! S3、每次systick溢出后会置位计数标志位和中断标志位,计数标志位在计数器重装载后被清除,而中断标志位也会随着中断服务程序的响应被清除,所以这两个标志位都不需要手动清除。
5 }* I4 O+ s# \5 M" b3 `7 A: \: }  I4、采用使用库函数的方法,只能采用中断的方法响应定时器计时时间到,如要采用查询的方法,那只能采用设置systick的寄存器的方法,具体操作以后再做分析。
chenbourne 回答时间:2016-6-15 21:29:03
谢谢 分享     
fightingboon 回答时间:2016-6-20 14:44:41
MouseCat 回答时间:2016-6-21 11:41:11
赞一个,很详细
西街耳呦 回答时间:2016-6-22 16:56:16
虽然不是很懂,留着慢慢看
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版