
STM32中的时钟系统概述5 X9 G# v- }3 h: V: s* F( x![]() q9 H/ c. r0 f% M: Y% l1 r 5个蓝色背景的是时钟源 SYSCLK是系统时钟,最重要的时钟,可以看到其他的外设的时钟都来源于系统时钟' J! @8 @. u$ V+ h. j7 s* Q, l' B w 7 N- h& b0 E8 O$ }" e# j HSI RC高速内部: q. |% ^& K) O) v4 Y9 ^ 约为8MHz,但不太稳定,可以作为系统时钟,灰色背景的梯形表示选择器 HSE Os高速外部 接晶振,例如8MHz,其可以直接作为选择器的输入,也可以分频后作为选择器输入,PLL表示锁相环,用于倍频,可以选择2-16,通过锁相环寄存器配置,产生的时钟为PLL_CLK0 c9 L5 P+ p# H. Y% g p: q4 { / D- G0 V1 k/ R9 q/ C- i L' H CSS时钟监控系统- ]% }& l! @3 w- ~, _; {8 C! ~1 \ 一旦HSE失效,则自动切换到SYSCLK=HSI, M% F) J7 j) y4 L. u" U# B9 b- t 2 L5 Q& {% M; d, D1 n# [/ W LSE Os低速的外部时钟 通过外接晶振产生,一般为32.768kHz,用于RTCCLK & Y- i& v7 Q4 G+ }# F RTCCLK还可以来自于HSE的128分频 LSI RC低速内部! z( p% f8 |( l' c: {" p6 g. t5 F 由内部的RC振荡器产生,约为40kHz3 A+ u, E, C7 R& Z% s8 [8 A 主要是用于STM32的独立watch dog提供时钟7 C" C% O2 v4 d1 Y2 e) W1 f : S- n4 C% n$ s/ ^7 g% | MCO输出内部时钟引脚PA8 可以来自于系统时钟SYSCLK 2 O. i- W G% Q8 B1 J 可以来自于HSI; U* h7 U* R7 m6 X - ^- T% X" o" Y) z5 S+ P 可以来自于HSE : }5 t! k3 z! S4 L7 H4 m 可以来自于PLLCLK的2分频 & p$ Y/ }8 ^5 I2 Z6 C USB时钟 48MHz,可以来自于PLL时钟经过USB分频器,除以1或者1.54 I+ J( I# C6 W2 m Q 72MHz和48MHz之间的倍数就是1.5 AHB Prescaler AHB预分频器 AHB预分频器的分频因子有9种选择: 1,2,4,8,16,64,128,256,5124 O: a2 R/ m- ?$ N 分频后产生HCLK这个时钟最高可以到72MHz 1 Z' y- \5 z, f; C4 n5 l- ? APB1 Prescale APB1预分频器; _% a, I; u- y# o5 L. X 产生PCLK1,用于挂低速外设,例如通用定时器, G3 M0 [9 {1 P3 E APB2 Prescale APB2预分频器 产生PCLK2,可以供对于时钟要求高的外设 % H* j3 W. _& n7 E* ~' c 注意:任何一个外设使用前,必须首先使能其相应的时钟2 |, ]2 [: Z% Z% N" L% E - Z% o' d! z" e _3 I& w0 ]# v3 }# M stm32中的时钟配置RCC, B5 b# @( z E2 _" D j 如下图所示,为STM32工程中对于时钟的配置文件( r G5 v/ `9 h' n3 E4 r2 n9 R 7 P& D& T& i& `# o E9 k1 ~3 X( g ![]() 首先打开寄存器地址名称映射头文件 这个头文件中对于大部分寄存器的映射都会在这里通过一个结构体来定义% A9 Z7 ~3 R- o) T E ![]() 8 ]+ g% g; ^, M" t2 @$ V# t 如下图所示,这个结构体中的成员变量映射了对应的寄存器8 ^* }6 c4 W# G; \ $ Y& s- v6 | l, K4 b4 P6 B ![]() 2 M3 O0 l/ [6 S: S2 H 对于RCC寄存器的详细描述,可以参考STM32中文参考手册 ![]() RCC时钟控制寄存器 HSI,HSE,LSI,LSE,PLL这5个时钟源,使用前需要使能,使能后还不稳定,稳定后会产生稳定标志位4 B' M& D6 x" q; _, J1 m+ h - t( p/ X- c$ T, B ![]() / r1 A5 j$ f, [4 \( H3 r) H RCC时钟配置寄存CFGR 配置选择器,PLL倍频系数,Scaler的分频系数0 w" _ S5 k- R! H4 Y+ B 7 {! a9 S+ R) b ![]() : U2 j+ A2 c# X: i V ![]() 3 H: L( O( ]. s, i RCC外设时钟使能寄存器 AHBENR AHB外设时钟使能寄存器6 M8 w5 r6 O Z/ x0 B. W+ S6 u 包括SDIO,FSMC,CRC,FLITF,SRAM,DMA1,DMA2 ![]() , a, c0 K( R* A1 r4 C ![]() % x8 f5 E# g; ~; f/ G& c APB2ENR APB2外设时钟使能寄存器 包括ADC3,USART1,TIM8,SIP1,TIM1,ADC2,ADC1,IO ABCDEFG等 * p# V2 k; K" U ![]() 1 e3 g- l! h7 B2 r6 Y ![]() ![]() 4 b& @) f- ^3 i" J- {! ?; P APB1ENR APB1外设时钟使能寄存器 包括DAC接口,电源接口,备份接口,CAN时钟,USB时钟,I2C时钟,UART2345时钟,SPI23时钟,看门狗时钟,Timer 234567时钟等4 U5 v* S* v. Q% q P- K" _, U2 f E * O& h# C# x! j: r# j ![]() ![]() ![]() 5 g* J# @' J6 Z g Z; _; f9 W ![]() 7 D$ s' d* `4 j/ }% w RCC寄存器的操作 可以通过相关的库函数,对于这些RCC寄存器进行操作 ![]() 这些库函数可以分为以下几类: 7 t) o/ L! Y+ ?, \" J! f) q9 I 时钟使能配置. d% ]- l' H. T, b6 q/ [ void RCC_LSEConfig(uint8_t RCC_LSE);! ]5 y/ k t4 K: X & {: ]1 f& P1 i' H+ v void RCC_HCLKConfig(uint32_t RCC_SYSCLK); void RCC_HSEConfig(uint32_t RCC_HSE); 0 t4 X; `% P% w* d- r void RCC_HSICmd(FunctionalState NewState); + [6 B7 w! O3 L+ Q void RCC_LSICmd(FunctionalState NewState);' z* j& ]4 \7 d% k6 k# y8 s , F* [% g7 M% E3 ]# N! r7 F: H k ... o7 G* y2 P& [5 w4 k 时钟来源配置# Z- l4 f8 d, S! a void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul);, Q3 X& p: j: n' R& a4 f; y3 k 5 ]2 @6 l+ h6 m ~ void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);% n- g, S8 R6 K& l* w 4 B7 q- ^/ W U" z void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); 分频系数选择配置) J. V2 l8 j) ?* i% N1 r: A& C Y. p0 v / m* @( m- Q: B' ?: d6 ]- t void RCC_HCLKConfig(uint32_t RCC_SYSCLK);( `& ~1 D3 b' [, ^+ Z$ L) [ 0 ~. v# _* N; V4 T# s0 z' o void RCC_PCLK1Config(uint32_t RCC_HCLK); $ a6 @- [1 }, ]% c6 W$ r1 _ void RCC_PCLK2Config(uint32_t RCC_HCLK); ' x. }8 M7 R }5 P' Y 9 g( c# v8 u' E( y( ?. e 外设时钟使能 void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);) g" G; b0 k C0 k9 t# {/ D0 q 6 L2 y% z [3 O void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); 4 a- x! W1 K5 ? 其他外设时钟配置 void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource); Q. C6 U* _6 |) v, O void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);9 t! M, g( e9 h/ Y" n- a 状态参数获取 void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks); uint8_t RCC_GetSYSCLKSource(void);: }' h7 k- W4 r+ g # D D8 a# x8 s8 ~. } FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);3 R; Q% `# a9 C5 r: i3 R6 U' Q' U 7 E3 S$ J& U. I! I0 I# B RCC中断 . J( N2 |4 L2 j o: G! [4 K void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState);) z! a, t, Q) U$ w. { ITStatus RCC_GetITStatus(uint8_t RCC_IT);8 o0 t- @( S+ _" y 7 H- g! A7 X: A! T* @ void RCC_ClearITPendingBit(uint8_t RCC_IT); ————————————————. Q v* I# ~' G) ?& k% K 版权声明:CodeForCoffee# g) f' w5 o, |) h1 ^# l . P4 H: b' I F( q- F& J |
基于STM32时钟系统经验分享
【经验分享】STM32G4之SysTick系统时钟
【经验分享】STM32F4系统时钟
【经验分享】STM32G4之RTC实时时钟
【经验分享】STM32入门系列-STM32时钟系统,STM32时钟树
【经验分享】STM32入门系列-STM32时钟系统,自定义系统时钟
【经验分享】STM32入门系列-STM32时钟系统,时钟使能配置函数
DFSDM 时钟配置问题
【经验分享】详解STM32的时钟系统
【经验分享】STM32CubeMX-实时时钟(RTC)