DMA 原理从 0 到 1:为什么它能解放 CPU?一文讲透 DMA 的工作流程
【福利三:雨露均沾·逢7狂欢】之五:STM32系统时钟PLL故障排除1例
【福利三:雨露均沾·逢7狂欢】之三:AI帮我查BUG
福利三:雨露均沾·逢7狂欢】之二:STM32F407VG串口通信乱码故障的排除
基于STM32F103的I2C主从机通信
OpenBLT移植到STM32F103战舰开发板上适用于所有STM32F103系列的Bootloader
TFT LCD 与 FSMC 的硬件连接大容量 STM32F10xxx FSMC 接口
单片机:初学者该了解的STM32F103基础知识
2025软件工具兔哥知道
STM32之继电器模块
微信公众号
手机版
分享一个7 J/ I W! s+ X& h
#ifndef RCC_HPP_" G# y$ ^* l6 `& U$ L
#define RCC_HPP_% L2 W6 R& U! l3 T+ K
#include "STM32F103.h"+ f9 H. ^2 l8 S' C% O4 L
namespace MCU' i: g6 t# q" t; ?( `4 @
{) V: q% W% r) w
namespace STM32F1031 \: ]1 U7 \) w j6 N
{
struct RegisterRCC
{0 o6 E/ i6 H7 w* L `
volatile union
{
volatile uint32_t Value;7 T+ W: n2 Y; @* k+ X6 ]( [
, }4 o6 [( y4 j ?! J
volatile struct7 _) l# ?" p |' Y9 @# y+ K) x
{
volatile uint32_t HSION : 1;
volatile const uint32_t HSIRDY : 1;
volatile uint32_t RESERVED1 : 1;; W4 u4 O/ v" O: j, j
volatile uint32_t HSITRIM : 5;
volatile const uint32_t HSICAL : 8;
volatile uint32_t HSEON : 1;5 A+ J" A0 i9 x6 M
volatile const uint32_t HSERDY : 1;% i( z2 e; T; w6 U6 N5 ^3 ?
volatile uint32_t HSEBYP : 1;
volatile uint32_t CSSON : 1;
volatile uint32_t RESERVDE2 : 4;$ O6 D) ^- O0 f1 g! p
volatile uint32_t PLLON : 1;3 e: Y) {/ g7 r$ n4 r4 p
volatile const uint32_t PLLRDY : 1;
volatile uint32_t RESERVDE3 : 6;& V! a& E: |* d# X& j- j0 g- ]! u
}Bit;/ }& N2 r" \9 q" d, v" u: f/ ]
}CR;4 u4 m) `+ R9 ^8 Y9 n, \6 [
volatile union2 x7 r4 F4 ~2 n9 o) Y. Q4 s
{9 w/ s5 k3 F; o# H0 B
volatile uint32_t Value;1 _' m! U5 C/ \0 }) i4 ?
5 V4 v8 G) S# p
volatile struct: r. h7 |+ m' a: Y" j8 u- d% `
{9 r: U" f# |6 X3 i
volatile uint32_t SW : 2;' ~, }! y/ @% D7 {* b
volatile const uint32_t SWS : 2;
volatile uint32_t HPRE : 4;
volatile uint32_t PPRE1 : 3;5 e1 {& {) e, ]. z& A6 {) Q
volatile uint32_t PPRE2 : 3;
volatile uint32_t ADCPRE : 2;
volatile uint32_t PLLSRC : 1;2 f# M. k! f/ j. W. _1 I; T
volatile uint32_t PLLXTPRE : 1;. s. [: ?( D; ?( d6 x. x. L: n
volatile uint32_t PLLMUL : 4;
volatile uint32_t USBPRE : 1;
volatile uint32_t RESERVED1 : 1;
volatile uint32_t MCO : 3;! {. e6 @ C0 l
volatile uint32_t RESERVED2 : 5;& i% ]4 z/ B7 m
}Bit;* }( f9 _1 U3 u: {" m0 ~: D9 A" Q5 s
}CFGR;* A# q2 j5 e9 B+ Z, K H- W
( k7 v! q. q5 p" g3 t5 q* i* F" v
volatile union7 E, _- y4 `1 S! y3 n
{
volatile uint32_t Value;2 t, i) d! k6 A% p$ v
2 _+ Y' m% H* G5 z* A
volatile struct
{, \& b" W8 l: [
volatile const uint32_t LSIRDYF : 1;
volatile const uint32_t LSERDYF : 1;
volatile const uint32_t HSIRDYF : 1;% `" a9 A6 q; A7 C* p2 O, c# @
volatile const uint32_t HSERDYF : 1;
volatile const uint32_t PLLRDYF : 1; v" g! G- Z+ N0 t
volatile const uint32_t PLL2RDYF : 1;
volatile const uint32_t PLL3RDYF : 1;+ R% n5 A/ y/ g# [6 V
volatile const uint32_t CSSF : 1;
volatile uint32_t LSIRDYIE : 1;2 ?( Q) I" q- J- T9 w
volatile uint32_t LSERDYIE : 1;
volatile uint32_t HSIRDYIE : 1;
volatile uint32_t HSERDYIE : 1;, s7 E* e) F- z: ]# F2 o$ P3 M' m2 l
volatile uint32_t PLLRDYIE : 1;
volatile const uint32_t PLL2RDYE : 1;0 e p2 ]; H( m5 B3 Y: o K' `
volatile const uint32_t PLL3RDYE : 1;3 c( N" Z8 E; c) g
volatile uint32_t RESERVED1 : 1;
volatile uint32_t LSIRDYC : 1;
volatile uint32_t LSERDYC : 1;& K* o1 }7 S! M7 _! _- J- p
volatile uint32_t HISRDYC : 1;
volatile uint32_t HSERDYC : 1;
volatile uint32_t PLLRDYC : 1;
volatile uint32_t PLL2RDYC : 1;
volatile uint32_t PLL3RDYC : 1;; `% C6 P/ `/ ~% f4 v6 h) T
volatile uint32_t CSSC : 1;
volatile uint32_t RESERVED2 : 8;
}Bit;
}CIR;
volatile union
{5 P% q9 l* \, l9 i6 F: _+ x
volatile uint32_t Value;
volatile struct
{
volatile uint16_t AFIORST : 1;" u5 i$ t0 T) [" n
volatile uint16_t RESERVED1 : 1;
volatile uint16_t IOPARST : 1;
volatile uint16_t IOPBRST : 1;" A- s5 r) W% t8 f$ v5 b( Z
volatile uint16_t IOPCRST : 1;- O. ~' f1 p5 `$ n: R& o
volatile uint16_t IOPDRST : 1;! B+ Z( Q, N- z" w; \$ \' M
volatile uint16_t IOPERST : 1;
volatile uint16_t IOPFRST : 1;/ D5 V# q+ {5 V& u( k
volatile uint16_t IOPGRST : 1;) R* M% s6 {( b# \
volatile uint16_t ADC1RST : 1;$ @* M# y# S+ ^' d
volatile uint16_t ADC2RST : 1;
volatile uint16_t TIM1RST : 1;& m2 q8 r" h$ o1 E8 f! N, t
volatile uint16_t SPI1RST : 1;, E2 W' F2 Y* W4 L* v
volatile uint16_t TIM8RST : 1;# V6 r3 \$ c! E2 D, g
volatile uint16_t USART1RST : 1;
volatile uint16_t ADC3RST : 1;
volatile uint16_t RESERVED2 : 16;
}Bit;, S' H/ G$ [0 _) p3 Z6 v3 S; s% m
}APB2RSTR;
, |7 ]; J6 `; Y. M6 F* {
volatile union+ J/ w( h4 `) I
{8 [% t* L: I" }6 o
volatile uint32_t Value;
volatile struct
{' h3 F/ b4 `/ I# A$ j9 W' K
volatile uint32_t TIM2RST : 1;* `' w$ O& x; ]3 L( a( z# e/ G
volatile uint32_t TIM3RST : 1;
volatile uint32_t TIM4RST : 1;9 ^6 n4 |6 d# @0 |. O
volatile uint32_t TIM5RST : 1;. O0 f( u, I" @1 T b5 Q
volatile uint32_t TIM6RST : 1;" `# m2 ?$ _/ w+ F* X4 z
volatile uint32_t TIM7RST : 1;& O8 X8 v" h( q& U: g
volatile uint32_t RESERVED1 : 2;6 T4 [" [7 x5 v* U- C; o& N6 {
volatile uint32_t RESERVED2 : 3;; `7 Q1 h: Y+ V5 m, |' s
volatile uint32_t WWDGRST : 1;
volatile uint32_t RESERVED3 : 2;# r4 L8 E: C( S8 M
volatile uint32_t SPI2RST : 1;
volatile uint32_t SPI3RST : 1;
volatile uint32_t RESERVED4 : 1;& F7 P1 G+ S. y+ t) r7 n% y3 H
volatile uint32_t USART2RST : 1;
volatile uint32_t USART3RST : 1;
volatile uint32_t USART4RST : 1;5 z7 J% y$ H, N9 I0 x
volatile uint32_t USART5RST : 1; _; ~9 m+ K" m# a* [8 u4 Q. q
volatile uint32_t I2C1RST : 1;% I0 g6 S; Z/ q" B1 d
volatile uint32_t I2C2RST : 1;
volatile uint32_t USBRST : 1;
volatile uint32_t RESERVED5 : 1;( S, c, D+ m& a* g4 {, r4 U5 I( w9 i
volatile uint32_t CANRST : 1;+ L5 H: e# o% R8 q
volatile uint32_t RESERVED6 : 1;& f, J+ l' s% @7 A, B' p
volatile uint32_t BKPRST : 1;
volatile uint32_t PWRRST : 1;
volatile uint32_t DACRST : 1;
volatile uint32_t RESERVED7 : 2;
}Bit;9 d! k, K% @4 }" m4 Q# ]* Z. I% u
}APB1RSTR;
volatile union4 `8 a- B. [5 C' W
{
volatile uint32_t Value;
volatile struct
{
volatile uint16_t DMA1EN : 1;$ _# w: G2 |. n/ c; U0 ?& o# q$ P
volatile uint16_t DMA2EN : 1;' Q: o/ X+ s: M0 l
volatile uint16_t SRAMEN : 1;) H9 N+ z- H: i$ `- P9 h3 V1 o
volatile uint16_t RESERVED1 : 1; D. X4 |: f1 k, Q* N" y' {# p. g
volatile uint16_t FLITFEN : 1;
volatile uint16_t RESERVED2 : 1;$ f* S) A7 m; J2 F4 H
volatile uint16_t CRCEN : 1;
volatile uint16_t RESERVED3 : 1;
volatile uint16_t FSMCEN : 1;
volatile uint16_t RESERVED4 : 1;% A1 e1 W( Q* Y: n1 T, u3 Y* a
volatile uint16_t SDIOEN : 1;
volatile uint16_t RESERVED5 : 5;6 ^( ~4 v9 q3 Y
volatile uint16_t RESERVED6 : 16;
}Bit;6 j6 b! j( O8 ` M& e0 A
}AHBENR;4 G5 @* c" L2 q2 _: [$ Y" `$ E
volatile union
{
volatile uint32_t Value;6 v( @6 K9 C* _) u/ J$ I* p# L! v
* O q: ]- W, \1 r4 _9 w* I
volatile struct$ |( Q$ N% }" K+ n* ]
{
volatile uint16_t AFIOEN : 1;5 R, ]! R: T3 {- Y) [% @
volatile uint16_t RESERVED1 : 1;# T: a' k' \2 i# ?
volatile uint16_t IOPAEN : 1;9 Y' L( b" m& I
volatile uint16_t IOPBEN : 1;
volatile uint16_t IOPCEN : 1;
volatile uint16_t IOPDEN : 1;
volatile uint16_t IOPEEN : 1;
volatile uint16_t IOPFEN : 1;
volatile uint16_t IOPGEN : 1;
volatile uint16_t ADC1EN : 1;
volatile uint16_t ADC2EN : 1;* C- M1 `+ T2 r5 y: d% a
volatile uint16_t TIM1EN : 1;3 n9 ^; X( p# z3 E
volatile uint16_t SPI1EN : 1;
volatile uint16_t TIM8EN : 1;4 x- U7 \: T( Y- a3 t
volatile uint16_t USART1EN : 1;) W9 U, P- t1 @& t- z3 F
volatile uint16_t ADC3EN : 1;8 T, D- D$ J3 d' H' s$ {/ v
volatile uint16_t RESERVED2 : 16;
}Bit;: y( Y$ p( ~3 `, P6 M. H( W
}APB2ENR;
volatile union3 ~7 q3 x T% j) K$ d0 F8 g. s
{2 s: g5 c0 L0 y4 t2 B$ ?1 z
volatile uint32_t Value;
volatile struct$ }( i1 t1 z0 v4 m; {1 V9 e
{
volatile uint32_t TIM2EN : 1;- F! E) R. L; T. P
volatile uint32_t TIM3EN : 1;. a# }) G4 r1 J& N0 ^
volatile uint32_t TIM4EN : 1;
volatile uint32_t TIM5EN : 1;) ` H7 z6 }5 ~0 ]: P8 F( s
volatile uint32_t TIM6EN : 1;
volatile uint32_t TIM7EN : 1;2 X8 l2 R. c$ L T, P8 H: A
volatile uint32_t RESERVED1 : 2;
volatile uint32_t RESERVED2 : 3;; S' F5 Z0 u* t b7 C* i7 X4 U- U' z% o
volatile uint32_t WWDGEN : 1;
volatile uint32_t RESERVED3 : 2;% O* n* X" C, D: ]
volatile uint32_t SPI2EN : 1;- ~, {6 [! ~8 r R2 u7 p
volatile uint32_t SPI3EN : 1;
volatile uint32_t RESERVED4 : 1;6 G! ^( q7 H" `1 ~2 h( u
volatile uint32_t USART2EN : 1;
volatile uint32_t USART3EN : 1;$ k. f6 b% y8 q
volatile uint32_t USART4EN : 1;
volatile uint32_t USART5EN : 1;1 P% G1 ?$ d3 _/ x% G4 h: T
volatile uint32_t I2C1EN : 1;
volatile uint32_t I2C2EN : 1;
volatile uint32_t USBEN : 1;
volatile uint32_t RESERVED5 : 1;
volatile uint32_t CANEN : 1;8 M1 {( p0 E5 t2 O
volatile uint32_t RESERVED6 : 1;/ p' y" y& z6 b: K
volatile uint32_t BKPEN : 1;
volatile uint32_t PWREN : 1;
volatile uint32_t DACEN : 1;
volatile uint32_t RESERVED7 : 2;. O; g- o5 W5 N, i( s
}Bit;$ w- |. W5 m: @! I2 `
}APB1ENR;
1 }2 Z @0 t7 ?9 n3 H/ W9 K. B
volatile union: l3 y- B- x Z2 |8 V( U7 `1 j
{( J$ X5 ^8 x z5 P$ |
volatile uint32_t Value;, a; S5 Y* F/ b* _( L& K; O- V
volatile struct
{& { L0 C: p* O' S
volatile uint32_t LSEON : 1;. R7 x( j- `# ]6 T
volatile const uint32_t LSERDY : 1;
volatile uint32_t LSEBYP : 1;# l; r3 K, Q. V8 x% ]' `# T
volatile uint32_t RESERVED1 : 5;0 o2 f$ l; w9 ~( p( D- n. v) u
volatile uint32_t RTCSEL : 2;* C; k0 _+ d% s* {
volatile uint32_t RESERVED2 : 5;
volatile uint32_t RTCEN : 1;
volatile uint32_t BDRST : 1;
volatile uint32_t RESERVED3 : 7;
volatile uint32_t RESERVED4 : 8;' f. ~) X% d: J5 z2 Z
}Bit;) V/ \+ G7 [. H; J
}BDCR;# k9 J _) s, k$ m' c) a; h
$ t" u* Y4 K: R! w9 C
volatile union 4 |( b5 r: K% b' S9 X
{
volatile uint32_t Value;& h/ P0 } U/ |5 h
. C/ m8 Z2 J4 ~8 \' F. ~1 t* u
volatile struct) k; p; y, z/ O/ {7 F
{, t. s+ r' p' ~
volatile uint32_t LSION : 1;
volatile const uint32_t LSIRDY : 1;
volatile uint32_t RESERVED1 : 6;+ R$ T# E+ B4 k! k1 _9 Q. Y
volatile uint32_t RESERVED2 : 8;
volatile uint32_t RESERVED3 : 8;
volatile uint32_t RMVF : 1;" v m) Z/ J& \
volatile uint32_t RESERVED4 : 1;: c5 j _ Q' z0 \. N( Y9 ?7 |$ Z
volatile uint32_t PINRSTF : 1;
volatile uint32_t PORRSTF : 1;: N7 J+ h- Z, u
volatile uint32_t SFTRSTF : 1;
volatile uint32_t IWDGRSTF : 1;5 B$ m: w( L D
volatile uint32_t WWDGRSTF : 1;
volatile uint32_t LPWRRSTF : 1;+ j1 o, C7 K- \& f7 e) ?5 A
}Bit;
}CSR;5 u8 ]' w. D4 I1 x* x* w( Y" K
};# m$ J& D- m: c% H0 L
( J+ E$ M: t: r
enum RCC_PLL_MUL' \" H8 X7 s8 ]; G6 N+ Z
{
RCC_PLL_MUL2 = 0b0000,6 a Q# c# G; j8 u; H k
RCC_PLL_MUL3 = 0b0001,) d' u: r4 J/ [9 j
RCC_PLL_MUL4 = 0b0010," d1 M/ {1 L1 [! q; \) T& Y
RCC_PLL_MUL5 = 0b0011,
RCC_PLL_MUL6 = 0b0100,
RCC_PLL_MUL7 = 0b0101,9 ?/ |* ]% `; i, `# u! L6 \$ i# p2 b. {
RCC_PLL_MUL8 = 0b0110,
RCC_PLL_MUL9 = 0b0111,$ F" [; y% L0 I# ]6 ^
RCC_PLL_MUL10 = 0b1000,( Q, |- y, L( ^" e0 O
RCC_PLL_MUL11 = 0b1001,
RCC_PLL_MUL12 = 0b1010,
RCC_PLL_MUL13 = 0b1011,% U. f' S9 x- J- K
RCC_PLL_MUL14 = 0b1100,
RCC_PLL_MUL15 = 0b1101,' J9 \( I4 [: I1 k" Q
RCC_PLL_MUL16 = 0b1110,7 G* h5 S) a ?/ J. F
};' D* q% g3 h# u2 W6 L2 t' A+ U
' E% k% G3 X2 F8 O+ n; T3 Z! [
enum RCC_PLL_XTPRE' ?4 h0 f4 N$ a+ V3 j( h! h& C
{" }- P7 ?* K/ a. `: }! S
RCC_PLL_XTPRE_DIV1 = 0b0," H# F/ O% l) N' F# }
RCC_PLL_XTPRE_DIV2 = 0b1,
};
" s5 A/ T, ?4 d/ [% f4 {3 \
enum RCC_PLL_SRC% P4 G( t; r: g
{
RCC_PLL_SRC_HSI_DIV2 = 0b0,5 M+ l4 h; _- e3 S, X T" G D+ X
RCC_PLL_SRC_HSE = 0b1,
};3 [8 P5 E% u7 y* v5 `* U" u
enum RCC_HPRE
{
RCC_HPRE_DIV1 = 0b0000,( w) s& w2 R6 B& r: O* E: h
RCC_HPRE_DIV2 = 0b1000,, i: E: L$ |( D
RCC_HPRE_DIV4 = 0b1001,( {) B) W2 @9 ~1 I# M
RCC_HPRE_DIV8 = 0b1010,
RCC_HPRE_DIV16 = 0b1011,: v$ K" r; k' D' x
RCC_HPRE_DIV64 = 0b1100,
RCC_HPRE_DIV128 = 0b1101,
RCC_HPRE_DIV256 = 0b1110,
RCC_HPRE_DIV512 = 0b1111,$ y4 z5 Y) L3 L+ B7 `. M4 H6 }; |
};6 H/ j+ E; ^/ w! M: h" j6 H7 i
enum RCC_PPRE% T, P( a3 C/ v. W) `" v, ]: _9 R
{3 H8 m( a! M! m; L
RCC_PPRE_DIV1 = 0b000," Z8 d. ]1 f1 h; g
RCC_PPRE_DIV2 = 0b100,, M; C) c ~- T5 K5 u5 U, ~/ L7 O
RCC_PPRE_DIV4 = 0b101,
RCC_PPRE_DIV8 = 0b110,
RCC_PPRE_DIV16 = 0b111,
};
# F( B: e) ?) g* x
enum RCC_SW
{
RCC_SW_HSI = 0b00,
RCC_SW_HSE = 0b01,
RCC_SW_PLL = 0b10,# A( W6 Y! x3 r' K2 N! a' u; e
};
class CRCC
{
public:
//保存外部晶体频率 在EnableHSE方法中初始化 用于计算系统频率
static uint32_t HSE;
. p' G+ U7 m1 X$ Y9 {- {+ P0 v3 ]
volatile struct RegisterRCC *pRegister = (volatile struct RegisterRCC *)(RCC_BASE);: m; H( G. e4 j; @5 k# B/ T# s
//开启外部高速时钟并等待时钟就绪,如果时钟不能就绪则一直等待
//HSE:晶体频率 单位:Hz
void EnableHSE(uint32_t HSE)1 ]/ Q4 t+ y5 [% q
{# d% l& q) V [2 [( F9 I0 F# [; B
CRCC::HSE = HSE;7 J$ }4 D; R& ?
6 D% c% h1 {+ }9 c6 {( N8 ] V
this->pRegister->CR.Bit.HSEON = 1;8 w4 w. Y, x5 [5 U0 U/ v; h
while(!this->pRegister->CR.Bit.HSERDY);: H. g; h# Y$ t# b
}4 i5 s( t1 q7 N: C1 q
|, k8 k j! _ b% W+ _$ t$ H, q
//设置PLL参数,必须在PLL关闭的状态下
void SetPLL(RCC_PLL_MUL MUL, RCC_PLL_XTPRE XTPRE, RCC_PLL_SRC SRC)7 `, D& y" F/ d3 S. T- C
{! }$ V) h- R) \6 V* b5 i1 }+ i; l$ a
this->pRegister->CFGR.Bit.PLLMUL = MUL;
this->pRegister->CFGR.Bit.PLLXTPRE = XTPRE;0 r/ }* D' @, j
this->pRegister->CFGR.Bit.PLLSRC = SRC;- I8 T/ I1 S7 q3 U5 T& ]7 F* D9 d
}5 ^2 J2 v+ r k& i
//开启PLL时钟并等待时钟就绪,如果时钟不能就绪则一直等待+ x D( Q4 u& G) w: P
void EnablePLL(void)
{
this->pRegister->CR.Bit.PLLON = 1;
while(!this->pRegister->CR.Bit.PLLRDY);7 J0 o! z* y$ z8 f8 V
}2 ~; R, `* Z/ V9 {! T. F- `+ l0 `; u* a
//切换系统时钟源并等待切换就绪,如果切换不能就绪则一直等待( Y; o6 a& k6 w. ^2 s. S
void SetSysClkSource(RCC_SW SW)/ `" n' v- q! r! v
{* c9 J& I; }6 c* I
this->pRegister->CFGR.Bit.SW = SW;
while(this->pRegister->CFGR.Bit.SWS != SW);+ Z% O- q( n- w6 Z
}9 T* ^ T# ^3 q/ |: l
% k/ b( Z/ C) D# L; b
//获取系统时钟频率 单位:Hz
uint32_t GetSYSCLK(void)
{
if(this->pRegister->CFGR.Bit.SWS == RCC_SW_HSI)# i! l' R4 D4 I! F! o7 F1 f: N
{
//系统时钟为HSI9 J5 B. o& t0 {7 C9 D! z, a
return 8000000;: V6 w0 ^* Y6 j- o2 c
}
else if(this->pRegister->CFGR.Bit.SWS == RCC_SW_HSE)6 ?$ `- H, t& W* k6 c, o
{
//系统时钟为HSE. y' i9 o6 m* H7 q
return CRCC::HSE;
}) h* P1 p h- N; i+ S4 c4 w" W
else if(this->pRegister->CFGR.Bit.SWS == RCC_SW_PLL)
{
//系统时钟为PLL
uint32_t SRC, XTPRE, MUL;
if(this->pRegister->CFGR.Bit.PLLSRC == RCC_PLL_SRC_HSI_DIV2)
{
//PPL输入时钟源为HSI/2
SRC = 8000000;
XTPRE = 2;* k8 c0 [6 S$ [/ e+ A/ @
}8 T4 k. ]; f. T: L
else
{) X: O0 ? x5 m1 V
//PLL输入时钟源为HSE/ @7 A! K* ?$ a4 X6 w* e ]( L+ T
SRC = CRCC::HSE;. c8 H- t1 ^, o9 j* b
5 }( @$ }- ~6 u( t
if(this->pRegister->CFGR.Bit.PLLXTPRE == RCC_PLL_XTPRE_DIV1)
{
//PLL输入时钟源为HSE/2
XTPRE = 1;! b! t/ I* O' S" t% C
}6 y/ S1 o+ `$ q, K
else6 O3 ]& p/ [1 I9 f8 ^ T' g
{' k s3 G$ q" q7 X0 R% ]
//PLL输入时钟源为HSE/2
XTPRE = 2;( a3 V$ t6 R8 A: m- O
}5 R+ n. j$ |0 _0 m r0 \3 H
}/ R; h! Z" g5 s0 e
8 [2 M6 l K7 S
switch((uint32_t)this->pRegister->CFGR.Bit.PLLMUL). h/ L# U4 q; ? H6 u& r$ O- O
{' Y! M+ @3 N9 a& N% {% E
case RCC_PLL_MUL2: MUL = 2; break;
case RCC_PLL_MUL3: MUL = 3; break;, O/ n4 V" X$ g, x
case RCC_PLL_MUL4: MUL = 4; break;; z2 x2 P( O, o2 Q) C% G1 l
case RCC_PLL_MUL5: MUL = 5; break;
case RCC_PLL_MUL6: MUL = 6; break;
case RCC_PLL_MUL7: MUL = 7; break;; f- ]$ q( ]) _- f
case RCC_PLL_MUL8: MUL = 8; break;
case RCC_PLL_MUL9: MUL = 9; break;0 z! S D! Q# R/ Q7 l/ o3 Y; O8 a
case RCC_PLL_MUL10: MUL = 10; break;
case RCC_PLL_MUL11: MUL = 11; break;( g/ V1 O, V; D0 I* W
case RCC_PLL_MUL12: MUL = 12; break;
case RCC_PLL_MUL13: MUL = 13; break;/ D2 | w+ c- R! `5 O1 x+ l
case RCC_PLL_MUL14: MUL = 14; break;# ^+ z2 V# v; W; r" Q
case RCC_PLL_MUL15: MUL = 15; break;
case RCC_PLL_MUL16: MUL = 16; break;& B: o& O5 x. {
default: MUL = 16; break;; J* n$ i" _/ f) @0 r
}
d N2 x% K5 {
return SRC / XTPRE * MUL;) B. ^6 j* M$ v q: K0 t& C
}
else
return 8000000;
}
//获取AHB总线频率 单位:Hz
uint32_t GetHCLK(void)
{
uint32_t Prescaler;0 {7 H5 Z$ Q, s+ v" s4 S
( w9 X& W- @4 J( h/ w6 B, j
switch((uint32_t)this->pRegister->CFGR.Bit.HPRE)
{
case RCC_HPRE_DIV1: Prescaler = 1; break;4 o, B3 H% D9 \0 r
case RCC_HPRE_DIV2: Prescaler = 2; break;
case RCC_HPRE_DIV4: Prescaler = 4; break;" C/ b: f& O2 \# Z6 P
case RCC_HPRE_DIV8: Prescaler = 8; break;
case RCC_HPRE_DIV16: Prescaler = 16; break;
case RCC_HPRE_DIV64: Prescaler = 64; break;$ x7 |/ s) g- ^: B$ G
case RCC_HPRE_DIV128: Prescaler = 128; break;. P3 l* o2 S3 m4 T" [ Q: r
case RCC_HPRE_DIV256: Prescaler = 256; break;
case RCC_HPRE_DIV512: Prescaler = 512; break;
default: Prescaler = 1; break;: O- Y( a0 W& l$ |
}
5 h4 E% g' f1 r
return this->GetSYSCLK() / Prescaler;4 Y! Q3 v5 Z2 d
}/ x g: P! R) ^- t9 M, v: O) j
7 d0 {$ d8 T; U- j9 O2 F& g
//获取APB1总线频率 单位:Hz
uint32_t GetPCLK1(void)/ n- W) }+ N8 U' B
{9 c# C; F' w. D+ l3 |; c% f
uint32_t Prescaler;! D( Z: H; i R$ |9 N
% m5 \- x4 H& ]- e
switch((uint32_t)this->pRegister->CFGR.Bit.PPRE1)& U! D% p% v3 d- z! z' F- r' k% \1 I
{6 \1 E. F( G8 t5 F
case RCC_PPRE_DIV1: Prescaler = 1; break;
case RCC_PPRE_DIV2: Prescaler = 2; break;# \4 @+ v( N1 i+ I( t, e. w/ g
case RCC_PPRE_DIV4: Prescaler = 4; break;+ k% v4 R, Y9 d) T9 e* C' o7 {( M
case RCC_PPRE_DIV8: Prescaler = 8; break;
case RCC_PPRE_DIV16: Prescaler = 16; break;
default: Prescaler = 1; break;
}7 T4 ?! T5 Z( I8 b' m ?
! u/ a$ O' d8 c! _# g2 R9 ]
return this->GetHCLK() / Prescaler;* K M$ ]: B- G) c
}6 i- S9 Y+ ]9 T
) p2 j. F# f' O0 Q4 x
//获取APB2总线频率 单位:Hz
uint32_t GetPCLK2(void)5 Q3 C$ x) ]' }1 W- f$ N4 i
{
uint32_t Prescaler;
switch((uint32_t)this->pRegister->CFGR.Bit.PPRE2): K' `+ p1 }' n
{
case RCC_PPRE_DIV1: Prescaler = 1; break;. n1 ?$ x$ E% Z7 R# _
case RCC_PPRE_DIV2: Prescaler = 2; break;: w# U8 ~. [; ?8 a7 U
case RCC_PPRE_DIV4: Prescaler = 4; break;, o; I, Z# Z6 ]/ ^! M3 d
case RCC_PPRE_DIV8: Prescaler = 8; break;
case RCC_PPRE_DIV16: Prescaler = 16; break;
default: Prescaler = 1; break;' [9 x- T' y- Z7 W. N1 B
}
return this->GetHCLK() / Prescaler;
}2 V! N0 E) O+ R& z
};
4 j& }. Y' d' R, B3 p! x
uint32_t CRCC::HSE = 0;: I% K( ^; M' ], \6 i
}
}+ y# L; a( ~2 C( Q0 Q
* ~$ a |0 H: ?5 j- |8 ?
#endif // !RCC_HPP_, I3 Q# Y& Z6 F3 \; f
3 c- l% O: ~4 H# H# ~9 Y( Z
这是对RCC的封装,其实对寄存器的封装只是C++写单片机的小问题.还有几个问题要解决.+ \( h3 C/ ?% x5 l' C: T H1 n) @
第一:如何把中断连接到任何对象的方法,这个问题本质就是如何利用指针调用对象方法,实现后可以更好的发挥面向对象的多态思路,实现一些高灵活度的编程.我用模板类实现了一个类似C#中的委托对象,然后利用这个对象还可以实现类似C#中的事件,完成消息的多播.当然这是需要付出代价的,这个模板类要用到虚函数表,经过实测这个消耗是可以接受的,多1us左右吧.这个模板类的实现具体可以用Bing国际版搜索FastDelegate., S) n5 z6 d. h- j: H. U
第二:如何new和delete,这个必须通过OS实现.我使用FreeRTOS,然后全局重载new和delete运算符到pvPortMalloc和pvPortFree.不过能定义声明的对象尽量定义声明,不要频繁new和delete因为FreeRTOS的内存管理还是很弱鸡的.实现的目的只是为了提高程序的灵活度.让一些代码可以更快地适配一些硬件.我通常都是只new不delete
为了更好更快地更换MCU,应该定义一个HAL层,里面全是虚基类,抽象类似但又不同的硬件.然后顶层基于HAL开发,底层继承HAL的虚基类并做具体实现.不过虚基类又牵涉虚函数表,会有性能损失.在对性能要求高的地方还是针对不同的硬件进行直接控制., e, z" T4 F$ e
0 v7 Z% m3 K6 J7 K0 I% j! c% b
为了更好的进行C++编程,我用gcc编译器.使用这个编译器时一定要注意,编译优化可能导致运行结果不正确,我通常是用O2或Os,一些特殊的函数还需要标记为O0.开发环境是Visual Studio 2019(个人版 免费) + VisualGDB(我买了正版).VisualGDB V5.5R2这个版本真是超级好用,自动完成,代码着色,代码格式化都是杠杠的.这个环境中在线仿真是ST-Link 2 + OpenOCD,可以设置端点,可以实时读取寄存器值,等等.
总之,C++配上这个开发环境生产力大大提高,代码的可复用性也大大提高.另外,我的项目已经投产了.
& a G F% b/ c; k" z
+ Z5 V# }, k, g3 p
还更新吗,能出一期环境搭建的教程吗,配一个Demo工程) w# o& U7 @6 ?8 W$ P4 b