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

基于STM32的SYSTICK应用详解

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

$ ]* B; v7 ~8 ^9 ?  g4 E
  SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等。
要注意的是,当处理器在调试期间被喊停(halt)时,则SysTick定时器亦将暂停运作。
0 L  H+ o7 K+ x' [9 x& d/ B
时钟的选择:
用户可以在位于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);等

( {6 ^, ^; a7 z0 ^) F( A& K0 }
在3.5版本的库函数中与systick相关的函数只有两个
第一个,SysTick_Config(uint32_t ticks),在core_cm3.h头文件中进行定义的。
第二个,void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource),在misc.c文件中定义的。

% L; m7 v( ^7 O  o- `1 ]
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)/ `, z/ C) a! k2 B+ `8 D
函数说明:
- R( C" p9 ^' i; u7 c' d' G1 f1 x
  1. <span style="background-color: White;"><font color="Black">/**3 Q1 O6 M4 ^+ {& m
  2. * [url=home.php?mod=space&uid=247401]@brief[/url]  Initialize and start the SysTick counter and its interrupt.
    3 ]  M1 G2 t; M3 r& k
  3. *
    - O0 p! n/ v( l3 q
  4. * @param   ticks   number of ticks between two interrupts6 h0 l3 k& _$ V7 y2 i4 K! b9 ~& W" q
  5. * [url=home.php?mod=space&uid=266161]@return[/url]  1 = failed, 0 = successful' V+ d; `5 f; T' O
  6. *
    3 Q, }7 p) e4 |* |/ h
  7. * Initialise the system tick timer and its interrupt and start the9 [1 m  @/ R9 _$ O% O/ e
  8. * system tick timer / counter in free running mode to generate
    9 W8 P! a6 m" W& E9 G2 Z
  9. * periodical interrupts.- |! W, _% a( a3 n+ u
  10. */0 g) l. N$ |1 e# I$ y# k) @' Z. ?" K
  11. static __INLINE uint32_t SysTick_Config(uint32_t ticks)( w2 h( G5 P* [3 j/ f
  12. {
    # O+ a* `5 z* V0 l) O
  13.   if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            
    1 U4 P6 A  c1 m% `: w0 a
  14.   /* Reload value impossible */重装载值必须小于0XFF FFFF,为什么,这是一个24位的递减计数器。
    " ]7 R7 B: Z- e+ a) X
  15. 7 O/ U1 w+ W$ P, W
  16.   SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
    . i4 S8 P* y3 H; V) {
  17.      /* set reload register */设置重装载值,SysTick_LOAD_RELOAD_Msk定义见后面
    , M: ^! y+ K% C4 b( ~
  18.   NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
    - \7 o5 v( o$ Y2 |9 l) E/ ^( O9 a8 M
  19. /* set Priority for Cortex-M0 System Interrupts */8 p  x1 M+ B. O, O  u4 H' |
  20.   SysTick->VAL   = 0;
    $ F9 q4 N; o0 K
  21.   /* Load the SysTick Counter Value */( }6 L7 A* @+ O; o
  22.   SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
    : |# n; U$ y- J$ [; g$ f' y
  23.                    SysTick_CTRL_TICKINT_Msk   |
      z' L; V: h7 N8 o
  24.                    SysTick_CTRL_ENABLE_Msk;                  
    8 V/ a' q, l0 }6 J( J+ Z2 l+ B* Y
  25. /* Enable SysTick IRQ and SysTick Timer */! {" W4 M9 @7 r* Y7 \
  26.   return (0);
    ; L/ m* Z# I7 j- _- n; [
  27.   /* Function successful */( o% K& Q( w5 D
  28. }
    5 _8 y& F+ O' h8 F
  29. #endif7 g  F. P3 B, J5 j* v. S
  30. 与systick相关的寄存器定义+ i& x; M  R& K; C1 z% k5 N& @
  31. /** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick
    ; o) \! q3 ]$ F' O+ \
  32.   memory mapped structure for SysTick
    . y  w% Q% T) n, ?( [
  33.   @{
    ( c& l4 E1 B5 U
  34. */% l* f4 w8 n% n# R2 i; `+ h
  35. typedef struct
    # k- q/ j7 C# P8 K9 O
  36. {
    % D8 Q7 P  M. I8 e; U) W
  37.   __IO uint32_t CTRL; /*!< Offset: 0x00  SysTick Control and Status Register */; J2 k3 q. ?, I$ ]" T7 R
  38.   __IO uint32_t LOAD; /*!< Offset: 0x04  SysTick Reload Value Register       */) H! {/ L" D- e6 ^
  39.   __IO uint32_t VAL; /*!< Offset: 0x08  SysTick Current Value Register      */; m; l5 B' R! k
  40.   __I  uint32_t CALIB; /*!< Offset: 0x0C  SysTick Calibration Register        */
    . R" X! N& V4 G# ~0 j3 W4 f3 s; K' r9 e
  41. } SysTick_Type;# O2 z$ D; S0 g, O

  42. $ j* n$ P2 b6 m6 l
  43. 与systick寄存器相关的寄存器及位的定义
    9 u: V- m8 F: P1 ]" u& a* s1 n2 Z; P

  44. : U8 _$ d: O8 ~! T; `
  45. /* SysTick Control / Status Register Definitions */控制/状态寄存器
    8 n# m4 |' e: ?- V$ i+ E
  46. #define  SysTick_CTRL_COUNTFLAG_Pos  16      /*!< SysTick CTRL: COUNTFLAG Position */
    0 U- n( l: p+ M5 B" b! G- V; K
  47. #define SysTick_CTRL_COUNTFLAG_Msk         (1ul << SysTick_CTRL_COUNTFLAG_Pos)         , \& }* u; y" H7 m; l. n( b( d
  48. /*!< SysTick CTRL: COUNTFLAG Mask */ 溢出标志位
    6 {% F. s. b9 N7 v3 c" u: S
  49. - s, ]6 O; t0 A3 e* Q+ A. R$ J
  50. #define SysTick_CTRL_CLKSOURCE_Pos   2       /*!< SysTick CTRL: CLKSOURCE Position */' k! x: [$ x) A: T3 h! B& n
  51. #define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)  ( E2 W4 @! O" L5 ~
  52. /*!< SysTick CTRL: CLKSOURCE Mask */时钟源选择位,0=外部时钟;1=内核时钟
    & T. g& W1 _! Q( v% Q8 n  l/ m* L  K( |

  53. ) A. E, Q0 _2 i& T8 k' m6 G: {7 G; P8 {
  54. #define SysTick_CTRL_TICKINT_Pos      1        /*!< SysTick CTRL: TICKINT Position */1 s* Z$ p9 U8 H- H4 p9 @# g
  55. #define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)         
      O" C3 \  T0 t1 F4 z
  56. /*!< SysTick CTRL: TICKINT Mask */异常请求位8 K$ H# W7 b, l. L& d

  57. $ I# x; `- }% ]+ p
  58. #define SysTick_CTRL_ENABLE_Pos             0       /*!< SysTick CTRL: ENABLE Position */
    " e. n/ F/ W% x5 x" |! w- M
  59. #define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos)               . j( u! {) K( h9 ^9 f6 a* m
  60. /*!< SysTick CTRL: ENABLE Mask */使能位
    ! G3 p  y4 O/ ]

  61. $ e3 i$ J! M: u  N8 G+ f1 [- D
  62. /* SysTick Reload Register Definitions */
    , W& L. B/ H2 [
  63. #define SysTick_LOAD_RELOAD_Pos             0    /*!< SysTick LOAD: RELOAD Position */) J) M: ]- W0 P5 X! x8 l
  64. #define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        
    3 p3 h! y  I7 y+ d) x$ O
  65. /*!< SysTick LOAD: RELOAD Mask */
    ' Q/ J4 P: T# K, v! F7 J

  66. 5 Z  I& G$ n- C# @
  67. /* SysTick Current Register Definitions */
    # `( c% ^' x' @7 M1 v
  68. #define SysTick_VAL_CURRENT_Pos             0       /*!< SysTick VAL: CURRENT Position */
    * r3 r* @) _4 k' [
  69. #define SysTick_VAL_CURRENT_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        / P4 Q# g+ {+ c$ g
  70. /*!< SysTick VAL: CURRENT Mask *// l+ K; g# G. t  A% G7 }5 z

  71. 2 U; o9 u4 r8 ^* E  r
  72. /* SysTick Calibration Register Definitions */, T1 t% x3 j. _# B$ \, l
  73. #define SysTick_CALIB_NOREF_Pos            31      /*!< SysTick CALIB: NOREF Position */8 F$ j2 h: a& b+ m. f0 W
  74. #define SysTick_CALIB_NOREF_Msk            (1ul << SysTick_CALIB_NOREF_Pos)              
    5 F& P" c! g: e; [0 ^  M# V: M
  75. /*!< SysTick CALIB: NOREF Mask */) [3 Q8 H- A" F! q
  76. 1 Y1 z( h$ A: K7 Q  \% U" h
  77. #define SysTick_CALIB_SKEW_Pos             30       /*!< SysTick CALIB: SKEW Position */7 Z3 Z# S1 j% c+ V% a9 a1 p
  78. #define SysTick_CALIB_SKEW_Msk             (1ul << SysTick_CALIB_SKEW_Pos)               " F) j' F" u5 o4 u: l! j
  79. /*!< SysTick CALIB: SKEW Mask */" `% y9 D$ ]$ a0 X" D. M0 T
  80. % j$ l- V+ H1 ], T& X
  81. #define SysTick_CALIB_TENMS_Pos             0       /*!< SysTick CALIB: TENMS Position */
    ) s& u1 ?7 V( i! H2 g
  82. #define SysTick_CALIB_TENMS_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */1 Z* e; I: V5 O: J; U" e0 i5 t# F
  83. /*@}*/ /* end of group CMSIS_CM3_SysTick */</font></span>
复制代码
8 J+ x+ s% ]6 Q5 g5 O7 C# Q
% S9 L9 F) ]3 w. H
与systick相关的寄存器的说明! l/ v5 A) V# h8 `$ Y5 B
31.jpg 5 I& ^4 Y9 H0 T/ Y

