什么是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- <span style="background-color: White;"><font color="Black">/**3 Q1 O6 M4 ^+ {& m
- * [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 - *
- O0 p! n/ v( l3 q - * @param ticks number of ticks between two interrupts6 h0 l3 k& _$ V7 y2 i4 K! b9 ~& W" q
- * [url=home.php?mod=space&uid=266161]@return[/url] 1 = failed, 0 = successful' V+ d; `5 f; T' O
- *
3 Q, }7 p) e4 |* |/ h - * Initialise the system tick timer and its interrupt and start the9 [1 m @/ R9 _$ O% O/ e
- * system tick timer / counter in free running mode to generate
9 W8 P! a6 m" W& E9 G2 Z - * periodical interrupts.- |! W, _% a( a3 n+ u
- */0 g) l. N$ |1 e# I$ y# k) @' Z. ?" K
- static __INLINE uint32_t SysTick_Config(uint32_t ticks)( w2 h( G5 P* [3 j/ f
- {
# O+ a* `5 z* V0 l) O - if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);
1 U4 P6 A c1 m% `: w0 a - /* Reload value impossible */重装载值必须小于0XFF FFFF,为什么,这是一个24位的递减计数器。
" ]7 R7 B: Z- e+ a) X - 7 O/ U1 w+ W$ P, W
- SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
. i4 S8 P* y3 H; V) { - /* set reload register */设置重装载值,SysTick_LOAD_RELOAD_Msk定义见后面
, M: ^! y+ K% C4 b( ~ - NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
- \7 o5 v( o$ Y2 |9 l) E/ ^( O9 a8 M - /* set Priority for Cortex-M0 System Interrupts */8 p x1 M+ B. O, O u4 H' |
- SysTick->VAL = 0;
$ F9 q4 N; o0 K - /* Load the SysTick Counter Value */( }6 L7 A* @+ O; o
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
: |# n; U$ y- J$ [; g$ f' y - SysTick_CTRL_TICKINT_Msk |
z' L; V: h7 N8 o - SysTick_CTRL_ENABLE_Msk;
8 V/ a' q, l0 }6 J( J+ Z2 l+ B* Y - /* Enable SysTick IRQ and SysTick Timer */! {" W4 M9 @7 r* Y7 \
- return (0);
; L/ m* Z# I7 j- _- n; [ - /* Function successful */( o% K& Q( w5 D
- }
5 _8 y& F+ O' h8 F - #endif7 g F. P3 B, J5 j* v. S
- 与systick相关的寄存器定义+ i& x; M R& K; C1 z% k5 N& @
- /** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick
; o) \! q3 ]$ F' O+ \ - memory mapped structure for SysTick
. y w% Q% T) n, ?( [ - @{
( c& l4 E1 B5 U - */% l* f4 w8 n% n# R2 i; `+ h
- typedef struct
# k- q/ j7 C# P8 K9 O - {
% D8 Q7 P M. I8 e; U) W - __IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */; J2 k3 q. ?, I$ ]" T7 R
- __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */) H! {/ L" D- e6 ^
- __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */; m; l5 B' R! k
- __I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */
. R" X! N& V4 G# ~0 j3 W4 f3 s; K' r9 e - } SysTick_Type;# O2 z$ D; S0 g, O
$ j* n$ P2 b6 m6 l- 与systick寄存器相关的寄存器及位的定义
9 u: V- m8 F: P1 ]" u& a* s1 n2 Z; P
: U8 _$ d: O8 ~! T; `- /* SysTick Control / Status Register Definitions */控制/状态寄存器
8 n# m4 |' e: ?- V$ i+ E - #define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
0 U- n( l: p+ M5 B" b! G- V; K - #define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos) , \& }* u; y" H7 m; l. n( b( d
- /*!< SysTick CTRL: COUNTFLAG Mask */ 溢出标志位
6 {% F. s. b9 N7 v3 c" u: S - - s, ]6 O; t0 A3 e* Q+ A. R$ J
- #define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */' k! x: [$ x) A: T3 h! B& n
- #define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos) ( E2 W4 @! O" L5 ~
- /*!< SysTick CTRL: CLKSOURCE Mask */时钟源选择位,0=外部时钟;1=内核时钟
& T. g& W1 _! Q( v% Q8 n l/ m* L K( |
) A. E, Q0 _2 i& T8 k' m6 G: {7 G; P8 {- #define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */1 s* Z$ p9 U8 H- H4 p9 @# g
- #define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos)
O" C3 \ T0 t1 F4 z - /*!< SysTick CTRL: TICKINT Mask */异常请求位8 K$ H# W7 b, l. L& d
$ I# x; `- }% ]+ p- #define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
" e. n/ F/ W% x5 x" |! w- M - #define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos) . j( u! {) K( h9 ^9 f6 a* m
- /*!< SysTick CTRL: ENABLE Mask */使能位
! G3 p y4 O/ ]
$ e3 i$ J! M: u N8 G+ f1 [- D- /* SysTick Reload Register Definitions */
, W& L. B/ H2 [ - #define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */) J) M: ]- W0 P5 X! x8 l
- #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)
3 p3 h! y I7 y+ d) x$ O - /*!< SysTick LOAD: RELOAD Mask */
' Q/ J4 P: T# K, v! F7 J
5 Z I& G$ n- C# @- /* SysTick Current Register Definitions */
# `( c% ^' x' @7 M1 v - #define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
* r3 r* @) _4 k' [ - #define SysTick_VAL_CURRENT_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) / P4 Q# g+ {+ c$ g
- /*!< SysTick VAL: CURRENT Mask *// l+ K; g# G. t A% G7 }5 z
2 U; o9 u4 r8 ^* E r- /* SysTick Calibration Register Definitions */, T1 t% x3 j. _# B$ \, l
- #define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */8 F$ j2 h: a& b+ m. f0 W
- #define SysTick_CALIB_NOREF_Msk (1ul << SysTick_CALIB_NOREF_Pos)
5 F& P" c! g: e; [0 ^ M# V: M - /*!< SysTick CALIB: NOREF Mask */) [3 Q8 H- A" F! q
- 1 Y1 z( h$ A: K7 Q \% U" h
- #define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */7 Z3 Z# S1 j% c+ V% a9 a1 p
- #define SysTick_CALIB_SKEW_Msk (1ul << SysTick_CALIB_SKEW_Pos) " F) j' F" u5 o4 u: l! j
- /*!< SysTick CALIB: SKEW Mask */" `% y9 D$ ]$ a0 X" D. M0 T
- % j$ l- V+ H1 ], T& X
- #define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
) s& u1 ?7 V( i! H2 g - #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
- /*@}*/ /* 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
5 I& ^4 Y9 H0 T/ Y
# j' G4 c+ {! }8 v' |' M9 f
( L& c" H7 ^; }3 H+ k. m6 q; G9 @% J
1 h5 w9 J2 v6 |& [+ ^
% 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- <span style="background-color: White;"><font color="Black">/**3 t( }, k; `# {" p- ?: x8 \3 Y
- * @brief Configures the SysTick clock source.
) ]8 W# C L6 A1 J0 m - * @param SysTick_CLKSource: specifies the SysTick clock source.
' O) z2 K6 r7 y - * This parameter can be one of the following values:+ |2 S0 s; h8 b! k8 e# R
- * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.
( V+ E: j z2 s1 T# l, e - * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.
; C$ Q: J+ _$ H7 P - * @retval None
+ N( m9 ?# H5 j- Y - */9 S- f; h C* @$ x* M
- void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)& U4 [; F! P4 B, c! F
- {
- C. G' V# l l* e( A4 A - /* Check the parameters */
. Z3 M" P- R% o2 B - assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));: Q! E* t: f$ g
- if (SysTick_CLKSource == SysTick_CLKSource_HCLK): i% U6 j+ _& c9 a' k
- {
! m" v0 d) k9 x - SysTick->CTRL |= SysTick_CLKSource_HCLK;. z& W3 U7 f2 z1 K- G# x( ^. S8 U$ `
- }
1 V& @5 h0 q) k% O$ \ - else
' w9 `6 c# T8 ~" ^/ ] - {4 W% v6 O5 x* A$ I
- SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;& o6 }2 p; t7 X; j b _
- }9 r% L. z/ j/ o
- }- A5 x4 i- Z4 w
/ B$ l7 E, y4 z3 E1 x# P+ M- 5 ]# y* E! f/ d+ f' x
- Systick时钟源的定义:
& {1 P" Y" S7 X9 {, G+ p - /** @defgroup SysTick_clock_source3 A# L; O: Z# u4 w) G
- * @{
. }0 D6 g8 R6 a7 { - */% i" e9 q( S/ g% u4 l1 r
8 @: Q, d4 r" G; F! [- #define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)//将控制状态寄存器的第二位置0,即用外部时钟源5 w; s" I) k2 M) P& T
- #define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)//将控制状态寄存器的第二位置1,即用内核时钟. {/ K& ]7 F( I \& e" F- t# l
- #define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
% V0 R$ y+ f4 Z4 ^2 v- ^/ g, r - ((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
* 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- <span style="background-color: White;"><font color="Black">/**
& s; `" [* ^+ Q! V; R4 ^+ X - * @brief This function handles SysTick Handler.* D* Y) Q) {$ C Q
- * @param None
; @5 t% ~2 R& U% y% t - * @retval None: F, V. A g0 F. i/ U! b4 D- s3 E
- */
$ s- [/ P9 O J: l) [$ e5 F' D - void SysTick_Handler(void)
2 {) p9 e% `3 d - { H) [1 E; c7 N- [3 l
- }</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
- <span style="background-color: White;"><font color="Black">/**- y% z9 A4 N4 u
- * @brief Set the priority for an interrupt
2 n; f. F: D& n$ _3 M* Z% u$ I- F - *
$ K+ j) k. w1 E( ^. b! c) | - * @param IRQn The number of the interrupt for set priority3 q0 D- h/ w: [ }( m# l7 S4 i
- * @param priority The priority to set% t' ~% P7 q& d" K
- *% D- V; M# d% Q( D/ v
- * Set the priority for the specified interrupt. The interrupt# Q. y/ G: u8 g; e" ?1 B& p0 k# M
- * number can be positive to specify an external (device specific)6 D1 M3 W0 a1 Q- r
- * interrupt, or negative to specify an internal (core) interrupt.7 V; T2 I l6 F! m- P4 x9 ]
- *7 S$ f N- _/ _' E
- * Note: The priority cannot be set for every core interrupt.
" x- Q2 {! F- h0 A9 v - */4 I& Y, Z* X' z) n6 S' _ ]
- 4 T* ~7 s( F" m6 L. m
# j6 R& d) g' l
: M7 G, B7 q+ n4 {1 ~7 P9 p- : k, T8 g5 C! s/ o& k0 C B
- static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+ _# g" T5 v4 G+ t/ M - {& I% ?; `. A8 _
- if(IRQn < 0) {' ~1 O/ K3 J# q' @- s
- 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 - else { s. ]; F+ T& O+ C
- NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
# [; _5 d- K( z - }</font></span>
复制代码 8 G$ t( }. m% k0 q7 B
下面以一个实例来说明: 利用systick来实现以1秒的时间间隔,闪亮一个LED指示灯,指示灯接在GPIOA.8,低电平点亮。8 X1 c; _) w( u5 v8 X, F. R) ?
- <span style="background-color: White;"><font color="Black">#include "stm32f10x.h"
. W5 h$ Z0 M3 w# l! X; ~ - //函数声明9 w( t; |% N! X& B
- void GPIO_Configuration(void);//设置GPIOA.8端口
Q9 v+ w' f& J$ g3 b: X - u32 t;//定义一个全局变量8 s \, ~: p; p. v( O; h7 k& e
- int main(void)& w2 }6 q: [5 I( M* C
- {
5 l3 P- Q. i7 b9 L! Y; J+ v - // SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);$ |- P4 R8 X0 Z' K
- SysTick_Config(9000000);
u8 B* Q- O o- P6 I7 d - SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
3 R' `; W9 _6 H8 y' u - GPIO_Configuration();. l$ P; a& a* L+ |& S
- while(1); # M* I- y7 `0 i9 t8 E: q
- }" f U2 b+ ~& z8 \
- g1 a1 w! ` I: [5 z* _- //GPIOA.8设置函数* R8 X# ~2 `- ?1 h/ d5 A
- void GPIO_Configuration(void)( U6 l5 Y) i7 j# x+ i
- {
, w# R: H2 c% N - GPIO_InitTypeDef GPIO_InitStruct;//定义一个端口初始化结构体: S2 P) H$ |7 Q4 ]5 B' s0 K
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//打开GPIOA口时钟* }% e( |6 |1 x2 k
- GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//设置为推挽输出! U% ~' R9 y$ w, N: c
- GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//设置输出频率50M/ D. j! Y" e' u0 h! _
- GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;//指定第8脚
+ q8 X. a, U. ?; y - GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化GPIOA.8 ! _' w# y2 _2 _9 R H/ f
- GPIO_SetBits( GPIOA, GPIO_Pin_8);//置高GPIOA.8,关闭LED) s D% d9 W. C% [4 j: x K) S
- }
8 X6 O! b7 E6 I8 Q2 i - //systick中断函数( g# r/ k+ U) j& N/ d7 ^
- void SysTick_Handler(void)
: y7 _: y0 l# ` - {
4 H5 Q7 B8 J5 m - t++;+ M' B$ {0 E$ J
- if(t>=1)
8 h; O$ Q1 V- v3 E3 S9 k - {- G. u0 r1 h- m, e
- if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1)
6 U M1 \9 X' V$ R5 j0 Z - {GPIO_ResetBits( GPIOA, GPIO_Pin_8);} 9 }0 Z' H% `$ R1 [$ ^( n' [$ ~$ i X
- }0 I" ?4 o [) @ N/ h
- if(t>=2)
9 A0 s. T; r+ Y q5 c/ ]' Z' m+ n' K - {, I! j: ?' e, L" E! k
- if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==0)
) E; k' a# u# t+ W& V+ B$ V, |# p - {GPIO_SetBits( GPIOA, GPIO_Pin_8);}2 \3 O- U. C$ r! o4 Y
- t=0;
/ p# T/ O& K' S, @ - }8 ^# Q- w' t. w4 `: |8 o& J& R
- }</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
; @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
# j& I# L! m/ {: ]( `4 R4 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& { |
1、要使用systick定时器,只需调用SysTick_Config(uint32_t ticks)函数即可, H& `3 P J3 H# N+ q9 R' ~/ e
自动完成了,重装载值的装载,时钟源选择,计数寄存器复位,中断优先级的设置(最低),开中断,开始计数的工作。
2、要修改时钟源调用SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)。
3、要修改中断优先级调用" i4 g% A7 e' s0 }0 c
void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
应用说明:
1、因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的寄存器的方法,具体操作以后再做分析。