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

【经验分享】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的中断;

! y5 T* K' q- j- x& ]1 ]3 w
  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计数器;
6 Y: d5 N/ ~8 N$ U' F% U6 E  Y
  1. /*Include---------------------------*/
    ) i: ?5 z: B0 F# D- f; K
  2. #include"stm32f10x_lib.h"        //包含所有的头文件/ d) v$ y/ g" A3 ?- ^  ^
  3. #include<stdio.h>
    , C3 c; Z' L& m9 j1 a

  4. ( U- V* C: w5 J( \) y5 b' \+ u
  5. //----------------函数声明--------------------
    - y/ A- E1 e6 C8 w/ u
  6. void Delay_MS(u16 dly);
    2 n  Y5 R- [" Q" f
  7. void RCC_Configuration(void);. {* ^$ j# y$ l0 Q/ T
  8. void GPIO_Configuration(void);
    - i& W- |) z5 P- N7 [3 M2 ?
  9. void USART3_Configuration(void);; ?: G1 W1 G1 ~$ E! O
  10. ' Q* E& [4 f0 C5 P/ g( g! i
  11. . z' j" B# j! }9 `8 H
  12. u8 tab[] = "hello welcome to class !";6 [( `$ B5 ~+ z/ Y2 Z
  13. 3 z6 l% q) g/ G4 v! |
  14. void SYSTICK_Configuration(void)0 a, o5 V: }3 E) w+ z9 |, i7 M
  15. {
    * r7 u0 z/ ]+ L0 _! c7 T
  16.     SysTick_CounterCmd(SysTick_Counter_Disable);
      |+ f8 c# p% ~
  17.     SysTick_ITConfig(DISABLE);. p+ K' G( a. D( C! C
  18.     SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);/ ]: n4 C, [: u9 m
  19.     SysTick_SetReload(9000*1000);+ i4 n3 n9 I9 `6 I
  20.        SysTick_CounterCmd(SysTick_Counter_Enable);
    3 B+ h" y8 y0 j; b4 W  ~4 k
  21. 8 _- V: s% T( Y0 t( }
  22.     //*************打开systick时钟,但是由于systick时钟是默认开启的;
    ! I; a. _' d" k, K4 r
  23.     2 }, K1 q& [0 x- n1 N( c
  24. }      
    + y1 I2 P$ R- A; j2 Q( L- J
  25. 1 p3 t4 F; T# ^2 B* `1 n5 S! W! N
  26. 4 _) D  g% Y. g$ n5 t
  27. /*******************************************************************************
      M2 P" O% A" B0 z0 Q. R
  28. * Function Name  : main
    , |7 j4 l+ {: E9 p$ T5 x7 {5 ^" O: ^
  29. * Description    : Main program." N" H. W$ i/ D
  30. * Input          : None4 b( j9 S& B$ }3 y
  31. * Output         : None
    6 Q, `3 F& k- D  m2 M8 _! }- S- N
  32. * Return         : None9 c8 F, y# G/ ~( j2 H' P! A
  33. *******************************************************************************/ # c( A1 g, p- h* t  k
  34. int main(void)
    % a: ]& y- \  Z- v: O3 W
  35. {* {# e/ c, g$ [: ^% F
  36.     u8 min, sec;
    7 ]' W/ M2 q& c8 g; m- K0 C# |
  37.     #ifdef DEBUG
    ( i$ {3 p: t5 t( J4 O* i- P) c! b; n
  38.     debug();  x  l8 t* }- i
  39.     #endif/ o6 ^" Q% D5 w5 d+ {
  40.     //------------初始化------------- a+ N! ~& X( X- }) U
  41.     RCC_Configuration();1 Z$ N" }6 c9 }) _# o
  42.     GPIO_Configuration();   
    ' S" Y" B5 H5 k; E+ ?
  43.     USART3_Configuration();5 m. m: [" [) ]- E5 W- Z
  44.     SYSTICK_Configuration();      + l/ c. Q: K; p6 h
  45. ' @3 D3 @( [3 K5 V' E: e' Z
  46. //     id_num[0] = *((u8*)(0x1FFFF7E9));    //stm32芯片id的放置地址,96位id;12字节* O$ z  |' k! ?. l
  47.      printf("hello world\n");* i# F1 p& i- I: ]4 D: R
  48.     //------------将数据上传给上位机-----------
    + E/ I$ {7 V# ?+ v
  49.     min = 1;6 K3 f% p2 J. L! \* m; J1 Z; G3 D
  50.     sec = 30;
    6 J0 U5 f9 ^0 R7 d
  51. 3 A- S7 g! J/ X8 b% ], z( m: J; Y
  52.     while(1)
    , \% O' o7 g  A0 e2 r
  53.     {
    5 ?2 `. W: H. o- E" a3 I7 k: }
  54.         FlagStatus Status;
    8 S. Z  n5 S8 V9 g5 }7 e
  55.         Status = SysTick_GetFlagStatus(SysTick_FLAG_COUNT);3 q1 {: q) r. V. o& P5 ]. M
  56.         if(Status == RESET)! d' ^, g9 O  Z; }) U0 `8 b  p& l
  57.         {
    $ H  A3 c" L" d. C
  58.             ;
    ) A7 ?! n+ a6 f/ q) p) B; A" G
  59.         }% u$ E- y9 v$ H5 K( m4 W
  60.         else8 ]' n5 C8 g; h' i3 [' D0 o, }: Q
  61.         {. K. Q4 d' E# ~
  62.             sec++;
    9 F- P+ x0 }" U# }9 G4 ~& k
  63.             if(sec == 60)
    1 ^) }' J( `" R9 O" }
  64.             {
    + z$ f) K* ~( R2 q: k4 O- a' U
  65.                 sec=0;
    : }& m/ T! ?+ C( w4 c
  66.                 min++;
    $ K* g4 I6 p' v- o7 x
  67.             }
    ) }, S8 [; \6 i& i  |4 h/ M
  68.             printf("\t\t%d:%d", min, sec);
    $ h4 A, h! m2 S1 q
  69.         }
    , ^: y4 l& s% {9 e( a
  70.     }! t  G" T2 }4 B: v$ o
  71.         
    % n6 ]" m$ a+ m' w, }$ |
  72. }7 Y+ J7 c9 t9 e& z" J) N
  73. $ ^( v' D7 Q' n+ W4 a3 F& ~4 Q
  74. /*******************************************************************************
    6 H2 v6 e0 R/ @. X  \0 i
  75. * Function Name  : Delay_Ms( j  r/ h1 v* n( E# |; p. o  `
  76. * Description    : delay 1 ms.
    ! J2 M5 @) S& h  o
  77. * Input          : dly (ms)
    / }' @: s& x5 D# M. w
  78. * Output         : None
    ! \4 I9 w2 A) r4 Z7 L
  79. * Return         : None
    + c6 X) W+ V% `& b% `: {
  80. *******************************************************************************/- f8 r/ Q2 A1 B! _/ W
  81. void Delay_MS(u16 dly)% H) W- I# ^, w1 `- B  O" H
  82. {- S0 A2 X  D# L/ a
  83.     u16 i,j;8 W- X/ G; @/ A* H( w7 S1 \. w( B
  84.     for(i=0;i<dly;i++)
    ; Q, B5 R: i' }" z& F3 s8 r# C2 \3 F% w
  85.         for(j=1000;j>0;j--);7 {0 H5 f, W4 E0 n4 I+ l8 W4 A/ G6 G: J
  86. }. B6 o  J% j$ m- v( l& C. m

  87. - N+ r: B) C" F7 D& n, i) Q! y
  88. /*******************************************************************************( ]4 W% J2 m2 a5 C
  89. * Function Name  : RCC_Configuration3 l- W( ?% ?' q
  90. * Description    : Configures the different system clocks.* h% R' r# o& B) \5 x$ @
  91. * Input          : None
    6 P9 E! |7 ]7 M
  92. * Output         : None3 E& U1 V2 P1 i4 A
  93. * Return         : None
    # Z4 T' S) k( o! N4 i( [
  94. *******************************************************************************/' }, u2 I0 J/ W9 w% t2 I& q! @
  95. void RCC_Configuration(void)
    * W8 P% b, d$ Z8 |
  96. {6 R1 I8 s# J" g% p" }: H: Q
  97.     //----------使用外部RC晶振-----------) S7 s5 c2 |) q0 s$ O5 f
  98.     RCC_DeInit();            //初始化为缺省值
    ( ]$ h! t6 Q) [, j9 @1 e- N0 z  U- `
  99.     RCC_HSEConfig(RCC_HSE_ON);    //使能外部的高速时钟
    - W; r. S0 w) d
  100.     while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);    //等待外部高速时钟使能就绪
    ; K" |% S: C$ H. `. I" _
  101.     $ T3 [3 e0 H8 P9 R
  102.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);    //Enable Prefetch Buffer
    ( }: N7 Z( {8 G! U& y2 T, g5 j( H
  103.     FLASH_SetLatency(FLASH_Latency_2);        //Flash 2 wait state
    ' J! z  H4 Y6 E% U! y
  104.    
    / \& k5 F  {4 z. ?" A) I9 ?
  105.     RCC_HCLKConfig(RCC_SYSCLK_Div1);        //HCLK = SYSCLK
    7 k% j$ e3 R1 [. p" F3 {
  106.     RCC_PCLK2Config(RCC_HCLK_Div1);            //PCLK2 =  HCLK- Y* y% i* }- U/ ^- v. Y4 T
  107.     RCC_PCLK1Config(RCC_HCLK_Div2);            //PCLK1 = HCLK/2
    % z- I+ P2 V+ O" ?) j  J; w- A
  108.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);    //PLLCLK = 8MHZ * 9 =72MHZ
    5 d9 D; a! j8 r
  109.     RCC_PLLCmd(ENABLE);            //Enable PLLCLK6 J+ R2 c& N. g. }, M4 W- j1 V4 a4 H
  110. % j0 C, l; {# q0 A, h) f% j  b
  111.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);    //Wait till PLLCLK is ready" d- m- v. d! k0 E# |
  112.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);    //Select PLL as system clock. M, o: s& y, B
  113.     while(RCC_GetSYSCLKSource()!=0x08);        //Wait till PLL is used as system clock source3 d% `) l4 Y4 R0 |4 Z6 A, X
  114.    
    & `$ k' d, E6 t( W
  115.     //---------打开相应外设时钟--------------------
    # Z4 o% P. b7 g+ U4 @' Z, J6 k
  116.     RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);    //使能APB2外设的GPIOC的时钟
    2 t7 _9 {' f( N
  117.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //复用功能时钟开启            
    ! t5 O  b! t1 p1 b9 V
  118. }( e' w4 L; L5 O+ D

  119. : u$ Y5 Y9 C; y0 |) U8 K
  120. /*******************************************************************************
    5 L; M* o) x0 Y+ q/ y
  121. * Function Name  : GPIO_Configuration4 t; M- X) X( i; |
  122. * Description    : 初始化GPIO外设
    1 W: H3 U+ w5 x2 q1 J+ N
  123. * Input          : None3 Q! }/ M& f9 C- g; [- _1 Q
  124. * Output         : None
    * y3 l" a- Q9 a" o# v! j
  125. * Return         : None
    - J) ^: G* Y: a
  126. *******************************************************************************/
    / O) X& H0 u% M2 ~  x
  127. //由电路图可知;配置PC10,PC11引脚
    $ i1 w$ B: R/ a! M) w1 P1 N0 u
  128. void GPIO_Configuration(void)
    1 B! h% M: m) g% n: l
  129. {
    ) o. P- \0 g- l, ^9 L# ~" f& E. O
  130.     //CLK:PB5  CLR:PE11 DATA:PE10, I( S9 O! U, r( F" h+ [5 O
  131.     GPIO_InitTypeDef    GPIO_InitStructure;        //声明一个结构体变量
    . j" Z* w+ h( E+ }
  132.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;     //选择PB.1-
    . _0 I+ v4 I: c; S
  133.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //管脚频率为50MHZ+ i# e/ G% Z" Y# s7 `
  134.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //输出模式为 "复用推挽输出"
    - p5 i0 R% a/ \! F6 o  D
  135.     GPIO_Init(GPIOC,&GPIO_InitStructure);                 //初始化GPIOB寄存器
    * j/ ^- {3 B% W2 t$ R
  136.    
    - A) A( ]% C" K( S8 a& }! ~& b
  137.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 |GPIO_Pin_11 ;     //选择PE.10 PE.11- }% u! i7 U- A) f# ]
  138.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //管脚频率为50MHZ; T' Y* t" n. s* }* J$ h& l9 l
  139.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;     //输出模式为    "浮空输入"
    2 N0 W  [( ?! m
  140.     GPIO_Init(GPIOC,&GPIO_InitStructure);                 //初始化GPIOE寄存器
    0 A# x2 J+ }) H0 T4 d
  141.     6 Z  X: I, ]$ Z/ c
  142.     //开启时钟    必须在RCC_Configuration中设置    % t" n3 U; G* C2 F) g
  143.     ! [" I- ]; s# h9 \# Z3 @, Y4 Z
  144.     5 T, C7 ?" A  e) i8 I( z+ f# y
  145.     //端口重映射:PC10/PC11
    - u) \4 D3 p' Z3 R6 l  K  @
  146.     GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);    ; ]+ o2 I' [6 d0 |8 K
  147. }
    ) @& Q# Z5 I( y3 V" }9 q& Z; R

  148. : y" E; l3 e/ c6 \% A" P+ a
  149. void USART3_Configuration(void)4 n3 `- |: W* Q5 i' ^
  150. {9 N6 }. M! u0 k' n! U
  151.     USART_InitTypeDef USART_InitStructure;0 [! ]# q: E/ |2 s3 s2 y+ `
  152.     USART_InitStructure.USART_BaudRate = 9600;9 J/ F8 V5 [& }+ I: u
  153.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
      u1 O- z5 q; {" B. u
  154.     USART_InitStructure.USART_StopBits = USART_StopBits_1;1 U2 ?8 `4 n, O7 M' w! k
  155.     USART_InitStructure.USART_Parity = USART_Parity_No;5 R" I4 Z7 D4 A/ i7 S: f, P) C
  156.     USART_InitStructure.USART_HardwareFlowControl =    USART_HardwareFlowControl_None;( u- b/ e7 b4 f2 J+ B  b4 R
  157.     USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    / a0 O4 g; F- u, F2 o- U# B
  158. 7 P6 T. s9 B5 F- A1 E
  159.     USART_Init(USART3, &USART_InitStructure);0 |6 S3 W2 t- y& D! M& U
  160. ' Y1 v/ P$ ^: X
  161.     USART_Cmd(USART3, ENABLE);    //开启使能
    0 o. z: H# f, |8 F% L- |. h
  162. }
    & T& `4 n+ K" I: V7 E7 I, b. s

  163. 6 X0 i4 i9 \0 Z/ P6 G) q. E/ ~# ?
  164. /***********************************************************/ r& z% F" J! O/ p8 v
  165. name:    fputc                                               *
    7 f+ y5 V2 E7 r% }3 v
  166. Description:重定向这个c库printf函数,文件流--->串口USART  *. C" x& R  d' v6 v8 H: W9 b6 v6 F, C
  167.                                                            *6 G1 b$ O1 A' p+ Z
  168. ************************************************************/
    ( D+ t# }2 `) N
  169. int fputc(int ch,FILE *f)2 _$ S2 [$ p& k7 h" W% _
  170. {
    ) n: P) a. K# W' |4 J7 W7 P
  171.     //ch发送给USART16 z* S4 h0 g3 c9 X
  172.     USART_SendData(USART3, ch);: N7 A9 [; k' c' F( j! u
  173.     //等待发送完毕
    5 ^! o# A1 E7 n' _/ o# L; W, `2 J
  174.     while(USART_GetFlagStatus(USART3, USART_FLAG_TC)==RESET)
    - q: E3 e; C9 l% z% O) e# |: p, Y0 H, k
  175.         ;
    ! l( h! b8 H# v! |5 F' B: [. F
  176.     return ch;/ L# S! w- r; V8 |! t
  177. }
复制代码
. A! v9 Y& J/ q4 ^3 ~/ _: L2 A
收藏 评论0 发布时间:2022-1-20 21:23

举报

0个回答

所属标签

相似分享

官网相关资源

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