# j' G4 c+ {! }8 v' |' M9 f 32.jpg
( L& c" H7 ^; }3 H+ k. m6 q; G9 @% J
1 h5 w9 J2 v6 |& [+ ^ 33.jpg
% n0 C! W8 z  k0 @9 q  ~9 m/ A0 B/ e* z% w) Z. t$ O* h& u
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
作用:
选择systick的时钟源,AHB时钟或AHB的8分频
默认使用的是AHB时钟,即72MHz
% c+ }! o; M) z; |, A2 |1 g9 T5 ?" v1 I9 c  @) R' a) F
函数说明:
, w( m4 x* ?/ |' n4 T$ H
  1. <span style="background-color: White;"><font color="Black">/**3 t( }, k; `# {" p- ?: x8 \3 Y
  2.   * @brief  Configures the SysTick clock source.
    ) ]8 W# C  L6 A1 J0 m
  3.   * @param  SysTick_CLKSource: specifies the SysTick clock source.
    ' O) z2 K6 r7 y
  4.   *   This parameter can be one of the following values:+ |2 S0 s; h8 b! k8 e# R
  5.   *     @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.
    ( V+ E: j  z2 s1 T# l, e
  6.   *     @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.
    ; C$ Q: J+ _$ H7 P
  7.   * @retval None
    + N( m9 ?# H5 j- Y
  8.   */9 S- f; h  C* @$ x* M
  9. void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)& U4 [; F! P4 B, c! F
  10. {
    - C. G' V# l  l* e( A4 A
  11.   /* Check the parameters */
    . Z3 M" P- R% o2 B
  12.   assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));: Q! E* t: f$ g
  13.   if (SysTick_CLKSource == SysTick_CLKSource_HCLK): i% U6 j+ _& c9 a' k
  14.   {
    ! m" v0 d) k9 x
  15.     SysTick->CTRL |= SysTick_CLKSource_HCLK;. z& W3 U7 f2 z1 K- G# x( ^. S8 U$ `
  16.   }
    1 V& @5 h0 q) k% O$ \
  17.   else
    ' w9 `6 c# T8 ~" ^/ ]
  18.   {4 W% v6 O5 x* A$ I
  19.     SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;& o6 }2 p; t7 X; j  b  _
  20.   }9 r% L. z/ j/ o
  21. }- A5 x4 i- Z4 w

  22. / B$ l7 E, y4 z3 E1 x# P+ M
  23. 5 ]# y* E! f/ d+ f' x
  24. Systick时钟源的定义:
    & {1 P" Y" S7 X9 {, G+ p
  25. /** @defgroup SysTick_clock_source3 A# L; O: Z# u4 w) G
  26.   * @{
    . }0 D6 g8 R6 a7 {
  27.   */% i" e9 q( S/ g% u4 l1 r

  28. 8 @: Q, d4 r" G; F! [
  29. #define SysTick_CLKSource_HCLK_Div8    ((uint32_t)0xFFFFFFFB)//将控制状态寄存器的第二位置0,即用外部时钟源5 w; s" I) k2 M) P& T
  30. #define SysTick_CLKSource_HCLK         ((uint32_t)0x00000004)//将控制状态寄存器的第二位置1,即用内核时钟. {/ K& ]7 F( I  \& e" F- t# l
  31. #define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
    % V0 R$ y+ f4 Z4 ^2 v- ^/ g, r
  32.                                        ((SOURCE) == SysTick_CLKSource_HCLK_Div8))</font></span>
复制代码

; _. L. \0 D6 h4 }5 }
Systick定时时间的设定:

