什么是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
- <span style="background-color: White;"><font color="Black">/**
" O/ K1 r1 ^% G. I; L4 G8 x2 f/ q - * [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
- *! M9 B# }/ p! u: K
- * @param ticks number of ticks between two interrupts
4 v# U2 ^6 E; u$ o9 M- R% b; P - * [url=home.php?mod=space&uid=266161]@return[/url] 1 = failed, 0 = successful" d0 u, b# M7 [7 P# g& P6 ^
- *; t: |2 R1 ^" V
- * Initialise the system tick timer and its interrupt and start the' P9 f4 V3 X' K- j Y
- * system tick timer / counter in free running mode to generate
- s. M2 f* {2 I. n* y - * periodical interrupts.
* e7 Y$ e- ]% H - */1 P" a0 W; C) [* n0 ^
- static __INLINE uint32_t SysTick_Config(uint32_t ticks)
" p2 _+ m$ H) J3 w" e B - {
2 x* C. w5 D! d c3 V8 k W - if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);
. [' A. a: j/ L( x! z6 T - /* Reload value impossible */重装载值必须小于0XFF FFFF,为什么,这是一个24位的递减计数器。! H! l8 \+ v# ~0 R) M5 i& H$ N
- - O `/ ^; o/ X
- SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
; a; P# `' Y b @! g7 b) h - /* set reload register */设置重装载值,SysTick_LOAD_RELOAD_Msk定义见后面
& k9 I5 g9 h" i$ b# m7 F! c- [( e7 J - NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);& _) }8 }) M a, [( r
- /* set Priority for Cortex-M0 System Interrupts */
, D2 ]3 }! r* }( ^# q6 } - SysTick->VAL = 0;& {$ f' o3 f! u" f" r( ]
- /* Load the SysTick Counter Value */. S0 S7 x) Q/ C! U* H. G0 g! M9 R
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
- D7 k# m# V7 D2 U - SysTick_CTRL_TICKINT_Msk |/ c: s4 n) a+ y- c0 b
- SysTick_CTRL_ENABLE_Msk;
+ O6 b" C( H0 t2 B7 U - /* Enable SysTick IRQ and SysTick Timer */$ Y" i4 h4 J6 c4 ~5 q
- return (0);, b7 W f5 ^$ n- S4 l0 l6 v; \/ j" T
- /* Function successful */' {1 R: y% z: g& v; \ \* I
- }% O8 g. u! N, _6 w$ m
- #endif
2 i& G' w. R& j' S; \ - 与systick相关的寄存器定义
9 u, H( ?! e( Z - /** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick. T5 e7 ]& S2 B c- K
- memory mapped structure for SysTick- b" T# ~& f5 U9 ^6 k6 F
- @{- W3 p C* T0 u. w, L
- */* y: }/ [) ~0 @3 O
- typedef struct
2 ? l& K- h/ c: } - {
) V+ L3 N+ }) g0 y$ v, {* X: q2 z - __IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */
' g- A7 E1 |; _0 U3 r- R) a/ z: i - __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */
: ^+ `! _ ] X3 G' l! B# `$ w - __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */
0 Z3 Q) E6 b8 ? - __I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */
) h% U N: }- r8 q$ h - } SysTick_Type;8 ?+ V& i& j: z3 [" \6 S" o; ^) S
- 5 w: q/ B$ F6 n$ \* k- A2 ^
- 与systick寄存器相关的寄存器及位的定义
6 ~! }3 D8 ^1 O8 G! w1 l
+ J! V* f3 E t- _: P, `" t- /* SysTick Control / Status Register Definitions */控制/状态寄存器
8 ~+ O1 C7 w H; _ - #define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
1 O% U% M* Y7 G G r+ j; J - #define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos)
; M; u$ r% N+ {" X5 _# m9 I% y - /*!< SysTick CTRL: COUNTFLAG Mask */ 溢出标志位 [) D, Y1 V# E' U/ q. T9 ?* l
- - G# j5 H8 Z# L* l% _, D. r
- #define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
" p4 I: B5 i6 G) d! j' j - #define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos)
! }" E/ ~. ]8 C - /*!< SysTick CTRL: CLKSOURCE Mask */时钟源选择位,0=外部时钟;1=内核时钟
# [" v. ]' j" \/ Y8 w* V
. c. p* J$ p4 `, u# K- #define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */0 h) P/ v3 Q- o& b( S/ [! ^6 F8 t
- #define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos) 7 C+ G# u2 g, F
- /*!< SysTick CTRL: TICKINT Mask */异常请求位- J; s3 v0 T, g, A+ I' X
0 `5 b3 [2 x5 W" }- #define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
g4 g3 e5 P3 [9 J, B( X) k - #define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos)
* p1 U8 Y6 p( _9 M+ K - /*!< SysTick CTRL: ENABLE Mask */使能位4 |* H8 e9 x O% S, l/ j0 ^3 j
- 6 i4 F7 ^2 u3 c! _3 R
- /* SysTick Reload Register Definitions */
1 r" H7 V" v4 Z% g" }' I - #define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */1 l( \2 C% g8 d" ]( K& h
- #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)
6 w, m. P1 J7 _# f7 E - /*!< SysTick LOAD: RELOAD Mask */
! e. y) K9 j3 Q) c
% d2 I8 v, E5 i6 Q; [- /* SysTick Current Register Definitions */' h* ^* g( F0 j ]6 K
- #define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
k$ O: B7 y- x - #define SysTick_VAL_CURRENT_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)
$ J- ?+ K6 p/ J7 U0 {2 [ - /*!< SysTick VAL: CURRENT Mask */( s; `2 o3 Y# i, x' x
- 7 i: d) s) B% s3 x' _$ _- v ]
- /* SysTick Calibration Register Definitions */
6 f; T6 \4 M, a3 t - #define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
. _- X9 q$ p" l4 y8 U - #define SysTick_CALIB_NOREF_Msk (1ul << SysTick_CALIB_NOREF_Pos) ; {; s/ B- i, L1 H
- /*!< SysTick CALIB: NOREF Mask */
$ q+ Q5 }4 b' d7 Y) Q
( e+ q$ ^) K+ i- #define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
- }5 y& G" |5 C- X1 U) [ - #define SysTick_CALIB_SKEW_Msk (1ul << SysTick_CALIB_SKEW_Pos)
6 K: M- l' {( O - /*!< SysTick CALIB: SKEW Mask */, ^2 n, G" E: W8 r
: ^) @4 @$ m- T/ d- #define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
2 e( H5 e# x& [6 M - #define SysTick_CALIB_TENMS_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */! G" H5 N' o9 F* Z/ B! l, o
- /*@}*/ /* 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' \
; b# J0 C: [* a: g
% X2 Z5 D: g3 S
3 }2 Q5 L5 I% M3 t4 u# t
! X$ Z! P1 ?$ ]6 L" o4 x' n
' |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- <span style="background-color: White;"><font color="Black">/**
G3 ?3 |- `) }8 G9 K v' L' t# r - * @brief Configures the SysTick clock source.
! n& E2 Y& B3 J- l, _ - * @param SysTick_CLKSource: specifies the SysTick clock source.; \3 q9 d$ C4 N! u
- * This parameter can be one of the following values:
$ J. R) x; w8 q- J/ D - * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source. Z L3 ~2 M& Y. s) n- `5 D
- * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.7 V% I* |; k* r/ T9 t6 D
- * @retval None2 C, B) S# B6 P- {% J5 R) f
- */% a7 A9 N+ s$ h6 O
- void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
* R# P2 k8 S; \+ ?5 c8 k6 ^ - {
8 g# @; p. {1 S4 G. i9 q1 g* \ - /* Check the parameters */
% G- l* n4 D8 h0 [, Q - assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
4 c: U8 U4 @0 X6 B( @* @ | - if (SysTick_CLKSource == SysTick_CLKSource_HCLK)9 Q# q8 x) |0 @" s
- {
' j# T& k9 F6 Q5 U( r' B - SysTick->CTRL |= SysTick_CLKSource_HCLK;/ o* W" ~* ?' P* P) z
- }
) h5 E8 J8 o U/ @* }0 Y - else
" X# V1 f4 W5 a - {
1 ]) U% U# c1 o- h$ Z$ ] - SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
+ `% C/ U! b5 i& {+ P - }
: |& W# d( n: k3 r - }3 P C1 `/ P% d0 W9 Z0 k
- , ~6 m9 A8 b; o
& s* Y8 \" s6 ~5 h" a& l- Systick时钟源的定义: _& q0 }# m& m3 b
- /** @defgroup SysTick_clock_source
4 U% h+ |" b- V9 ]; ~ - * @{
; U1 ? C; T) ^$ P; g4 B - */
7 c( O0 p- D4 f L8 C( _ - 3 S: A, \- r7 O1 u" f0 K
- #define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)//将控制状态寄存器的第二位置0,即用外部时钟源
8 {2 X" G* l7 @- Y( U% K - #define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)//将控制状态寄存器的第二位置1,即用内核时钟2 r4 j. d4 I+ m9 `+ l: N
- #define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \( F4 A- b4 s" @0 h9 M z' x
- ((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
" 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- <span style="background-color: White;"><font color="Black">/**
) [. ~# F% V A) e5 [! X: y - * @brief This function handles SysTick Handler.+ \7 k. C/ s7 B6 k( g
- * @param None
, d) \2 H+ F& c2 h/ a3 U - * @retval None" O6 ^7 V9 e2 O2 H
- */
( G$ q6 b8 @6 m - void SysTick_Handler(void)6 I, w7 \# V6 T, @# Z$ Y' Q
- {1 X. G* Y5 W+ }0 L9 M
- }</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
- <span style="background-color: White;"><font color="Black">/** [, a0 q5 }1 E( ^+ _
- * @brief Set the priority for an interrupt0 l: j8 H; c. [7 c
- *, r; B; [2 |. V9 w9 s! ^/ L9 B9 S
- * @param IRQn The number of the interrupt for set priority
- g9 G' ^- V- N F# v. k5 ? - * @param priority The priority to set
' O2 {4 ^) a1 c; i$ X% F" M - *7 |9 v, N. u) e, t
- * Set the priority for the specified interrupt. The interrupt
# T6 F: y: t7 W6 `% ^ - * number can be positive to specify an external (device specific)7 Y7 [6 V$ ~! t
- * interrupt, or negative to specify an internal (core) interrupt.1 {4 d, g. @( V2 H$ d. F( ]; h
- */ X9 J' ^' ]" a I' l
- * Note: The priority cannot be set for every core interrupt.- d: X5 w R2 T4 g* H8 z$ L
- */
+ g. ]) G w9 I r( B6 K: a" u; w - ) P2 B& ^8 o' j3 V
- 1 n2 `# ]- t7 }1 f3 m$ `
# G0 I O& a: u+ O( W
7 I+ [6 Y0 m0 B, Y. o6 ^6 J$ n6 t- static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)2 ]7 A/ T) p. w( g
- {5 r6 e1 b) B4 u' Q& }
- if(IRQn < 0) {8 C7 y+ @; o, b7 E2 o" X, ]6 c0 V1 o; m/ _
- 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 - else {1 ]: F2 X4 ^+ c1 N9 y( s
- NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
, I5 w/ n) ]& w- [4 z - }</font></span>
复制代码 ' [! o, `+ B* ?9 q- B; e
下面以一个实例来说明: 利用systick来实现以1秒的时间间隔,闪亮一个LED指示灯,指示灯接在GPIOA.8,低电平点亮。/ y) j7 d/ \& q$ v
- <span style="background-color: White;"><font color="Black">#include "stm32f10x.h"
4 f5 @# F8 r5 ~$ K7 n" _+ v - //函数声明. z: H& Z% F9 l" |7 E8 E
- void GPIO_Configuration(void);//设置GPIOA.8端口
0 | p' x: D, c- { - u32 t;//定义一个全局变量8 f* Y0 W' w/ M% C% J, Y, C# G
- int main(void); j- j: Y2 I l) |# E% g$ g
- {: }1 ]% E; x. e
- // SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
4 [9 l2 t% [0 U* M3 N' l - SysTick_Config(9000000);
. P6 W9 D% [0 y. R% B- O - SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
0 V4 Q& ]1 l( t7 u! X - GPIO_Configuration();
* Z' S5 h" {- }, x B - while(1); & ^4 a4 Q: |0 {; ~6 b$ N" U& _3 k
- }
5 d/ Q( s* w3 o$ |4 u! z. U - , r5 k. y* E! V6 f7 e
- //GPIOA.8设置函数3 E4 T4 f7 y$ j6 r
- void GPIO_Configuration(void)+ Z F0 r6 Q+ i I' K, I
- {7 G( o2 U6 N! E: r( J: V9 n
- GPIO_InitTypeDef GPIO_InitStruct;//定义一个端口初始化结构体/ f9 t) p9 L: Q4 i/ S. Z4 | b
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//打开GPIOA口时钟
. n9 u1 ^3 E& ^8 } - GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//设置为推挽输出' j7 d6 k5 f: Q7 D
- GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//设置输出频率50M
- d( t1 ?( C( V# O9 @& P - GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;//指定第8脚
( p5 Y0 }; I; X9 F) W - GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化GPIOA.8
+ T! A* Y3 }- B- E - GPIO_SetBits( GPIOA, GPIO_Pin_8);//置高GPIOA.8,关闭LED' ~0 @# n* v9 |5 o6 n; x- M3 R1 p3 j
- }
7 a7 J' ?2 s, i f" \ - //systick中断函数9 W F0 M$ a; D! y. `
- void SysTick_Handler(void)" q' g1 |( b3 z% }! ?* {
- {
. I/ ^' G1 l. i& Q2 E' y - t++;
& {( _3 G+ ~: S/ N" s - if(t>=1)
# C' E* L6 O2 d0 M - {
x0 j4 t- Y' t: I* H - if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1)
' ^: y" s7 @: x - {GPIO_ResetBits( GPIOA, GPIO_Pin_8);} 9 f7 [9 N: L; k0 o# d& K/ P
- }* O! v/ [7 i/ C3 W
- if(t>=2)
6 G2 d( ~* H# Z - {! S' p( }: n& J7 w( t2 g& C
- if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==0)
( u' e4 X% ^$ {$ O* q3 K9 _ - {GPIO_SetBits( GPIOA, GPIO_Pin_8);}$ L: }6 D$ s; r1 e/ X& r) ^- t6 a7 u
- t=0;" o( t( z! w0 y3 Q* a: h
- }$ t$ h8 m9 P, `' W% h& i
- }</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
) B1 t& `: |/ Q1 {
# u% }& U0 ~+ o- A
2、直接调用SysTick_Config(9000000);即不分频的结果,间隔为1/8=0.125s
% \' Y; ]2 g/ u2 E
# 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 |
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)。
3、要修改中断优先级调用7 y* c# }& x1 g3 N
void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
应用说明:
1、因systick是一个24位的定时器,故重装值最大值为2的24次方=16 777 215,
要注意不要超出这个值。
2、systick是cortex_m3的标配,不是外设。故不需要在RCC寄存器组打开他的时钟。
3、每次systick溢出后会置位计数标志位和中断标志位,计数标志位在计数器重装载后被清除,而中断标志位也会随着中断服务程序的响应被清除,所以这两个标志位都不需要手动清除。
4、采用使用库函数的方法,只能采用中断的方法响应定时器计时时间到,如要采用查询的方法,那只能采用设置systick的寄存器的方法,具体操作以后再做分析。