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

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

[复制链接]
STMCU小助手 发布时间:2025-7-30 16:49
, W+ D/ \9 ~) Z& H9 a

* u2 ?* o0 t5 |; F1 X( m# D% q1. 问题
% t' ^- A1 l0 OSTM32CubeMX 升级到了 V6.13.0 ,与此同时 STM32Cube_FW_H7 也升级到了 V1.12.0 ,在时钟获取数组的定义中出现了问题,造成的问题现象是串口输出内容乱码,经过和 V6.12.1+ STM32Cube_FW_H7_V1.11.2 生成的代码对比,发现是时钟获取函数的数组出现的问题,修改之后即可正常。
* J* e5 C, i  h6 z5 B6 @5 p0 C
& g7 h. t* f! P3 p" p/ f- v
& F7 K9 h  X5 O$ H$ O  U
2. 如何复现0 {2 i: e  N/ A. y  ~4 N1 G) C
在 ST 官网上下载 STM32CubeMX 6.13.0 链接:Here,选择器件型号为 STM32H743ZIT6,使能 USART3 这个外设,选择使用 STM32Cube_FW_H7_V1.12.0 库来生成代码之后,串口打印出来的内容就是乱码。% A. m  c: A" K8 R% e2 e. U

/ n0 Q( {8 }3 d9 ?$ x) x

+ i: B* M5 [9 B0 k* g$ g时钟配置如下图 1 所示。7 v) V- A+ }# H6 w' o$ d3 u$ ?
14.png
图1. 默认时钟配置

: j2 n; w5 |' H% E4 w1 O0 o/ t9 g
2.1. 代码分析2 r9 p. E" m- P  z/ e$ m7 V
首先,让我们看一下,不同的版本在生成代码中的主要区别,主要是 D1CorePrescTable 这个数组的内容有变化。2 `' }0 M+ B, ~: W
15.png
图2. 生成代码对比

1 q( _& H7 x6 V9 T9 M1 K

" w+ _& L2 M1 G5 `" ?3 l2 T; S由上图可见,数组 D1CorePrescTable 的【4 : 7】内容由原来的{1,2,3,4}变成了 {0,0,0,0},那么这个数组是做什么用的,又为什么会对串口有影响呢?让我们来分析一下代码。* W% r4 d/ E% E5 O; o& L/ l
/ N( g& J; G8 ]. H$ J0 ?

" e! y8 _  e, x6 p: G! V: t- [在串口初始化中有如下调用关系:9 p. s( b1 B' ?5 L' Y1 w

& [9 O: k6 s; j
- C  H3 \/ G+ E1 J# c
MX_USART3_UART_Init()àHAL_UART_Init()àUART_SetConfig()àHAL_RCC_GetPCLK1Freq()
1 M4 y! [  Q7 g6 W- v
16.png
图3. 代码内容

1 k4 |; j* P# Z* A0 H

  `1 J6 I+ k0 O$ N+ T+ ?% Q3 R1 \由图 3 中的代码,我们可以看到,这里引用了 D1CorePrescTable 的内容,这里是如何引用的呢?其实是比较巧妙的。$ w$ n" V1 i: P5 A, X

; O' G# Y& M+ [7 }, ?% T9 i6 z

8 s9 }4 x) R7 S$ h7 c; g( J# {3 v我们首先看寄存器中是如何配置的。( s1 b+ T7 o( q/ G5 E2 K, H8 v0 U0 t
17.png
图4. 寄存器描述

3 E6 U. x& y6 E% m0 O

  [. f+ K8 i* e' H3 _* L寄存器中的 D2PPRE1[2:0]是配置 D2 域中 APB1 的分频系数,默认是 0xx,表示不分频;100 是 1/2 分频;101 是 1/4 分频 ; 以此类推。
# |/ e6 [3 Q, ]
& G9 _6 a% d: D) r4 n% U! @4 C4 `

1 P, Z5 S* }. Y0 c7 W8 f在整个时钟树中的位置如图 5 所示% ]% l8 ^9 ], E- |3 `
18.png
图5. 寄存器在时钟树中位置

8 }% }# g. y* e' r% S

. G$ }  _2 |* L0 u回到代码,我们单独截取其中一句话。
$ J2 m+ f9 q# Q$ ^+ X( z
19.png
图6. 代码详细内容
0 j$ A; D" S! i" x$ F
4 W6 m) L9 }: v8 l6 I3 L) l
其中的数值定义如图 7 所示! S3 ~6 G4 O: [1 w+ A
20.png
图7. 代码定义内容

' P! y# G2 P2 Z; y: {. h; a
) {/ O- L" |$ t( K5 z$ r+ N
这个地方通过读取寄存器(RCC->D2CFGR 中的 D2PPRE1)的配置,就能得到 APB1总线上的时钟分频参数,其先通过函数 HAL_RCC_GetHCLKFreq()得到系统时钟的频率,再将其进行右移操作(右移 1 位代表除以 2)。具体右移多少位就是通过查找 D1CorePrescTable 这个表来决定的。
+ v4 m6 Y* q8 }0 K5 O" r% c( Y

1 |& v: f2 {$ ?* Y6 n" k% v比如,这里如果是 1/2 分频,那么 RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos 得到的结果就是 0b100,再和 0x1FU 进行“与操作”得到也是 0b100,即十进制的 4。通过正确的 D1CorePrescTable 表格,即可得到 D1CorePrescTable【4】=1,(注意数组是从 0 开始的)那么就是系统时钟进行右移 1 位的操作,得到除以 2 的效果。
/ X' f1 V7 P* ^4 s1 M, x4 P% @" ^$ d9 `$ J$ }
( r# j# o- J5 ]$ K
正确数组:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
9 z7 ?/ r4 L! l
5 y( l* ]5 C9 A5 u) T: d2 }

