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

经验分享 | STM32CubeMX 生成时钟获取函数的分析

[复制链接]
STMCU小助手 发布时间:2025-7-30 16:49

7 Y& S+ E( d& @3 {9 e
( u) V& w$ |7 D+ ~! M3 [
1. 问题2 r: I: v& b/ k3 \
STM32CubeMX 升级到了 V6.13.0 ,与此同时 STM32Cube_FW_H7 也升级到了 V1.12.0 ,在时钟获取数组的定义中出现了问题,造成的问题现象是串口输出内容乱码,经过和 V6.12.1+ STM32Cube_FW_H7_V1.11.2 生成的代码对比,发现是时钟获取函数的数组出现的问题,修改之后即可正常。* h9 m0 _# q; ?4 C
* a  y/ S% `: Y6 c3 Z; S1 E8 Z

% R1 i7 {) }8 |. D% f6 `' M2. 如何复现0 z5 _3 |$ l' `& K
在 ST 官网上下载 STM32CubeMX 6.13.0 链接:Here,选择器件型号为 STM32H743ZIT6,使能 USART3 这个外设,选择使用 STM32Cube_FW_H7_V1.12.0 库来生成代码之后,串口打印出来的内容就是乱码。
' y" b) y1 `+ |  s( ^* Z( x
9 |0 n  A& j1 u" t8 y8 K

5 ?+ o! q6 ^" x3 c时钟配置如下图 1 所示。  T$ z! w: n4 ]9 R, [- C
14.png
图1. 默认时钟配置
5 B$ D! t  d. e/ X
2.1. 代码分析6 b- x' _) E9 B( P% T
首先,让我们看一下,不同的版本在生成代码中的主要区别,主要是 D1CorePrescTable 这个数组的内容有变化。: E& ^- p9 w; P
15.png
图2. 生成代码对比
) q9 H* H# I( f* Q+ Q) a& s: |

: w) f  \" t. s( z% U6 g3 q  z. m7 P由上图可见,数组 D1CorePrescTable 的【4 : 7】内容由原来的{1,2,3,4}变成了 {0,0,0,0},那么这个数组是做什么用的,又为什么会对串口有影响呢?让我们来分析一下代码。
# q- [. N! Q! F# R: }
5 O$ o6 [3 a' R& a
+ }2 e7 I4 Y4 i% z9 t$ v
在串口初始化中有如下调用关系:
. L+ h. M0 c9 X2 @# p* J) _5 _4 j# A  X

$ R. l  ]; ]5 M; [# G2 `MX_USART3_UART_Init()àHAL_UART_Init()àUART_SetConfig()àHAL_RCC_GetPCLK1Freq()
( F1 `. C- n* N
16.png
图3. 代码内容
" [% j- |- l  @- q$ O5 d' M8 F8 w
/ m# g) d1 V. ]( g2 d) H
由图 3 中的代码,我们可以看到,这里引用了 D1CorePrescTable 的内容,这里是如何引用的呢?其实是比较巧妙的。2 u7 k3 y. \+ {, a; u& q

* r+ |( j2 {; K9 u3 X

/ i* I! \& G6 @& |( [9 o0 k我们首先看寄存器中是如何配置的。
* w6 O2 R$ [8 \
17.png
图4. 寄存器描述
& o1 J, g: T6 F9 }

. c9 h, d" v9 U- s寄存器中的 D2PPRE1[2:0]是配置 D2 域中 APB1 的分频系数,默认是 0xx,表示不分频;100 是 1/2 分频;101 是 1/4 分频 ; 以此类推。
% o- p* j( |. p# ~& a9 g9 E2 _1 M2 x" g. q2 D
2 A) o) P0 g% P! s. J3 X
在整个时钟树中的位置如图 5 所示! d) E. Y' m5 x3 M( Q
18.png
图5. 寄存器在时钟树中位置

. S  ]# Q; h0 Z4 r
9 h* y; B. n# [* G& |2 N( [
回到代码,我们单独截取其中一句话。
" c; ^+ C, d+ M& B, O0 q: g; z* S* m
19.png
图6. 代码详细内容

" b/ O) y, U. {5 O

5 f) w3 b2 ]8 _8 k; k0 K其中的数值定义如图 7 所示5 a! ]; U1 I0 J0 S. ^3 O
20.png
图7. 代码定义内容

" X2 C8 o. p8 S/ I

# @1 F$ h% X- }6 X! w这个地方通过读取寄存器(RCC->D2CFGR 中的 D2PPRE1)的配置,就能得到 APB1总线上的时钟分频参数,其先通过函数 HAL_RCC_GetHCLKFreq()得到系统时钟的频率,再将其进行右移操作(右移 1 位代表除以 2)。具体右移多少位就是通过查找 D1CorePrescTable 这个表来决定的。
  B  }; X: ]& _' l9 _' ]
+ `% E5 ^9 C4 Z# ~2 W

# n- |5 ^/ A9 X) q8 r) O比如,这里如果是 1/2 分频,那么 RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos 得到的结果就是 0b100,再和 0x1FU 进行“与操作”得到也是 0b100,即十进制的 4。通过正确的 D1CorePrescTable 表格,即可得到 D1CorePrescTable【4】=1,(注意数组是从 0 开始的)那么就是系统时钟进行右移 1 位的操作,得到除以 2 的效果。
3 Q2 _/ g, W/ k3 ]/ ]6 d) y9 Z1 Q0 K* d: E5 a" o( U
4 Q' c) d0 m4 O" o$ I+ h1 E+ X
正确数组:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
% k4 W7 h$ o' Y+ o0 m7 z2 c9 U" h3 ^1 u