+ ~- N- ^& I- ?: e: k' N
重装载值=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,而又在主函数中编写中断函数,则会报错。  C1 J$ Q/ ~/ J( X, ?, e0 h
$ \: i8 G* G% C% J1 a0 N: C  h
34.jpg
* Q. a- T/ g: Q

; ]3 c" z- G! a) B7 \' C  \+ m# n
因为在stm32f10x_it.c文件中,也有这个中断函数的声明,只是内容是空的。& |  {. ]$ `: x4 x$ _

) S& t% K" B# A2 X
  1. <span style="background-color: White;"><font color="Black">/**
    & s; `" [* ^+ Q! V; R4 ^+ X
  2.   * @brief  This function handles SysTick Handler.* D* Y) Q) {$ C  Q
  3.   * @param  None
    ; @5 t% ~2 R& U% y% t
  4.   * @retval None: F, V. A  g0 F. i/ U! b4 D- s3 E
  5.   */
    $ s- [/ P9 O  J: l) [$ e5 F' D
  6. void SysTick_Handler(void)
    2 {) p9 e% `3 d
  7. {  H) [1 E; c7 N- [3 l
  8. }</font></span>
复制代码

7 t% \  [+ o5 C! e
中断优先级的修改
在调用SysTick_Config(uint32_t ticks)之后,调用 void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)。这个函数在core_cm3.h头文件中。
具体内容如下:- o3 t& |" p+ X7 o! ]) D/ w& x
  1. <span style="background-color: White;"><font color="Black">/**- y% z9 A4 N4 u
  2. * @brief  Set the priority for an interrupt
    2 n; f. F: D& n$ _3 M* Z% u$ I- F
  3. *
    $ K+ j) k. w1 E( ^. b! c) |
  4. * @param  IRQn      The number of the interrupt for set priority3 q0 D- h/ w: [  }( m# l7 S4 i
  5. * @param  priority  The priority to set% t' ~% P7 q& d" K
  6. *% D- V; M# d% Q( D/ v
  7. * Set the priority for the specified interrupt. The interrupt# Q. y/ G: u8 g; e" ?1 B& p0 k# M
  8. * number can be positive to specify an external (device specific)6 D1 M3 W0 a1 Q- r
  9. * interrupt, or negative to specify an internal (core) interrupt.7 V; T2 I  l6 F! m- P4 x9 ]
  10. *7 S$ f  N- _/ _' E
  11. * Note: The priority cannot be set for every core interrupt.
    " x- Q2 {! F- h0 A9 v
  12. */4 I& Y, Z* X' z) n6 S' _  ]
  13. 4 T* ~7 s( F" m6 L. m

  14. # j6 R& d) g' l

  15. : M7 G, B7 q+ n4 {1 ~7 P9 p
  16. : k, T8 g5 C! s/ o& k0 C  B
  17. static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
    + _# g" T5 v4 G+ t/ M
  18. {& I% ?; `. A8 _
  19.   if(IRQn < 0) {' ~1 O/ K3 J# q' @- s
  20.     SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
    8 q& }3 _6 B. }+ y( ^( N5 W( q: Y
  21.   else {  s. ]; F+ T& O+ C
  22.     NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */
    # [; _5 d- K( z
  23. }</font></span>
复制代码
8 G$ t( }. m% k0 q7 B
下面以一个实例来说明:
利用systick来实现以1秒的时间间隔,闪亮一个LED指示灯,指示灯接在GPIOA.8,低电平点亮。8 X1 c; _) w( u5 v8 X, F. R) ?
  1. <span style="background-color: White;"><font color="Black">#include "stm32f10x.h"
    . W5 h$ Z0 M3 w# l! X; ~
  2. //函数声明9 w( t; |% N! X& B
  3. void GPIO_Configuration(void);//设置GPIOA.8端口
      Q9 v+ w' f& J$ g3 b: X
  4. u32 t;//定义一个全局变量8 s  \, ~: p; p. v( O; h7 k& e
  5. int main(void)& w2 }6 q: [5 I( M* C
  6. {
    5 l3 P- Q. i7 b9 L! Y; J+ v
  7. // SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);$ |- P4 R8 X0 Z' K
  8.        SysTick_Config(9000000);
      u8 B* Q- O  o- P6 I7 d
  9.        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
    3 R' `; W9 _6 H8 y' u
  10.        GPIO_Configuration();. l$ P; a& a* L+ |& S
  11.        while(1);      # M* I- y7 `0 i9 t8 E: q
  12. }" f  U2 b+ ~& z8 \

  13. - g1 a1 w! `  I: [5 z* _
  14. //GPIOA.8设置函数* R8 X# ~2 `- ?1 h/ d5 A
  15. void GPIO_Configuration(void)( U6 l5 Y) i7 j# x+ i
  16. {
    , w# R: H2 c% N
  17. GPIO_InitTypeDef  GPIO_InitStruct;//定义一个端口初始化结构体: S2 P) H$ |7 Q4 ]5 B' s0 K
  18.        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//打开GPIOA口时钟* }% e( |6 |1 x2 k
  19.        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//设置为推挽输出! U% ~' R9 y$ w, N: c
  20.        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//设置输出频率50M/ D. j! Y" e' u0 h! _
  21.        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;//指定第8脚
    + q8 X. a, U. ?; y
  22.        GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化GPIOA.8      ! _' w# y2 _2 _9 R  H/ f
  23.        GPIO_SetBits( GPIOA,  GPIO_Pin_8);//置高GPIOA.8,关闭LED) s  D% d9 W. C% [4 j: x  K) S
  24. }
    8 X6 O! b7 E6 I8 Q2 i
  25. //systick中断函数( g# r/ k+ U) j& N/ d7 ^
  26. void SysTick_Handler(void)
    : y7 _: y0 l# `
  27. {
    4 H5 Q7 B8 J5 m
  28. t++;+ M' B$ {0 E$ J
  29.        if(t>=1)
    8 h; O$ Q1 V- v3 E3 S9 k
  30.        {- G. u0 r1 h- m, e
  31.               if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1)
    6 U  M1 \9 X' V$ R5 j0 Z
  32.               {GPIO_ResetBits( GPIOA, GPIO_Pin_8);}      9 }0 Z' H% `$ R1 [$ ^( n' [$ ~$ i  X
  33.        }0 I" ?4 o  [) @  N/ h
  34.        if(t>=2)
    9 A0 s. T; r+ Y  q5 c/ ]' Z' m+ n' K
  35.        {, I! j: ?' e, L" E! k
  36.               if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==0)
    ) E; k' a# u# t+ W& V+ B$ V, |# p
  37.                      {GPIO_SetBits( GPIOA, GPIO_Pin_8);}2 \3 O- U. C$ r! o4 Y
  38.                      t=0;
    / p# T/ O& K' S, @
  39.        }8 ^# Q- w' t. w4 `: |8 o& J& R
  40. }</font></span>
