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

【经验分享】stm32之Systick(系统时钟)

[复制链接]
STMCU小助手 发布时间:2022-1-20 21:23
Systick的两大作用:
  1、可以产生精确延时;
  2、可以提供给操作系统一个单独的心跳(时钟)节拍;
通常实现Delay(N)函数的方法为:
  for(i=0;i<x;i++)
    ;
  对于STM32系统微处理器来说,执行一条指令只有几十ns(纳秒),进入for循环,要实现N毫秒的x值非常大;而由于系统频率的宽广,很难计算出延时N毫秒的精确值;针对STM32微处理器,需要重新设计一个新的方法去实现该功能,以实现在程序中使用Delay(N);
  cortex的内核中包含一个SysTick时钟,SysTick为一个24位递减计数器;SysTick设定初值并使能后,每经过1个系统时钟周期,计数值就减1;计数到0,SysTick计数器自动装载初值并继续计数,同时内部的COUNTFLAG标志会置位;触发中断(前提是中断使能);
  如果外部晶振(即外接的晶振)位8Mhz,经过内部9分频;系统时钟则为72Mhz(cpu的时钟);SysTick的最高频率为9Mhz(cpu时钟的8分频);在这个条件下;如果设置SysTick值为9000;而SysTick是9Mhz;则能产生1ms的时间基;即SysTick产生1ms的中断;
  h  M6 }& X+ \5 u9 V* L
  SysTick相关的寄存器:
  CTRL:  SysTick控制和状态寄存器;
  LOAD:  SysTick重装载值寄存器;
  VAL:   SysTick当前寄存器;(重新写入的时候;会把状态寄存器的FLAG清零)
  CALIB:  SysTick校准值寄存器;
SysTick设置步骤:(使用ST的函数库使用Systick的方法)
  1、调用SysTick_CounterCmd()失能SysTick计数器;
  2、调用SysTick_ITConfig()失能SysTick中断;
  3、调用SysTick_CLKSourceConfig()设置SysTick时钟源;
  4、调用SysTick_SetReload() 设置SysTick重装载值;
  5、调用SysTick_ITConfig() 使能SysTick中断;
  6、调用SysTick_CounterCmd()  开启SysTick计数器;