2 i: B: b( O. h+ O错误数组:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};  r; ?8 _! a. G; G, R2 _8 r1 ?9 P& L

# {7 g5 @. C( i( v' A, ^+ ]4 e

- B  v) a$ ^3 [; E6 g% ^但是如果是错误的数组,查到的就是 D1CorePrescTable【4】=0,这是不需要右移的,就是没有经过 1/2 分频,显然是不对正确的。
: t# Y' }4 n  {5 S) G' |" C. i$ ?; z% H, n2 l2 p8 {

) ?! G! c  w" B+ x5 O1 T这里还有个小问题:如果在 APB1 的时钟是没有经过分频的,那么 RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos 得到的结果就总是小于 4 的(即 0xx,具体参见图 4),查表得到的结果就都是 0,也是没有问题的。但是1/2,1/4,1/8,1/16 这些分频系数都会出现计算错误,所以正确的方式就是手动修改这个参数即可解决问题。/ h" s, G# @% v) {& d6 {
% Y% V8 U( J9 N& a6 |
0 M- u: ?& N/ }2 G1 G' H
3. 解决问题2 C0 p- M4 T6 Z! g' F! y
手动修改 system_stm32h7xx.c 中的数组 D1CorePrescTable 中的【4 :7】中数据即可。0 s# F3 ^+ a4 T/ G! D' t  g

/ r4 t  J- w6 I0 ?1 j5 y
: S: |, B6 V; O5 D" Q3 s* ?
正确:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
7 o# g9 ?4 d- }5 x9 g- Q
1 Z: z% ?& Y9 G* F) Y$ h

$ A. g8 F3 w2 R- e; N% {同时,提交 bugzilla :197431 (此号码为 ST 内部使用,外部用户无法访问)。
& p$ _8 J; A$ K4 d# y1 d+ {/ G. V% s* i- |
( J5 S3 ], W, T; Z# E, Z
4. 小结
& t: c& j: W7 F8 n+ b! t) i6 L这个问题,主要是来自时钟计算所需要的表格出错,造成串口波特率计算出来的结果错误。本文简要分析了数组在查表的方式进行的对应运算关系,并对错误范围做出了解释,未来遇到类似的问题都可以使用此方式进行分析。5 ?3 P: q! |- Q5 o; X0 V
————————————————# f2 o7 [( U* q! ]* W, J' m

; K3 X/ K2 J4 R. f* f: q$ B

3 _7 t8 E7 H" N                           
% Y! |7 j# f- @- z4 T8 E, i! F" O, q5 b3 z
赞 收藏 评论0 发布时间:2025-7-30 16:49

举报

0个回答

所属标签

相似技术帖

官网相关资源

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