. A% v0 R/ K9 O) t0 x3 f3 j' ]错误数组:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};. z( e4 ^$ o% N
, H$ ?( l0 I& v2 L& G/ F
1 v; l, N7 n: K
但是如果是错误的数组,查到的就是 D1CorePrescTable【4】=0,这是不需要右移的,就是没有经过 1/2 分频,显然是不对正确的。
; a% y: a& [9 w. m0 E. e5 B0 t& `0 [+ f: Y
* h$ Q. }) G2 N' T+ O) _" q- Q) C8 Z
这里还有个小问题:如果在 APB1 的时钟是没有经过分频的,那么 RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos 得到的结果就总是小于 4 的(即 0xx,具体参见图 4),查表得到的结果就都是 0,也是没有问题的。但是1/2,1/4,1/8,1/16 这些分频系数都会出现计算错误,所以正确的方式就是手动修改这个参数即可解决问题。
' j* {/ ?1 r9 W, ^/ U
$ x+ k: N: K9 A# h0 p
) Z. P8 X. P8 l% M5 F( J" x( w
3. 解决问题
. s: b5 e; ?3 ^* g6 F$ m2 s% x7 V4 S手动修改 system_stm32h7xx.c 中的数组 D1CorePrescTable 中的【4 :7】中数据即可。- f$ i* m7 ~9 F+ g9 X8 C9 `
. E) A4 P. Y! F
$ ]; Q' Y# ?5 ?8 z4 c. a& U0 C9 k; D
正确:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};* f5 Q; b1 l: v, ~& K

7 W& g* k; w% m

. ?( a, Y. ?7 V1 g7 M) M同时,提交 bugzilla :197431 (此号码为 ST 内部使用,外部用户无法访问)。
* [$ B# M+ m& N" c) g# }/ ?' }7 S4 _  O% [$ M
# G( a: i1 @0 \/ @, }  W
4. 小结
3 i4 R0 _7 \5 [7 r4 B7 k# m  n2 y这个问题,主要是来自时钟计算所需要的表格出错,造成串口波特率计算出来的结果错误。本文简要分析了数组在查表的方式进行的对应运算关系,并对错误范围做出了解释,未来遇到类似的问题都可以使用此方式进行分析。
9 ^% M$ |& ?& B5 x7 P1 B, t% r. _————————————————
8 {( w  X- O1 U! f. R& b9 u. D/ `
3 S) e9 P5 _0 q5 o* b  m
6 y6 y) V+ M( v+ s0 {
                           
0 h8 p, g3 F5 c: L2 |) z" l6 t4 l# S: q4 X, W/ A
收藏 评论0 发布时间:2025-7-30 16:49

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版