复制代码
) ^' T0 I6 P' S5 \

5 i2 u. v; O" C' Z3 }0 o; ^
; X* W$ y. n0 D- P7 f, e4 W/ Y& V
模拟后的结果
1、8分频后结果
" s- |, `, H: K/ x 35.jpg
; @4 ^& x) r( k8 i( g% R2 u" F( P6 Q" l- k: {6 b$ k# U! c2 g
2、直接调用SysTick_Config(9000000);即不分频的结果,间隔为1/8=0.125s
; q) t- C' n6 t 36.jpg
# j& I# L! m/ {: ]( `4 R
4 a% j2 j, O+ K2 c; h6 c( n
% `( z! i2 S1 a+ `/ R4 @
) }/ k$ S1 O7 f
: u9 v& V4 G" {* M3 a7 a5 V

; a4 V* z' s4 s1 A2 [$ R* ~! i

, t  t& o* x8 ?% y& {
赞 收藏 3 评论5 发布时间:2016-6-15 15:51

举报

5个回答
又是一年春来到 回答时间:2016-6-15 15:51:47
总结:5 p- Z. ~! A6 j" s0 i. v
1、要使用systick定时器,只需调用SysTick_Config(uint32_t ticks)函数即可,  H& `3 P  J3 H# N+ q9 R' ~/ e
   自动完成了,重装载值的装载,时钟源选择,计数寄存器复位,中断优先级的设置(最低),开中断,开始计数的工作。
2 f1 e& M2 [2 `1 G4 Y/ [2、要修改时钟源调用SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)。
" ]/ c- g3 b1 l. v1 Z+ I. e3、要修改中断优先级调用" i4 g% A7 e' s0 }0 c
     void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
/ _4 H( `& H6 E2 a9 s应用说明:
4 P/ r/ G1 \& R1、因systick是一个24位的定时器,故重装值最大值为2的24次方=16 777 215," ], s1 n6 ]! E: H9 j, ]& U6 D
   要注意不要超出这个值。0 W6 s: O1 x* K# N. x; V% C4 `' Y
2、systick是cortex_m3的标配,不是外设。故不需要在RCC寄存器组打开他的时钟。6 c$ O& s9 Q, v: C  ^  \
3、每次systick溢出后会置位计数标志位和中断标志位,计数标志位在计数器重装载后被清除,而中断标志位也会随着中断服务程序的响应被清除,所以这两个标志位都不需要手动清除。/ a- q0 y& F& O% f$ w* T
4、采用使用库函数的方法,只能采用中断的方法响应定时器计时时间到,如要采用查询的方法,那只能采用设置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管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版