谷动谷力

 找回密码
 立即注册
查看: 10880|回复: 5
收起左侧

STM32F103RCT6开发板M3单片机教程05--RCC配置

[复制链接]
发表于 2021-11-10 23:07:23 | 显示全部楼层 |阅读模式
STM32F103RCT6开发板M3单片机教程05--RCC配置
. X6 D3 m* H* x0 O8 e3 N! E& E" ]/ K
( D  h6 Z7 w+ w5 K9 z3 ]6 F1 L. K* b  h1 C% t5 t( L
前言, k1 ^3 a/ \# ^1 C5 B. K
首先了解一下是什么RCC(Reset Clock Control),复位和时钟控制(RCC)% v1 K8 w5 K7 p/ \
小容量产品是指闪存存储器容量在16K32K字节之间的STM32F101xxSTM32F102xxSTM32F103xx微控制器。
. Y. h8 f+ ^6 E- X- h. s$ F% \中容量产品是指闪存存储器容量在
64K128K字节之间的STM32F101xxSTM32F102xxSTM32F103xx微控制器。
; i& ^) [' \, |, \& r1 `% j* g大容量产品是指闪存存储器容量在
256K512K字节之间的STM32F101xxSTM32F103xx微控制器。5 r) U  V6 z1 V& c
除非特别说明,本章节描述的模块应用于整个
STM32F103xx微控制器系列,因为我们使用是STM32F103RCT6开发板是mini最小系统板。
9 L8 z0 r$ {8 L4 e4 }5 [本教程使用是(光明谷SUN_STM32mini开发板8 `2 z1 d( C$ u2 @2 R
212247mr8ksgib4e2u4uhy.jpg / j1 E2 \6 B) S, m" s) z  D# O
4 {2 [5 [/ x- n) R! S
一、复位" ^5 t! H  [, P
STM32F10xxx支持三种复位形式,分别为系统复位、上电复位和备份区域复位。
9 O$ T/ N( Y& x" y' Z. C
* L6 T( r1 d# `* R* J* X, j) J

4 H: c9 L" U( g2 d% V1.1 系统复位$ d7 k- B$ v/ F. _& q6 E6 _* w
系统复位将复位除时钟控制寄存器CSR中的复位标志和备份区域中的寄存器以外的所有寄存器6 T4 G+ {$ S( C" q, X$ s
, u' g; b/ O& b9 C
当以下事件中的一件发生时,产生一个系统复位:
& S$ `0 z: X8 ^
1. NRST管脚上的低电平(外部复位); O2 N  Z+ y& \/ I3 M! ^$ z( k
2. 窗口看门狗计数终止(WWDG复位)$ m3 B) j% R6 M6 H, f
3. 独立看门狗计数终止(IWDG复位)
# k; y9 ]6 Y0 Z% C' U2 k. k" P+ K4. 软件复位(SW复位)0 R1 U3 Y. R# Q7 }3 [1 P; M
5. 低功耗管理复位6 U& z: T+ A1 |. }5 x4 a* I
可通过查看
RCC_CSR控制状态寄存器中的复位状态标志位识别复位事件来源。
& ]2 m. _# U9 _2 I8 G$ V& y3 m
软件复位) B" z% F) k% H  m% r1 D9 \
通过将Cortex™-M3中断应用和复位控制寄存器中的SYSRESETREQ位置’1’,可实现软件复位。请参考Cortex™-M3技术参考手册获得进一步信息。( b8 e$ n' W# K6 B9 T9 n
低功耗管理复位" E, b1 ^" v. ?% r
在以下两种情况下可产生低功耗管理复位:
3 K/ p) e; x: r
1. 在进入待机模式时产生低功耗管理复位:
6 D* l5 [" _: i; N2 `* m2 L% y+ ?通过将用户选择字节中的
nRST_STDBY位置’1’将使能该复位。这时,即使执行了进入待机模式的过程,系统将被复位而不是进入待机模式。! h: `, {# x8 {" r; m
2. 在进入停止模式时产生低功耗管理复位:
5 ]/ O. o" ?: `6 n通过将用户选择字节中的
nRST_STOP位置’1’将使能该复位。这时,即使执行了进入停机模式的过程,系统将被复位而不是进入停机模式。$ v  Q# d' _* ~8 e
关于用户选择字节的进一步信息,请参考
STM32F10xxx闪存编程手册。8 S% g9 r! a( U
0 V3 D2 C8 n' ^4 h! }0 I- F8 X" O
1.2 电源复位
0 n$ k* _( f% }当以下事件中之一发生时,产生电源复位:
; u# I2 B7 p+ g! G
1. 上电/掉电复位(POR/PDR复位)* q/ e8 _3 l1 D6 \0 g* T4 z
2. 从待机模式中返回8 y; R5 E4 t& I4 O; T. P
电源复位将复位除了备份区域外的所有寄存器。
(见图3)5 M, ?6 ?9 {7 T, }
图中复位源将最终作用于RESET管脚,并在复位过程中保持低电平。复位入口矢量被固定在地/ J# H  J1 @0 p6 p1 W
0x0000_0004。更多细节,参阅stm32f10xxx参考手册表36 4 a4 F# |' A8 K* e2 Y; D

" P1 ], v, j0 t# O8 x  s STm32Rest.JPG
1 s% K, I! ^) G, v: k4 K
% \5 x0 T6 @9 n  P6 d7 V, v1.3 备份域复位3 ^! Q5 D9 o9 R# h* B& L
当以下事件中之一发生时,产生备份区域复位。& Z: w# @8 H8 A, T$ U; e
1. 软件复位,备份区域复位可由设置备份区域控制寄存器RCC_BDCR中的BDRST位产生。
! }$ T" I9 ?( _# }
2. VDDVBAT两者掉电的前提下, VDDVBAT上电将引发备份区域复位。
7 o$ C: S. O/ t* B4 M3 [, S  f
6 Z0 b* ]* p% e( m4 u4 f

$ h2 M5 c& b) H9 a7 |. r% w二、 时钟8 [/ ]4 @' R$ K. Z

4 H4 T% L, R6 Q! ]) M4 M三种不同的时钟源可被用来驱动系统时钟(SYSCLK), ~. w/ }: g2 u- n; s) [0 ^
HSI振荡器时钟, J2 ^8 B4 Q0 I8 |1 B+ g
HSE振荡器时钟, ]) U5 J, R# Q. V- ?
PLL时钟
9 L0 D9 K7 b7 A/ X) O* H$ S- H: _这些设备有以下
2种二级时钟源:
( a. y0 X6 s8 J: S( z$ _
40kHz低速内部RC,可以用于驱动独立看门狗和通过程序选择驱动RTCRTC用于从停机/待机模式下自动唤醒系统。! `, I9 V2 @! P" e

0 l4 b7 O$ J4 I% k32.768kHz低速外部晶体也可用来通过程序选择驱动RTC(RTCCLK)' r7 r) p) B- L+ K6 k0 Z( F! t
当不被使用时,任一个时钟源都可被独立地启动或关闭,由此优化系统功耗。
8 u' @3 W7 H1 U3 X
复位和时钟控制 STM32F10xxx参考手 " q0 d) t- [5 Z9 n3 _5 ^( }
1.3 备份域复位
( ^& J) ?( w) q3 b当以下事件中之一发生时,产生备份区域复位。
! c0 h) R% D  s  v" X
1. 软件复位,备份区域复位可由设置备份区域控制寄存器RCC_BDCR中的BDRST位产生。
8 a2 o0 b- b# G6 ^
2. VDDVBAT两者掉电的前提下, VDDVBAT上电将引发备份区域复位。) ?/ q9 }! |% a- A6 Y
$ |. B# e( |9 E
stm32_clocktree.JPG 2 S; g+ u' s  I2 j9 l) X6 t
更多细节,参阅 STM32F10xxx参考手册
) G2 ~# Q4 @. ]7 P1 }* R [size=14.6667px]  e- P# x8 u2 b& D& m3 I
RCC设置流程: 
  1、将RCC寄存器重新设置为默认值    RCC_DeInit
  2、打开外部高速时钟晶振HSE      RCC_HSEConfig(RCC_HSE_ON)
  3、等待外部高速时钟晶振工作      HSEStartUpStatus = RCC_WaitForHSEStartUp();
  4、设置AHB时钟            RCC_HCLKConfig
  5、设置高速APB时钟          RCC_PCLK2Config
  6、设置低速APB时钟          RCC_PCLK1Config
  7、设置PLL              RCC_PLLConfig
  8、打开PLL              RCC_PLLCmd(ENABLE)
  9、等待PLL工作            while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
  10、设置系统时钟           RCC_SYSCLOCKConfig
  11、判断是否PLL是系统时钟      while(RCC_GetSYSCLKSource()!=0x08)
  12、打开要使用的外设时钟      RCC_APB2PerphClockCmd()/RCC_APB1PeriphClockCmd()

$ q$ t. J4 c. V) w了解基础知识下面实操吧
5 ]. Y. c9 _4 L3 N" d以前我们其实也有配置,但不具体,基本都本MCU默认的配置,真正用好STM32,还得熟悉RCC.
& \! L5 }8 g; i7 Y0 n, }+ `3 c; ?: j' Z3 |. {9 z5 G4 N; m/ Q$ |7 b1 I
程序编码3 i7 n: q# J9 q% h
: ~. z# @4 m+ G8 ?; k
8 k3 q2 K7 t- l" Y3 F
复制上节工程文件夹打开(这个方法比较方便)
- s+ W0 o7 D5 Z& Z, f/ {
  • 码字:编辑main.c, 在上节基础上增加RCC配置函数。
    1. /**********************************************************************************' u6 f; K( r: O+ |. g; O  ?* L
    2. * Sun STM32 mini Demo
      : b/ l8 a' S2 q% j

    3. % l! _; M# f1 u- k7 |
    4. *   Description( v! t7 _; A. O
    5.    
      - Y) _( D6 |. d; r7 o2 T3 e; s
    6.     RCC Config Demo; |  l  r  Z% x- I5 A

    7. 9 r) q% q( F  f& y8 M9 @
    8.    
      7 ~# i: M! @. e5 r2 J
    9. * Version    Date       Auther      Reversed History1 q) P( ]' R- t, F
    10.   ----------------------------------------------------------------------------
      ! m- J* c& ~$ f9 c
    11.   V1.0.0    2021-11-07  Lojam Fan  Fisrt Created * V2 J; N% h3 i9 f0 x% u$ x6 M. L
    12.   
      ' q3 ?6 B, r! x$ n4 _: d
    13. * (C) Sunshine Silicon Corporation
      , `* R" r# c# C7 `% w2 j, m
    14. *  Website: http://www.sunsili.com  http://sunsili.taobao.com http://bbs.sunsili.com1 f4 D* y2 w$ Y' \# u% B
    15. *  E-Mail : fan@sunsili.com* y& S7 I- ~4 E$ |
    16. ( v! x9 @5 o. C: y. b9 n5 X
    17. **********************************************************************************/  n# B% L; ?* h  k- r; X

    18. % P, x6 H  P& U1 n" m7 W. u( r. h
    19. #include "stm32f10x.h", L8 [) {9 z+ n/ c; [! q6 A; l
    20. #include "usart.h"( n& v  [5 H5 o% K1 M8 y
    21. #include "SysTick.h"
      . N& |* Y1 M$ U9 C  s1 @
    22. #include "led.h". P( q7 v9 G! ^  O
    23. #include "key.h"
      , X, ^1 c3 v/ I' {5 @  U7 @
    24. #include <stdio.h>
      ! n6 U, F  g0 U; |  {, a8 f

    25. , g6 l: K5 b8 a
    26. 9 u9 B" D7 G4 q5 Y
    27. extern vu8 Usart1_R_Buff[USART1_REC_MAXLEN];        //串口1数据接收缓冲区
      - ]. u+ Q) r- k4 R6 ]6 r; @
    28. extern vu8 Usart1_R_State;                                                //串口1接收状态. n* f$ b1 f1 s* Q
    29. extern vu16 Usart1_R_Count;                                                //当前接收数据的字节数         
      * r4 H* }' D- }( t, P

    30. ; l% `9 Q3 m0 J1 n: Z
    31. void RCC_Configuration(void);
      ( Y1 K* Q  t4 A' r4 w% b) y, a" K2 b
    32. : M4 J1 E  p6 C# L
    33. /*******************************************************************************
      ' {" P$ q" R# @, T; R9 M
    34. * 函数名  : main
      9 S& o* T5 R# p
    35. * 描述    : 主函数,用户程序从main函数开始运行! I& b# g3 Q  O/ h* q+ u: A
    36. * 输入    : 无
      " L2 F, o* l7 T- T0 W9 r5 |
    37. * 输出    : 无
      2 K. B2 l5 ^6 h0 f, R0 H1 o
    38. * 返回值  : int:返回值为一个16位整形数
      ' \4 U. B6 i( G0 d' I: p% X
    39. * 说明    : 无+ u3 O2 m7 v1 L6 n; y
    40. *******************************************************************************/  T$ v' y9 X! U2 a- _  ^
    41. int main(void)
      , x1 }9 \1 [9 h1 |9 a+ T
    42. {; ^' k( b1 @5 ^
    43.     u8 keyVal;
      2 [6 Q2 c6 F$ K( l( f6 W% F
    44.     RCC_Configuration();6 v, ~; v6 F3 \4 u1 k
    45.     SysTick_Init_Config();
      $ I0 r3 j* u$ q8 g0 Q
    46.         USART1_Init_Config(115200);//USART1初始化配置
      / w2 z6 A- D- y7 G4 Z/ S
    47.     LED_GPIO_Config();# F$ r) [. k6 e/ i' k
    48.     Key_GPIO_Config();
      + N- ?' a, g- ^6 m5 h2 t
    49.     printf ("*===================================================*\n");- @3 G) \( a: y
    50.     printf ("*  *  Name: Sun STM32 mini Demo Code.    *************\n");
      ! \5 l  |0 Z/ p6 U8 ^
    51.     printf ("*  * (C) Sunshine Silicon Corporation    *************\n");
      5 J- h% m: _8 h  W2 f& t, U8 w1 W
    52.     printf ("*  *  Website: http://www.sunsili.com    *************\n");
      # R6 P* \0 q2 u
    53.     printf ("*  *   E-Mail : fan@sunsili.com          *************\n");( s4 o  s) q/ \! u
    54.     printf ("*===================================================*\n");) W& |) z0 i9 [
    55.     printf ("* Sun STM32 mini Key Demo code .*\n");
      / A( v$ h( S$ t8 {1 L
    56.       s) n& [% s' h, a2 S1 O
    57.         while (1)
      + a) @" M& N; _! v( N
    58.         {* ^( F9 o: U/ `! n2 J7 l$ E
    59.         keyVal = Key_Down_Scan();( T  C* R+ W# ?! ^7 p
    60.                 if(Usart1_R_State == 1)//一帧数据接收完成
      2 b- d: |# M$ y' H5 J/ H  I
    61.                 {
        }& N2 X1 b5 M
    62.                         USART1_SendData((u8 *)Usart1_R_Buff, Usart1_R_Count);   //USART1发送数据缓冲区数据(发送刚接收完成的一帧数据)
      0 I. C2 o- r& V( t( @6 D/ b
    63.                         Usart1_R_State =0;
      $ i& ?- W6 z2 t" l5 r" l
    64.                         Usart1_R_Count =0;
      0 d: L# i  Z& w" X3 B3 J' Y& q
    65.                 }( @# d+ m1 ~, ^3 B/ ]
    66.         if(keyVal)
      8 y+ {; J+ r3 P! }, C3 z
    67.         {7 k; ?6 }: O( e% G8 u
    68.             printf("KeyVal:%d\r", keyVal);+ ?9 X* L6 M1 {2 r
    69.             if(keyVal & 0x01) LED3_ON();              W1 X8 f1 t8 y. j' _$ i
    70.             else if(keyVal & 0x02) LED4_ON();            
      0 H* h: s3 s+ f" q- P1 X
    71.         }9 i/ G, D+ l8 _, |
    72.         else LED_ALL_OFF();+ ]1 j4 T. \+ ]% A5 e* K! V4 E; ~
    73.         }
      1 D2 E2 u' @4 t6 q
    74. }
      0 r5 U9 c9 s$ W& Y* H( G( q
    75. ' {4 ?( W, b! S" {

    76. 9 i+ x; o* s2 j% C) \) M
    77. /*******************************************************************************
      / q) s5 s, l5 p. C) ]
    78. * 函数名  : RCC_Configuration* f/ n, J4 N: {
    79. * 描述    : 设置系统时钟为72MHZ(这个可以根据需要改)
      5 h" O% ]  N1 ~: ~5 Q- M( w. g
    80. * 输入    : 无
      9 Y* X$ p# h2 s6 @
    81. * 输出    : 无
      . R; j5 E2 ?  S( Y8 z6 ~; i
    82. * 返回值  : 无
      6 u0 N1 i( ^& d3 }5 g
    83. * 说明    : STM32F107x和STM32F105x系列MCU与STM32F103x系列MCU时钟配置有所不同* k! j3 t" Q! c* {' Y
    84. *******************************************************************************/- `' t+ x! V4 f
    85. void RCC_Configuration(void)$ D5 P, N" H% @7 K! q
    86. {
      : G. y+ q# _1 e2 o- O) b, `
    87.   ErrorStatus HSEStartUpStatus;               //外部高速时钟(HSE)的工作状态变量
      8 F; p+ e* O1 ~
    88.   7 ^' ]- z3 _1 f  g
    89.   RCC_DeInit();                               //将所有与时钟相关的寄存器设置为默认值. f. `0 ^5 T$ ~' i6 X9 M8 o
    90.   RCC_HSEConfig(RCC_HSE_ON);                  //启动外部高速时钟HSE 0 \4 u2 M8 ^" ]' x
    91.   HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速时钟(HSE)稳定1 n( _2 M; {! X1 K
    92. 2 _& u( o; G  l! q7 k% p
    93.   if(SUCCESS == HSEStartUpStatus)             //如果外部高速时钟已经稳定6 t- a! R& r4 C3 K2 L+ _( n# K
    94.   {
      6 o4 V5 |8 N8 X$ T
    95.     /* Enable Prefetch Buffer */
      * @* c  Y% w3 \5 P6 @3 o
    96.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Flash设置
      ! q# W  O# ]: {  w' @9 X; \
    97.     /* Flash 2 wait state */
      % }9 N6 B" v5 V3 h
    98.     FLASH_SetLatency(FLASH_Latency_2);
      $ j$ i) \$ Z) W
    99.     ( I- x0 U9 p* T# C* ^
    100.     t  R* L. O" p5 n5 m* \
    101.     RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置AHB时钟等于系统时钟(1分频)/72MHZ+ a) |, L9 t4 x' L+ z  {( o6 J* {
    102.     RCC_PCLK2Config(RCC_HCLK_Div1);  //设置APB2时钟和HCLK时钟相等/72MHz(最大为72MHz)
      ! O6 I5 ~+ i& @9 b( M
    103.     RCC_PCLK1Config(RCC_HCLK_Div2);  //设置APB1时钟是HCLK时钟的2分频/36MHz(最大为36MHz)
      & ?# Q2 a( V4 A2 \9 J6 c3 j# @5 r
    104.     - m8 h/ X$ F8 h$ [6 B
    105.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK = 8MHz * 9 = 72 MHz " J& I, O0 C2 }, g2 I1 a2 Z
    106. ! u3 f; s( [' M: d7 s
    107. + |* l6 h% ?8 T. K7 [. n% T
    108.     RCC_PLLCmd(ENABLE); //使能PLL
      # o& @$ q5 ]: w0 L2 T- Q
    109.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //等待PLL稳定
      . v+ g2 E; e2 {" ?
    110. , ~0 S# l. }, j" t$ h
    111.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);          //设置系统时钟的时钟源为PLL
      4 Y! V) f% ^7 _, v7 D, E
    112. 2 I% F0 I1 O) I1 B& J2 p" c* }
    113.     while(RCC_GetSYSCLKSource() != 0x08);               //检查系统的时钟源是否是PLL
      & F! E8 a- Q# W
    114.     RCC_ClockSecuritySystemCmd(ENABLE);                 //使能系统安全时钟 * r; c7 v3 D1 s3 _
    115.    
      , O" k! _( g; [  ^
    116.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO,ENABLE);
      : A% Z5 M* z5 [# ]
    117.   }- s: \( v! j9 g7 x- B& [7 R
    118. }
      / ?& N% `, T, _# `- k+ o

    119. ) R9 D- s7 r" t
    120. 1 x6 M  G9 c+ {  ?3 k
    121. + ?0 S2 _* ]( m7 v0 y% ^0 `% D
    122. /******************* (C) COPYRIGHT SUNSHINE SILICON  **************************
      9 L+ X8 D: P! s9 g7 W6 R% V, c9 x
    123. ********************        END OF FILE main.c        *******************/
    复制代码

    & x0 ^) P# L" u+ |, {* \$ g
  • 编译调试
    0 X3 ~6 o  W1 L9 v3 e) N4 c
保存直接编译,发现编译出错,提示FLASH_PrefetchBufferCmd 和 FLASH_SetLatency函数未定义。解决方法添加库文件stm32f10x_flash.c' b6 T8 f9 w+ R! O+ t2 f
重新编译,通过。! S3 a- P: r: n  p; x
调试
2 Y+ ?/ G% R3 T$ A; k7 C; c( Z: ~2 W/ w
方法不再重复,经过前两节练习,大家应该是会了.3 ]2 p4 Q% Q. {/ r# v: h# `% b( B8 E
效果与前一节是一样,只是我们多了RCC配置。现在效果一样,但是真正项目里RCC是配置不一样,是致命的。# P# l* G  L/ }! B+ E

5 t' \6 E: K( l. ]+ r- ?0 a课后作业
  m. R1 d% u$ T& i5 j改变CPU运行频率
. w: c( `" u- ]5 l- L" h1 ^
; n2 B) b/ M3 P! C3 \工程源码) v' i! C/ J- E9 u) f4 J
(回复后,可查看 下载)# m- _+ O; a2 J6 P+ Z* z# r# I
游客,如果您要查看本帖隐藏内容请回复

本帖被以下淘专辑推荐:

回复

使用道具 举报

 楼主| 发表于 2021-11-21 23:58:24 | 显示全部楼层
会员登录后,可看到更多内容,例程源码,及工程文档下载。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-21 23:59:35 | 显示全部楼层
微信扫码登录连注册一次完成
回复 支持 反对

使用道具 举报

发表于 2021-11-22 00:04:46 | 显示全部楼层
非常棒的教程
回复 支持 反对

使用道具 举报

发表于 2022-1-6 13:02:27 | 显示全部楼层
学习了
回复

使用道具 举报

发表于 2022-5-23 21:56:55 | 显示全部楼层
赞一个
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|深圳市光明谷科技有限公司|光明谷商城|Sunshine Silicon Corpporation ( 粤ICP备14060730号|Sitemap

GMT+8, 2024-3-29 16:25 , Processed in 0.109207 second(s), 46 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表