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

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

' h4 n3 V0 D6 C  U) ]  ^
  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计数器;
1 k. q$ P  i* s( O' q
  1. /*Include---------------------------*/2 C1 ]- `+ I/ K/ [* ~0 c& M+ P
  2. #include"stm32f10x_lib.h"        //包含所有的头文件+ N! s. z5 ^) D+ p7 u+ x
  3. #include<stdio.h>
    4 I; M% U* Y( ]5 c  X  b
  4. % Q0 \: v& f8 Z4 ~) O
  5. //----------------函数声明--------------------1 h9 z5 `7 N, }# Z% p
  6. void Delay_MS(u16 dly);
    % x: v  o9 N- e( G/ D" Y# n$ }
  7. void RCC_Configuration(void);
      Q, p/ l6 L7 `. G1 s
  8. void GPIO_Configuration(void);! q) l2 l: C/ W6 j6 r( M& M
  9. void USART3_Configuration(void);
    2 I  S& a# `6 ^) k
  10. ' J9 `9 x$ n7 P9 m5 }6 x+ l

  11. $ a1 @/ z& y" R' ~5 b
  12. u8 tab[] = "hello welcome to class !";
    , c, p7 o( X9 H; U5 w

  13. ; p& H/ c( f# z1 [! m4 Y! s
  14. void SYSTICK_Configuration(void)( s+ {0 i6 N9 w7 t; g# ^
  15. {! R' _$ }) p# `( A
  16.     SysTick_CounterCmd(SysTick_Counter_Disable);
    & v. I1 q+ p+ a0 Q/ w* Y3 f; g
  17.     SysTick_ITConfig(DISABLE);
    + x! Z6 Z$ ^9 R+ G6 n7 ~( n
  18.     SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);5 S5 B- H/ r$ w% B. g" P
  19.     SysTick_SetReload(9000*1000);
    2 {8 P- t7 m& ^; u, I
  20.        SysTick_CounterCmd(SysTick_Counter_Enable);
    7 A& l: n0 A$ W  ?

  21. ; O4 ]$ |/ K( ]& j7 m
  22.     //*************打开systick时钟,但是由于systick时钟是默认开启的;- Z. l( b! _% M9 g4 l
  23.     . d! u2 E" |. o. O9 B, A
  24. }      % p2 Y/ k9 @3 U% O, Q0 k, K; M) ]

  25. & ~) R3 G( n; F5 X. K; A
  26. 9 t! Z: g9 A/ `% g
  27. /*******************************************************************************
    ( z/ e& Z% n$ {2 E% |& T
  28. * Function Name  : main8 F( l1 G6 o6 [5 U  V
  29. * Description    : Main program.
    8 W9 T% ^6 M+ I, a
  30. * Input          : None4 `& J$ p6 E; U8 h
  31. * Output         : None- |' ]% F* n  W' \
  32. * Return         : None9 I% y3 b; V7 w/ R! W: L( |( Q) b8 }3 R
  33. *******************************************************************************/ + v7 B' E" Q7 x4 ?
  34. int main(void)$ Y7 D+ t3 u3 i  z
  35. {1 A# r2 `+ b/ L. @0 y5 h
  36.     u8 min, sec;
    4 R; N) X2 p# w/ F+ A, G0 V
  37.     #ifdef DEBUG5 {' ^" }5 j/ w0 I& H
  38.     debug();  s0 R- a: W6 F- ~, b
  39.     #endif, J* X! R8 D) v! {
  40.     //------------初始化------------
    5 B1 X6 ~$ D5 r2 W
  41.     RCC_Configuration();8 X3 Z6 T( }& T
  42.     GPIO_Configuration();   
    " H: h8 R* {3 m2 H' f; }
  43.     USART3_Configuration();
    " g9 N" H5 Q( I$ M7 S' W
  44.     SYSTICK_Configuration();      
    ( z/ ^& N5 p9 L* i$ H6 j

  45. 1 r! E. P  b) O3 o- V
  46. //     id_num[0] = *((u8*)(0x1FFFF7E9));    //stm32芯片id的放置地址,96位id;12字节
    8 f' ]3 t1 v$ d: Y* S- x
  47.      printf("hello world\n");' _' w. _# G. B; D2 B) V" s, F2 Z0 f
  48.     //------------将数据上传给上位机-----------
    6 _. [4 a; X& E5 z6 H. v/ J2 Y' q
  49.     min = 1;/ f5 z# ]0 b2 a+ D- }9 J* |
  50.     sec = 30;
    # C/ \) R* P* o4 K1 c
  51. : H, j+ Z* v: D" [
  52.     while(1)
    9 ], {+ h/ x4 {: s" B
  53.     {
    0 m8 F- p! Z) F7 e; Z
  54.         FlagStatus Status;
    , Y+ L, U9 l* O
  55.         Status = SysTick_GetFlagStatus(SysTick_FLAG_COUNT);
    7 e5 |6 T# E3 Q9 G
  56.         if(Status == RESET)6 ~, w+ Z5 e, l' r* X2 f! i" Y
  57.         {% S' r" b" N9 `2 e
  58.             ;- w, b" x, _. D" f  `
  59.         }
    0 V3 u' l' Q8 P! n7 H
  60.         else
    ) [9 ?, Q, p* n! q0 B" \, @/ ^: z
  61.         {- b, Z3 }2 i3 k. \
  62.             sec++;- ^  h. Y6 y" P- ~/ I) ]
  63.             if(sec == 60)
    ; Y& m! W1 q6 |3 f2 {, A$ m
  64.             {
      c. u. ]+ j- r$ Y9 H
  65.                 sec=0;# B5 f8 a' u5 C) u5 ?
  66.                 min++;! x* M9 V4 A1 D# f
  67.             }, C" F8 i0 F. z7 I1 m% C$ f
  68.             printf("\t\t%d:%d", min, sec);- h( U2 z6 ]7 c$ n0 I+ D0 _
  69.         }6 _) x3 Z. f* x9 c) Y$ q1 ^
  70.     }
    * p- H/ `! }% a4 o+ ]( {. o
  71.         
    : S' a5 l! ]+ u+ l" N' o+ W
  72. }+ d) Q$ b% ^' Q$ J9 w" \
  73. 5 X, U5 p4 i# F! t
  74. /*******************************************************************************4 {1 @0 A  O' S! I3 ]
  75. * Function Name  : Delay_Ms
    - ]9 A$ g: `2 h6 R% t
  76. * Description    : delay 1 ms.
    8 Q3 X3 X7 R6 K
  77. * Input          : dly (ms)
    ' q' B  b; G4 v# \0 N
  78. * Output         : None' `) Q# y( Q; g
  79. * Return         : None
    6 j6 P3 N4 ?& c5 x: s: t; b
  80. *******************************************************************************/
    5 R1 R5 h, R/ J4 u
  81. void Delay_MS(u16 dly)9 {1 S3 E- l% v5 A
  82. {
    " a; o' g  d3 b( `6 c2 y  V# ^
  83.     u16 i,j;( p, |3 X2 _, Q) a7 x; X
  84.     for(i=0;i<dly;i++)
    * u+ Z) Q5 B& s" L
  85.         for(j=1000;j>0;j--);9 Y: p2 J+ p; h% L
  86. }: Y0 {. m: V6 u  \

  87. ( j7 i- R5 v8 X
  88. /*******************************************************************************& ?- O% t3 C8 }: h. V
  89. * Function Name  : RCC_Configuration6 c, }! Z% {6 T( t" `4 @0 P
  90. * Description    : Configures the different system clocks.
    ' s5 n% V  A7 S2 c3 [+ `" P
  91. * Input          : None& A4 k  d' s8 n' {1 |: ?' `9 W
  92. * Output         : None  H' g  h$ @+ L3 d
  93. * Return         : None7 v7 l! Z8 Z! D  |2 b
  94. *******************************************************************************/+ B0 {3 {1 M) a: D" |
  95. void RCC_Configuration(void)
    " W# |) h+ G$ l' W
  96. {2 [0 O7 ?: k2 d; ?! ~* w, E5 m' Q
  97.     //----------使用外部RC晶振-----------
    2 {" k2 W) T: X; t
  98.     RCC_DeInit();            //初始化为缺省值
    ! S) B6 |) Z" H* e4 O
  99.     RCC_HSEConfig(RCC_HSE_ON);    //使能外部的高速时钟
    , h* c8 Y6 \7 d7 e( v9 y/ `
  100.     while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);    //等待外部高速时钟使能就绪
    % C/ ^9 x  U! K0 x. ~1 X6 ]
  101.     ! U- @- J7 ~% q) @1 l
  102.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);    //Enable Prefetch Buffer
    - ^% Y( w0 j! }/ A9 u) W1 i5 g
  103.     FLASH_SetLatency(FLASH_Latency_2);        //Flash 2 wait state
    9 n/ l& i' W" Q, S: I7 W' t* _  c
  104.    
    & q6 |" i, Z) Z4 v" ~3 Z
  105.     RCC_HCLKConfig(RCC_SYSCLK_Div1);        //HCLK = SYSCLK9 X7 n2 c+ I9 |, v/ D9 O8 m) R
  106.     RCC_PCLK2Config(RCC_HCLK_Div1);            //PCLK2 =  HCLK
    ; `+ _+ |4 o$ `* A( b( q0 p
  107.     RCC_PCLK1Config(RCC_HCLK_Div2);            //PCLK1 = HCLK/21 Z- P" }7 G8 Z! o  @, Y# {' V
  108.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);    //PLLCLK = 8MHZ * 9 =72MHZ
    9 |. P. y4 A8 B2 ^" h5 y
  109.     RCC_PLLCmd(ENABLE);            //Enable PLLCLK
    ( v' n" m' K+ [! c
  110. ! O3 n" N' g; K! X5 J
  111.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);    //Wait till PLLCLK is ready
    9 N9 G2 D  Y5 I+ I$ I1 j
  112.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);    //Select PLL as system clock
    0 h+ O* a" N# q, A4 u
  113.     while(RCC_GetSYSCLKSource()!=0x08);        //Wait till PLL is used as system clock source
    # s: B  q6 C( O3 k
  114.    
    8 R$ R" Q6 y6 k  ?  ^+ l
  115.     //---------打开相应外设时钟--------------------/ `: j1 }6 M5 a* d3 s
  116.     RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);    //使能APB2外设的GPIOC的时钟( |8 h% P0 p8 f3 y  t& [
  117.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //复用功能时钟开启            
    6 t6 r+ T- \4 O% O* a# ~# r2 R+ F2 w  s# Y
  118. }  ]5 G% B# N8 q& A/ w

  119. * ?# A; |' q( O3 r% [1 U: C' h
  120. /*******************************************************************************
    - f0 _' Q5 J. c  a  Q
  121. * Function Name  : GPIO_Configuration- n4 C; b1 O2 o* j  f2 H+ e3 I% [
  122. * Description    : 初始化GPIO外设0 S. X- w/ Z7 F  Z' Z
  123. * Input          : None9 }! w8 k% ^, S  D) G
  124. * Output         : None3 D$ M; I) N! |
  125. * Return         : None
    & d9 W. E9 K" t! v
  126. *******************************************************************************/, d5 U7 {8 q' F7 r' r" t
  127. //由电路图可知;配置PC10,PC11引脚
    . U0 P" D: u6 q6 \0 J% u  r0 l) ^
  128. void GPIO_Configuration(void)$ g' S# Q" o$ C/ V! q  \
  129. {
    4 M7 _9 P& ?# {) G5 F5 A
  130.     //CLK:PB5  CLR:PE11 DATA:PE10* u, _0 ]& j% Z. D
  131.     GPIO_InitTypeDef    GPIO_InitStructure;        //声明一个结构体变量
    " z5 E" U1 c: e+ L  K! z
  132.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;     //选择PB.1-' s1 O! m& S' x4 f' q8 b& m9 f
  133.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //管脚频率为50MHZ' Q* k7 r2 v: ]: i: P- V$ W
  134.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //输出模式为 "复用推挽输出"
    ' ^9 n8 S9 f0 x
  135.     GPIO_Init(GPIOC,&GPIO_InitStructure);                 //初始化GPIOB寄存器
    , N" G/ N" K9 g# ]( W. X% H9 m9 k3 D
  136.     + B$ p( C5 L& l. M( j. W
  137.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 |GPIO_Pin_11 ;     //选择PE.10 PE.11- p: S' P7 E- n: O* d. r
  138.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //管脚频率为50MHZ
    ( ^) k% L: L4 u* U0 C
  139.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;     //输出模式为    "浮空输入"
    0 o# M/ U1 C. n
  140.     GPIO_Init(GPIOC,&GPIO_InitStructure);                 //初始化GPIOE寄存器
    " e; N7 ~+ v4 Z% F: L) Z: e- D
  141.    
    % r) `8 o' C0 G; y2 x+ ?, T
  142.     //开启时钟    必须在RCC_Configuration中设置   
    ; e# g- e' V$ i; ~" H0 X
  143.     * I: {; j; L6 k- j! G$ I# X
  144.    
    + `; c( B+ [# z. y6 p( B
  145.     //端口重映射:PC10/PC11
    & u. {1 w6 h1 V3 r' o; ]) o* m) |4 K
  146.     GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);   
    . Y! g) l, w' ~6 [3 b
  147. }
    & L. z# U: ^+ K1 ?$ \

  148. $ Q/ u& u4 L) j! l
  149. void USART3_Configuration(void): r) b8 `& f) _1 x; ~% p
  150. {
    0 J1 r! a3 f( P3 j2 A0 w
  151.     USART_InitTypeDef USART_InitStructure;
    5 m( M- U9 ~( i# I. |
  152.     USART_InitStructure.USART_BaudRate = 9600;4 _6 H) u4 h1 @8 n$ ]" b
  153.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
      r: `" F9 j) o. w' N
  154.     USART_InitStructure.USART_StopBits = USART_StopBits_1;
    6 d! \: t. U' v& V" r2 U
  155.     USART_InitStructure.USART_Parity = USART_Parity_No;
    + u, i# c6 u( U+ N( Y) P1 t
  156.     USART_InitStructure.USART_HardwareFlowControl =    USART_HardwareFlowControl_None;6 [4 _: {; P6 y9 T1 R& \1 z
  157.     USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    . G2 L9 x( h- G( l! _) b
  158. ( l: P0 p6 Z1 J; }9 _0 v8 ^& E/ ]6 x
  159.     USART_Init(USART3, &USART_InitStructure);4 x3 A- @! b9 c% Q

  160. 4 x8 H5 L, p) |( M
  161.     USART_Cmd(USART3, ENABLE);    //开启使能
    9 b# N. M* E& R5 |! [3 \0 Y  C
  162. }" p! w6 Y3 D+ G' c5 K
  163. 7 M  ^% C" v/ ?: s) j( ?$ ~
  164. /***********************************************************
    & r/ S8 w6 g! l3 b- C
  165. name:    fputc                                               *
    # v& L5 j1 F" ~) L: z
  166. Description:重定向这个c库printf函数,文件流--->串口USART  *
    ; U9 ~* j0 ?  Z! N4 B
  167.                                                            *
    ( u; D, x* ~6 b* l/ C
  168. ************************************************************/
    . A( m# t' _, A+ v
  169. int fputc(int ch,FILE *f)# D+ M7 l1 j: z: f) s
  170. {
    $ i% G9 \& q3 o3 x! G  |: ]
  171.     //ch发送给USART1
    ; Z  F/ s$ ?% g" C! b# @
  172.     USART_SendData(USART3, ch);
    # l0 s" Y; e$ ~# C  Z
  173.     //等待发送完毕8 @( {- I" x0 q+ j' ~; t! m
  174.     while(USART_GetFlagStatus(USART3, USART_FLAG_TC)==RESET)
    ) b/ a4 e$ a6 Z# q+ Q
  175.         ;
    # P9 G# X, ?' k, _' J+ J! H
  176.     return ch;6 z9 k  ]" e# J- j/ d8 g# q
  177. }
复制代码

* ~5 s3 o3 {: d5 Q
赞 收藏 评论0 发布时间:2022-1-20 21:23

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版