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

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

/ [+ N/ J- H; {4 s" w1 G# s
  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计数器;

( }, n! t$ ]& `  r/ z8 \' `5 t+ X: y
  1. /*Include---------------------------*/
    & Y) }* W( S* e& T' a
  2. #include"stm32f10x_lib.h"        //包含所有的头文件0 {6 a" [0 g9 h& d" v
  3. #include<stdio.h>) F: t+ v) R- r, d4 A# e! J. t
  4. ' P+ w6 N3 A' P/ G/ I( `1 h
  5. //----------------函数声明--------------------
    7 i: k2 H! O5 V2 K% |
  6. void Delay_MS(u16 dly);
    " _% G/ L. V4 q
  7. void RCC_Configuration(void);1 \4 w+ |: O1 R/ q! X
  8. void GPIO_Configuration(void);
    ( N1 ~6 `& o' p, Y* p3 a
  9. void USART3_Configuration(void);
    ) A/ Y1 H, Y& h, g5 E9 q$ }
  10. 0 ^1 E! M+ }" r3 b! t* l

  11. 6 Y) w$ n# H3 |8 a! L
  12. u8 tab[] = "hello welcome to class !";
    - A4 }. _4 C8 F
  13. $ K3 \" E) k3 Y
  14. void SYSTICK_Configuration(void)
    7 c* u! _! b, V/ Y: i5 d
  15. {
    " g" T) B" \" P
  16.     SysTick_CounterCmd(SysTick_Counter_Disable);8 {$ n9 ^/ N* z. N7 B* c# m
  17.     SysTick_ITConfig(DISABLE);
    5 o) i8 T6 a3 G6 V, T. \/ a! O
  18.     SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);6 p( ?! j: v7 h4 u  z- c
  19.     SysTick_SetReload(9000*1000);, x- _. A: C) L2 b* i
  20.        SysTick_CounterCmd(SysTick_Counter_Enable);
    " A, X( D  a7 @: R$ e5 t( |

  21. * Q" u; ?0 Q3 q+ I2 _+ I) |
  22.     //*************打开systick时钟,但是由于systick时钟是默认开启的;/ U. ?8 v( w8 [1 {, ?/ `
  23.    
    - U3 `( a, }- [& j
  24. }      % g! G$ {3 X  u  t  P' ~0 {

  25. & G* y8 D' ~5 ^, g" [  [

  26. 4 G; Q; q) ]- h
  27. /*******************************************************************************& A; q3 M, y7 P6 H7 H
  28. * Function Name  : main& o$ l' x1 A) B0 m
  29. * Description    : Main program.
    3 R' @8 z2 f) v. k
  30. * Input          : None
    7 v7 z  Q$ ^- j1 r% a4 C  G* i
  31. * Output         : None
    9 H- d) a, J: [1 S0 s
  32. * Return         : None% e) g# l7 Z% x( E) a2 Z
  33. *******************************************************************************/
    1 Z! j9 N1 y' {! T9 S7 ]
  34. int main(void)
    0 S# ^) O4 G- p/ m6 @5 ]
  35. {8 k- k3 [  l9 Y) l
  36.     u8 min, sec;
    0 t. \/ R7 b' r$ {# u7 M4 C" ~) `
  37.     #ifdef DEBUG
    " x5 y0 |5 a4 G& k- G+ k9 x
  38.     debug();
    5 H& `; M/ z0 B) D- _, m
  39.     #endif2 G9 n& n4 m5 F" d0 r! C. j
  40.     //------------初始化------------
    4 W( ]2 f; H0 I& p
  41.     RCC_Configuration();9 ]" x& c4 M5 V* M4 `- ^" P, A1 L$ u; D
  42.     GPIO_Configuration();   
    $ D# i2 f' u6 a6 C. M% n
  43.     USART3_Configuration();/ a' K" f- O$ M6 T4 w% H8 H
  44.     SYSTICK_Configuration();      
    5 P; L# S& r. V) D
  45. & a/ N8 N; O  v7 }7 _
  46. //     id_num[0] = *((u8*)(0x1FFFF7E9));    //stm32芯片id的放置地址,96位id;12字节7 \9 }) c/ c9 a8 R6 a
  47.      printf("hello world\n");7 A8 `) P5 ^6 ?2 [. \5 L) r
  48.     //------------将数据上传给上位机-----------
    , @$ ^4 v9 g7 e6 @6 w1 ]6 |( a
  49.     min = 1;; _- [0 W4 L& W/ K5 b1 w4 m
  50.     sec = 30;
    + k8 V& x3 T6 e+ @9 ?3 N7 \, m6 \

  51. $ b( }; d" T1 O$ y% i
  52.     while(1)
    + U" V" [4 w! K7 r- E
  53.     {  ^8 ^; f* {/ I" E2 B7 Z1 S
  54.         FlagStatus Status;! X3 S1 |9 A. N2 c6 h, ]+ f
  55.         Status = SysTick_GetFlagStatus(SysTick_FLAG_COUNT);
    , ?5 ?, e5 `2 z# B& w% c& D6 `% Y
  56.         if(Status == RESET)
    $ G# y, x4 \- E% _% A+ M* l; `1 a1 ^
  57.         {
    & P( ~" N/ u- U6 Z
  58.             ;
    * ^/ d: k. \7 w+ G; U( z. h
  59.         }# }" {; k8 n* ]) M- R5 s) i5 {5 R
  60.         else
    * F# Z. p- I3 x$ `! c6 K
  61.         {
    % G* S, K5 p5 `: F2 b+ k
  62.             sec++;
    ) i* ]2 r0 N7 C) ^0 g  l4 f9 a% p
  63.             if(sec == 60)
    + J2 q: |9 G- H$ a, d$ ^2 }
  64.             {
    7 P9 |4 e7 H, D& q) ~3 K
  65.                 sec=0;
    7 H% Z5 l" @. M! e$ C
  66.                 min++;
    0 b7 H8 ]; v- ~7 w4 l+ q
  67.             }
    % V1 ?7 N" ^- @9 t# C1 a+ a( I/ }
  68.             printf("\t\t%d:%d", min, sec);" a6 U2 N# s  D# \6 G
  69.         }
    * Q. g2 C7 F1 @
  70.     }2 a3 u( V' O8 h
  71.         - p: F# M% ~& W; y& Y* f( h% [
  72. }
    . M2 N* S$ @/ S0 m+ l2 e+ M

  73. 1 ~0 X* B) p0 d
  74. /******************************************************************************** G/ U  W4 n" U2 K( [- U
  75. * Function Name  : Delay_Ms  J1 D2 r$ Q3 ^/ f
  76. * Description    : delay 1 ms.1 H$ R1 I3 d: T3 ?1 O' z0 a# r0 L
  77. * Input          : dly (ms)
    9 o3 a& i6 U1 h/ W( P
  78. * Output         : None" {# K0 J5 M9 B6 c. T2 i5 [. Z  \
  79. * Return         : None
    7 r" ], ~+ u9 n
  80. *******************************************************************************/9 C$ h( ^/ a) q8 T
  81. void Delay_MS(u16 dly)
    7 b4 f9 [& h" O+ b6 m! p6 g5 _
  82. {
    ' n8 \; s  w' s0 r2 D/ u/ _
  83.     u16 i,j;1 t* G8 y7 f! K+ l2 `
  84.     for(i=0;i<dly;i++)/ _# f; r8 _3 ^; W8 t
  85.         for(j=1000;j>0;j--);- W9 G4 k7 ?2 v* i% v  T9 N
  86. }7 b; {$ v) k4 Y' T1 P3 y) K3 @
  87. ( K- A5 A! C  e! z
  88. /*******************************************************************************
    7 i- u3 \" g& i' Q, ?  I
  89. * Function Name  : RCC_Configuration
    0 C: b6 S! }" U- E9 j0 e& t8 h
  90. * Description    : Configures the different system clocks.
    9 E6 u( e( Z1 `2 n+ f
  91. * Input          : None5 T2 i5 x4 X% G7 q8 S
  92. * Output         : None
    ' c" t. p! _- n( K/ B) F
  93. * Return         : None
    1 o# \' a4 l& J; E3 u4 b! @
  94. *******************************************************************************/
    2 w$ w4 ^) M+ [% }) h. `
  95. void RCC_Configuration(void)
    - q$ W8 l9 K% Y3 Y6 k
  96. {
    / K! ?9 m. s9 \/ K3 }
  97.     //----------使用外部RC晶振-----------7 ~+ g2 v9 @. [; `
  98.     RCC_DeInit();            //初始化为缺省值
    & k2 l2 [" @( Y8 O
  99.     RCC_HSEConfig(RCC_HSE_ON);    //使能外部的高速时钟
    9 {1 ?/ T+ H$ t. W* U  W% ?) J7 B
  100.     while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);    //等待外部高速时钟使能就绪/ J1 S/ j2 l( ]/ p4 i0 A' L
  101.    
    ) Z9 ~! i  f' m; K3 m
  102.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);    //Enable Prefetch Buffer
    3 M8 Z, p) D2 L9 Z
  103.     FLASH_SetLatency(FLASH_Latency_2);        //Flash 2 wait state
    ; G+ z6 l, n" u( a
  104.     6 ?/ q, V& M9 n8 X  J! L9 i4 @$ ^
  105.     RCC_HCLKConfig(RCC_SYSCLK_Div1);        //HCLK = SYSCLK
    & R/ O/ ?# L5 ?' W$ ^3 L
  106.     RCC_PCLK2Config(RCC_HCLK_Div1);            //PCLK2 =  HCLK# K& V! x8 T' g* H# E, {* H
  107.     RCC_PCLK1Config(RCC_HCLK_Div2);            //PCLK1 = HCLK/2
    6 a4 q3 z  u* l" U1 u0 R
  108.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);    //PLLCLK = 8MHZ * 9 =72MHZ
    # E% w0 O7 B. q5 I
  109.     RCC_PLLCmd(ENABLE);            //Enable PLLCLK
    9 B; a; y3 a) {% m+ F$ L

  110. " Z& I. c3 f/ s$ D) s: _$ `: X
  111.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);    //Wait till PLLCLK is ready
    # A) L( p7 m/ S8 J% `! ]
  112.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);    //Select PLL as system clock+ W/ H6 R( n1 ]: i7 E% ]7 ]
  113.     while(RCC_GetSYSCLKSource()!=0x08);        //Wait till PLL is used as system clock source
    ; s6 G* R( e% y, F5 v9 N) ~0 i2 u' a
  114.    
    $ x  G) O$ F  ]% y! d1 r0 x
  115.     //---------打开相应外设时钟--------------------
    . i% ~% M5 Q) n% ]) y; L
  116.     RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);    //使能APB2外设的GPIOC的时钟- G. n5 m8 _' w% b; D5 l/ V
  117.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); //复用功能时钟开启             3 B6 P0 n/ E% U
  118. }2 D+ _1 i% O* ~0 X# P0 M# U) r
  119. 1 h$ w; A. [8 d$ o
  120. /*******************************************************************************6 I- E% Q' w6 O- @
  121. * Function Name  : GPIO_Configuration& ^6 t# l6 `( ?2 e7 \3 H
  122. * Description    : 初始化GPIO外设
    * q8 R$ Q# K2 k; Z; ]# q5 \
  123. * Input          : None/ Q; Q! v* H& a
  124. * Output         : None  @: \4 ^4 m: M5 Q
  125. * Return         : None
    ; e4 \9 t4 G* b: v4 V" O# z) w
  126. *******************************************************************************/
    ! Q( \! x3 P! r- u! f# v
  127. //由电路图可知;配置PC10,PC11引脚4 N6 M* c! _' Y; V. R* x! A$ f! d
  128. void GPIO_Configuration(void)
    6 _, u4 d1 r2 E( ^
  129. {: m0 p6 e4 q' |+ |' v# s
  130.     //CLK:PB5  CLR:PE11 DATA:PE10
    / D" C/ ?$ e" l! e
  131.     GPIO_InitTypeDef    GPIO_InitStructure;        //声明一个结构体变量
    : E& H8 S* X) t7 n3 |, R
  132.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;     //选择PB.1-7 p$ e; ]) V5 a" l5 ~
  133.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //管脚频率为50MHZ
    3 b$ c+ q3 B+ M1 n. A8 S
  134.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //输出模式为 "复用推挽输出"
    2 t( P" m+ Q: c! y& R
  135.     GPIO_Init(GPIOC,&GPIO_InitStructure);                 //初始化GPIOB寄存器
    ; [  @+ q3 y' o$ S. L& `
  136.    
    6 `$ x6 `9 X3 V& `8 d
  137.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 |GPIO_Pin_11 ;     //选择PE.10 PE.11
    ( V$ k5 |( |* h3 M
  138.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //管脚频率为50MHZ
    , n# t; _8 \7 ?. s" Z" ~
  139.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;     //输出模式为    "浮空输入") `& a- G( c3 V
  140.     GPIO_Init(GPIOC,&GPIO_InitStructure);                 //初始化GPIOE寄存器
    6 N( t9 G/ x$ Y- q  v5 L/ D* W
  141.     ; d  }( \* M! V8 u# R
  142.     //开启时钟    必须在RCC_Configuration中设置   
    , p8 n- L4 D; K" I
  143.    
    % N+ f, c/ b, \  F7 C, ^
  144.    
    $ Q: L/ x: R7 i" w: Y5 R
  145.     //端口重映射:PC10/PC115 n9 `& J5 `/ H9 [% j$ |" D
  146.     GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);   
    , j! m$ t- _4 m  e& L9 A6 M6 x
  147. }
    - K( u/ ?& X! l' _

  148. ) S8 _* W4 ~1 Z0 s0 A
  149. void USART3_Configuration(void)  O* H, Y' G* Z& r
  150. {) U* x) l1 V7 _9 C4 d4 x( J
  151.     USART_InitTypeDef USART_InitStructure;. {1 k2 G" c  s! R& h% ]2 |6 f
  152.     USART_InitStructure.USART_BaudRate = 9600;+ K% N+ b! _) G* J0 ?
  153.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    7 I; \* S, Y, R' O9 p0 q- l' X
  154.     USART_InitStructure.USART_StopBits = USART_StopBits_1;6 b$ o/ `" R) G4 f+ Z2 F
  155.     USART_InitStructure.USART_Parity = USART_Parity_No;
    ( D/ Q9 C4 Z$ y* ]: z
  156.     USART_InitStructure.USART_HardwareFlowControl =    USART_HardwareFlowControl_None;* ~' K% i- }0 f
  157.     USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;3 v6 X: }8 }# M

  158. . G9 L/ v5 D, Y7 k6 t( q) Q% s
  159.     USART_Init(USART3, &USART_InitStructure);& B2 N2 p6 W( {
  160.   t- |* J3 c! ~1 {# y+ n2 T
  161.     USART_Cmd(USART3, ENABLE);    //开启使能* O8 @4 w3 a9 n
  162. }
    7 T3 O6 a7 k5 n
  163. / P5 f+ _; w5 o( Z% }. h
  164. /***********************************************************
    : l4 w& v6 s! W# J8 Q
  165. name:    fputc                                               *
    6 |3 w3 O3 T* _5 ?
  166. Description:重定向这个c库printf函数,文件流--->串口USART  *
    " ~8 Q2 G( g( l' {3 m
  167.                                                            *) t" P6 ~1 c2 l7 W; v, F, I& m3 f
  168. ************************************************************/
    8 s, |# X* |* x' h" o  u4 Y6 ]
  169. int fputc(int ch,FILE *f)1 r" s1 }0 U  X% P  r) `4 B# l
  170. {
    - G# m8 r% _; k9 Y2 ]
  171.     //ch发送给USART1
    9 `3 B) a# N8 L1 Q) z  t6 V
  172.     USART_SendData(USART3, ch);
    0 `1 n1 ^* V$ F; L% T( H- i1 f
  173.     //等待发送完毕
    ; c* ^( c: F/ W- r% ^3 r; I
  174.     while(USART_GetFlagStatus(USART3, USART_FLAG_TC)==RESET)2 z, j. O2 V) F" z
  175.         ;
    $ z, k) k# E/ K, J( |: M4 Z- \
  176.     return ch;
    ; l" r) ]4 L" y; M1 m3 F  I
  177. }
复制代码

0 m2 [# e6 L. H2 g  u& v2 D; w
赞 收藏 评论0 发布时间:2022-1-20 21:23

举报

0个回答

所属标签

相似技术帖

官网相关资源

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