. p8 C3 u. b2 k) N0 f: j
  1. /*Include---------------------------*/
    - M) |& W1 p% O- F, W
  2. #include"stm32f10x_lib.h"        //包含所有的头文件
    5 E* z( ?* h* s: O7 _; w& B; i
  3. #include<stdio.h>
    ; J( _( Y$ S) @5 q$ [
  4. % W+ h9 ]0 p0 g2 H
  5. //----------------函数声明--------------------
    8 n' b9 W! U( D" H( e
  6. void Delay_MS(u16 dly);( A9 C) y# r" i3 w2 _5 p" G
  7. void RCC_Configuration(void);# t+ h; K' A( \2 L( g
  8. void GPIO_Configuration(void);$ w/ l; T: y' s9 V9 ^1 l
  9. void USART3_Configuration(void);/ J9 e- C# k! t" C
  10. " [. E1 w9 o* n  H# J, G

  11. 7 Z& z) R4 a4 j3 ?' y9 y$ O" a
  12. u8 tab[] = "hello welcome to class !";
    $ j# N" Y8 U: v# _
  13. - t3 H- K; g+ X
  14. void SYSTICK_Configuration(void)
    - |2 @6 H2 p% w% v5 |% I
  15. {
    ! G# f4 u& \. v" P$ p
  16.     SysTick_CounterCmd(SysTick_Counter_Disable);
    $ k/ w3 h' o5 J: n
  17.     SysTick_ITConfig(DISABLE);: O0 @8 k9 q# X3 Z" x+ r3 [5 Z" o
  18.     SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
    * n7 {* ~  V9 `( ^
  19.     SysTick_SetReload(9000*1000);
    5 [: \; p% ~" T7 X6 F  t5 K8 w% a
  20.        SysTick_CounterCmd(SysTick_Counter_Enable);
    4 S2 T- T* }+ Z# b

  21. 9 R/ d1 d  f) P7 O
  22.     //*************打开systick时钟,但是由于systick时钟是默认开启的;' B* b& F; h+ z
  23.     1 m3 U' l4 B: P# U2 ^0 C
  24. }      7 U# o; S0 P6 I0 f* i0 j

  25. ! e# ?8 @& H. Z
  26. * ~! a. z$ z/ \4 A( c' s
  27. /*******************************************************************************' p3 T- l* O3 ~% O2 y* [
  28. * Function Name  : main' ~: D1 C" D0 v0 M: X' j& J
  29. * Description    : Main program.% l+ D% J- ]1 R% L( R; S$ m
  30. * Input          : None
    ) r: p  `& Q) K9 @  d1 `. ~( D1 p
  31. * Output         : None
    ( i3 D0 W1 Q" c8 J! B, x  n
  32. * Return         : None
    ( a4 t4 D4 H* p5 }1 ^: C9 \
  33. *******************************************************************************/
    8 g1 Z5 V7 u# J% ~
  34. int main(void)- P; @1 C9 c& ?4 [: ]3 M# t# d
  35. {8 c; t& a/ h* [6 Y: N
  36.     u8 min, sec;
    . y9 y: S& }2 Y! q% O9 J8 H! U6 ]5 b
  37.     #ifdef DEBUG
    ' p: N% u/ S+ P
  38.     debug();: j2 F* `9 B" H  ^/ `- b) D8 b
  39.     #endif$ B, K6 |7 `3 ?( o# c+ T& {
  40.     //------------初始化------------
    - {7 `8 I& _' E. q; j; C
  41.     RCC_Configuration();9 m: |5 J& w) I) _, a% }. U
  42.     GPIO_Configuration();      X2 Q0 E. o8 s
  43.     USART3_Configuration();% @" A7 ?( T" {5 ?3 D$ O
  44.     SYSTICK_Configuration();      0 r$ M2 H5 V( l, f+ V: }6 r

  45. # l/ i" K  b! X- |$ E, C
  46. //     id_num[0] = *((u8*)(0x1FFFF7E9));    //stm32芯片id的放置地址,96位id;12字节
    . R" I; j& a  P) u9 C% F
  47.      printf("hello world\n");! T) E6 c6 k. ~" \) w! ~
  48.     //------------将数据上传给上位机-----------; m# Z  n' ^! F2 h! Z; t
  49.     min = 1;6 B3 l- g% E- A* ?5 `9 ]
  50.     sec = 30;
    4 ~1 `1 z: n+ q8 l8 C  a
  51. 4 [) j2 S& Q! a. c, Z, D
  52.     while(1)
    & }5 q( f; _2 G% a
  53.     {; x$ i+ ~+ s) p% }  @% R
  54.         FlagStatus Status;; L! u) J" C! Z( C& [% [9 q
  55.         Status = SysTick_GetFlagStatus(SysTick_FLAG_COUNT);( ^0 ?& y7 `; K, K2 A& ^' Y5 q4 ^
  56.         if(Status == RESET)' Q8 w! C# P3 U$ P* ?
  57.         {/ |* ?9 t" {; [3 P. [0 W9 T) B! x
  58.             ;/ b; c, C6 U1 A4 K; M0 g" V
  59.         }+ D7 g5 I. J* R: x; V* D  x
  60.         else
    ; U. Y$ _" _' C/ }& J
  61.         {4 M- l' a2 i3 ~: A; r) Y# _) ^
  62.             sec++;
    + j8 }: s# @2 `' B
  63.             if(sec == 60)
    8 m& e, c1 g7 [& l' z+ q3 E4 w6 K
  64.             {
    2 b8 O" M; u3 U  ?' p7 X5 G) ?  D
  65.                 sec=0;1 S! r) m6 G7 v
  66.                 min++;
    1 ]( O. \$ Y1 U2 z9 s  I* I& ?4 V
  67.             }
    4 j5 e; E5 O5 c$ I
  68.             printf("\t\t%d:%d", min, sec);/ M& r. n/ U2 r; e
  69.         }
    - U! [4 k; [2 B. }. O+ e0 Q0 s/ \
  70.     }6 H6 e' z! q0 Z( `6 t
  71.         
      ~$ i+ e4 c( a
  72. }3 D5 V% @/ L! y5 }
  73. 9 T9 u! U0 m  r8 z
  74. /*******************************************************************************+ Q. B/ S( r  _# {3 D" M/ C
  75. * Function Name  : Delay_Ms
    8 o  J) Z5 _: O, I
  76. * Description    : delay 1 ms.& S& x. i# r/ R' \  E, u5 o) _! `
  77. * Input          : dly (ms)/ H2 Z" A* l+ |" M. M, B
  78. * Output         : None# Y. b- M! a- b  j2 u7 R: ?
  79. * Return         : None3 D& W7 r  m1 b0 w! b5 ~; Y# Y
  80. *******************************************************************************/
    , s' U# g; _/ `& z- u4 E
  81. void Delay_MS(u16 dly)
    5 _4 K% S4 O2 s- t: }3 r% o
  82. {1 K; z2 |  s3 H; y* F1 E# }; B2 R
  83.     u16 i,j;" {8 R" g& }# t: X- G
  84.     for(i=0;i<dly;i++)$ ^) [8 G# x# ?1 K9 X6 t7 ?
  85.         for(j=1000;j>0;j--);0 F, Y+ i- A, A- }" T( R
  86. }1 V1 }6 C! m! x" I+ X; F( h" E

  87. - y) G' s: X& D- M0 I3 \
  88. /*******************************************************************************. {/ Q' `6 K7 Q
  89. * Function Name  : RCC_Configuration
    8 `7 C! x# \; i6 b' ^! t
  90. * Description    : Configures the different system clocks.
    ! L% o4 x: Q- G
  91. * Input          : None. B" G5 P, `' r) [2 e
  92. * Output         : None% M- g+ `; t6 O  ]. ?7 |, |5 K+ K# B
  93. * Return         : None
    . m+ g6 W3 h; Y' t5 K
  94. *******************************************************************************/9 Q, R9 Y/ v/ D. c5 Z
  95. void RCC_Configuration(void)  f6 u1 o" u8 W
  96. {
    1 Z" p! [$ N7 }' V# _6 Y  C. R
  97.     //----------使用外部RC晶振-----------" O1 ~0 u  ]  _  v5 c) g
  98.     RCC_DeInit();            //初始化为缺省值
    - \# W# Q- e0 o  w% x5 I
  99.     RCC_HSEConfig(RCC_HSE_ON);    //使能外部的高速时钟 5 _2 I# L% m8 ^! a  s
  100.     while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);    //等待外部高速时钟使能就绪' h* Q; _& N8 X. z5 u3 w" a
  101.    
    ; o: l  z' r# q% v$ u
  102.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);    //Enable Prefetch Buffer
    - V0 K" D/ i+ J2 S, d/ @! v
  103.     FLASH_SetLatency(FLASH_Latency_2);        //Flash 2 wait state. i- U- J7 w% C( L/ S* ^
  104.    
    ; M( M/ i2 K% L3 H
  105.     RCC_HCLKConfig(RCC_SYSCLK_Div1);        //HCLK = SYSCLK
    ) Q0 R: j  s( t! i5 r- H& w
  106.     RCC_PCLK2Config(RCC_HCLK_Div1);            //PCLK2 =  HCLK) p) @4 z6 B2 j8 L
  107.     RCC_PCLK1Config(RCC_HCLK_Div2);            //PCLK1 = HCLK/2+ u6 ~5 F/ |1 l' x) u+ j
  108.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);    //PLLCLK = 8MHZ * 9 =72MHZ5 N7 ]: }7 U7 v- n" \
  109.     RCC_PLLCmd(ENABLE);            //Enable PLLCLK
    - l! b- D, S+ I1 i
  110. " o, W# X7 k0 J2 P  c8 W* T& |- `
  111.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);    //Wait till PLLCLK is ready
    $ [0 \+ S0 B3 _8 i
  112.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);    //Select PLL as system clock: z; [0 @& W6 n. a6 b- v% e
  113.     while(RCC_GetSYSCLKSource()!=0x08);        //Wait till PLL is used as system clock source
    ! q8 H/ |, v4 q6 d$ o) H" t
  114.    
    1 F& a7 v( V( p5 B9 e  R5 f
  115.     //---------打开相应外设时钟--------------------
    * N1 u! y' {9 q1 h& ~
  116.     RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);    //使能APB2外设的GPIOC的时钟
    + Z1 C. Q+ g3 ?
  117.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //复用功能时钟开启             , A1 G5 @2 f1 ], l1 M. H0 C1 i: X+ w* b4 d
  118. }: C# {# o0 [8 C4 W

  119. ; D0 X. Q: f" e' u2 @
  120. /*******************************************************************************
    ' C3 b6 I1 O" i' G8 I8 N  @
  121. * Function Name  : GPIO_Configuration* j6 j. A2 [0 A8 M) Y; o- I) ^
  122. * Description    : 初始化GPIO外设
    , C7 d3 u) K' g; u$ k# {
  123. * Input          : None
    6 W1 r+ c" B; _  E" y
  124. * Output         : None
    - A0 Y& u* q5 A2 }) H
  125. * Return         : None
    $ T% {. ]+ ~0 C: O7 @9 M) A
  126. *******************************************************************************/
    ( P6 Z. E" Q. f+ Q$ E
  127. //由电路图可知;配置PC10,PC11引脚# b0 X( ~! O+ d, k1 W% X
  128. void GPIO_Configuration(void)9 l) y5 Q0 j, _$ v6 ^7 K; @
  129. {
    9 d) a% A. h. n. F
  130.     //CLK:PB5  CLR:PE11 DATA:PE100 [2 |2 T% L2 o1 J- n- B' f5 E
  131.     GPIO_InitTypeDef    GPIO_InitStructure;        //声明一个结构体变量3 y9 S$ V, Z3 y& q) @3 X
  132.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;     //选择PB.1-
    * O( W3 U7 x- a1 [1 M% b  e
  133.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //管脚频率为50MHZ3 F( Y  N1 ^+ R8 r) }
  134.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //输出模式为 "复用推挽输出"
    8 |! h2 h1 G* z: [
  135.     GPIO_Init(GPIOC,&GPIO_InitStructure);                 //初始化GPIOB寄存器( S5 f( b8 U% `: V6 T- q
  136.    
    4 p: A; v5 M$ x: Y1 t7 c: Q# a" S
  137.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 |GPIO_Pin_11 ;     //选择PE.10 PE.11/ W( z# X/ n3 |" u
  138.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //管脚频率为50MHZ3 S2 ~+ j3 e9 m$ ]. z
  139.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;     //输出模式为    "浮空输入"
    * b0 h0 b+ t: s) t
  140.     GPIO_Init(GPIOC,&GPIO_InitStructure);                 //初始化GPIOE寄存器
    ) D8 l4 }+ f! g$ _
  141.    
    & J' D# r! X# l  }4 T" X
  142.     //开启时钟    必须在RCC_Configuration中设置    , g4 r; I4 Q. o! I, z; h
  143.    
    1 g6 ?" f* _1 {# j$ x; A4 {- ^
  144.     - M9 c. x; c. d
  145.     //端口重映射:PC10/PC11
    6 r- Q& S" r. S2 K+ T
  146.     GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);    / a8 u: A! I; z
  147. } + \& h  p/ e  u4 {. j: |8 d
  148. . b8 R% m  z8 X# j
  149. void USART3_Configuration(void)
    5 n! h8 O  z  f0 e/ c6 e8 {( {
  150. {( q' u6 h2 Q/ G6 L& [$ Q. t# D* Q; M
  151.     USART_InitTypeDef USART_InitStructure;. H* F1 S! g# E; x1 ?6 ]$ R
  152.     USART_InitStructure.USART_BaudRate = 9600;1 c$ ?6 B6 J8 z$ I, f
  153.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;2 o" ~. K0 ?5 ]. t) {8 }. b8 P2 t9 W
  154.     USART_InitStructure.USART_StopBits = USART_StopBits_1;: V! G* y+ i  B
  155.     USART_InitStructure.USART_Parity = USART_Parity_No;6 E) ?/ n$ p6 H: S5 Q
  156.     USART_InitStructure.USART_HardwareFlowControl =    USART_HardwareFlowControl_None;
    5 s* a/ V+ F5 r( N3 S# W
  157.     USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;3 @& W! ?1 A; i5 ]0 d- S

  158. & C, k. R- P4 v( _
  159.     USART_Init(USART3, &USART_InitStructure);
    - n0 X* W( X7 N/ K- C; u

  160. ' O7 x7 s4 \4 a0 ?
  161.     USART_Cmd(USART3, ENABLE);    //开启使能: v: h8 Z! Y) B9 v* k
  162. }1 C" C9 E% E' y* z; s

  163. 5 U1 q0 r& r9 \. A
  164. /***********************************************************9 Z" _- j7 h1 f4 F  d; e* Z: M
  165. name:    fputc                                               *4 s9 `( \$ U9 |
  166. Description:重定向这个c库printf函数,文件流--->串口USART  *
    1 t  ^( ^/ _7 S+ D
  167.                                                            *( O* d/ Z3 n: V* s) _# r5 g4 ~
  168. ************************************************************/4 Q! ?+ c9 ?% j6 O
  169. int fputc(int ch,FILE *f); L# j+ h* n3 X! @' V  i8 _2 M
  170. {' ?4 {  K7 e" g' P  m& ?2 K
  171.     //ch发送给USART1, p6 r* x! w/ {3 W3 r' t& g! i. P: U* p
  172.     USART_SendData(USART3, ch);
    / O7 g! c2 E) P
  173.     //等待发送完毕$ @* B2 u1 w8 a/ l
  174.     while(USART_GetFlagStatus(USART3, USART_FLAG_TC)==RESET)$ S: {! A+ N( o( i4 z) v' L
  175.         ;
    2 ^7 a' R. ^3 R5 K+ o# m3 z
  176.     return ch;
    8 _9 X$ S. d! ~" x) W. z
  177. }
复制代码
" p, c4 B* C! X: B; b% r
收藏 评论0 发布时间:2022-1-20 21:23

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版