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

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

[复制链接]
STMCU小助手 发布时间:2025-7-30 16:49
! [, Z7 X' Q4 L2 U

5 \$ j# F* w" a" U( w5 |$ }1. 问题4 |) s  k, J5 f) l% s: d
STM32CubeMX 升级到了 V6.13.0 ,与此同时 STM32Cube_FW_H7 也升级到了 V1.12.0 ,在时钟获取数组的定义中出现了问题,造成的问题现象是串口输出内容乱码,经过和 V6.12.1+ STM32Cube_FW_H7_V1.11.2 生成的代码对比,发现是时钟获取函数的数组出现的问题,修改之后即可正常。
3 _6 Z0 Y- ^& P! ^
8 |9 W: H; r! @" {% G

! o' [) l2 |* j2. 如何复现( H' q/ l$ k* Q! a5 z
在 ST 官网上下载 STM32CubeMX 6.13.0 链接:Here,选择器件型号为 STM32H743ZIT6,使能 USART3 这个外设,选择使用 STM32Cube_FW_H7_V1.12.0 库来生成代码之后,串口打印出来的内容就是乱码。
; z( q$ k9 ^2 p$ F9 k. @  p: Y6 K
# l( ^0 z1 [; x, M  L# ^) d

& S. Z3 Q% q4 a5 U5 O2 M9 ]% B" o6 G时钟配置如下图 1 所示。
' ^2 E6 k: y2 q" |
14.png
图1. 默认时钟配置

+ x* L: t; K5 Y) c' x
2.1. 代码分析- o8 t& j- u2 }1 ~6 T" X
首先,让我们看一下,不同的版本在生成代码中的主要区别,主要是 D1CorePrescTable 这个数组的内容有变化。: i8 V) g3 k  }
15.png
图2. 生成代码对比

4 O9 S7 @3 f# N& o* P% c

! }& D; z* k# P由上图可见,数组 D1CorePrescTable 的【4 : 7】内容由原来的{1,2,3,4}变成了 {0,0,0,0},那么这个数组是做什么用的,又为什么会对串口有影响呢?让我们来分析一下代码。6 ^! q0 o* @- _: `

# L4 Z( j4 E' Q

3 H+ ?3 f. u8 d8 ]在串口初始化中有如下调用关系:; |6 I# [+ M: C3 n; R. a

( v' z. [: u2 J% L8 v4 B, Q+ [

$ B( l9 Z# V2 S# s! l. L" vMX_USART3_UART_Init()àHAL_UART_Init()àUART_SetConfig()àHAL_RCC_GetPCLK1Freq(); Z& k7 \( m9 H% G, o1 D
16.png
图3. 代码内容
7 \) \) h) z6 l
+ @+ u) B/ }1 ]
由图 3 中的代码,我们可以看到,这里引用了 D1CorePrescTable 的内容,这里是如何引用的呢?其实是比较巧妙的。: ~! ~! N& g" B7 [2 z+ q

$ k, i/ |0 {0 Z' _
8 N; @" C6 H" i$ T/ K4 ^- v
我们首先看寄存器中是如何配置的。' O- G3 C3 t- T. L/ ?
17.png
图4. 寄存器描述

. G! G" P! j3 ~' D1 F9 ^" i/ h

( [" B- |) E: t6 x5 K寄存器中的 D2PPRE1[2:0]是配置 D2 域中 APB1 的分频系数,默认是 0xx,表示不分频;100 是 1/2 分频;101 是 1/4 分频 ; 以此类推。% ~8 t- z" h) ~7 w

5 n$ e5 w3 b* t+ p

6 G! @! w. a. D) k0 ^9 R* x在整个时钟树中的位置如图 5 所示
" S7 t! I( B1 m6 t% D
18.png
图5. 寄存器在时钟树中位置

( t7 D5 c/ [3 J; b+ O. ~
) d0 x' I: x) a! b
回到代码,我们单独截取其中一句话。
. N7 e& y% u/ a" O
19.png
图6. 代码详细内容
" C! e9 v% U7 c2 k! ~5 K# E

; D2 C# V2 D# Q# k! w其中的数值定义如图 7 所示
8 h' H2 v/ }9 q
20.png
图7. 代码定义内容

( z- L& ?! p8 a# R3 H& y1 O
/ W1 [! w$ p6 \6 `
这个地方通过读取寄存器(RCC->D2CFGR 中的 D2PPRE1)的配置,就能得到 APB1总线上的时钟分频参数,其先通过函数 HAL_RCC_GetHCLKFreq()得到系统时钟的频率,再将其进行右移操作(右移 1 位代表除以 2)。具体右移多少位就是通过查找 D1CorePrescTable 这个表来决定的。
+ H2 X% ?$ p/ y/ C3 U+ v
" m& J( `- @/ B+ i
5 m( ^* L# Y" V2 T! y: ]% y
比如,这里如果是 1/2 分频,那么 RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos 得到的结果就是 0b100,再和 0x1FU 进行“与操作”得到也是 0b100,即十进制的 4。通过正确的 D1CorePrescTable 表格,即可得到 D1CorePrescTable【4】=1,(注意数组是从 0 开始的)那么就是系统时钟进行右移 1 位的操作,得到除以 2 的效果。' B  C0 D; V0 T! J. R

0 I3 j6 e- J  ]" R
$ P; D' z3 W' T; ~
正确数组:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};+ A( \$ }0 `+ p+ U( t5 @+ m
2 [4 U: F- U! F; M1 z9 w. ^

2 W- `# C7 A0 P4 K: c% V6 O错误数组:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
6 ~  W# M  U" ~# F$ {, e+ U8 v0 N' h9 B) c! H
) A; _6 d# @- I* g2 }/ x
但是如果是错误的数组,查到的就是 D1CorePrescTable【4】=0,这是不需要右移的,就是没有经过 1/2 分频,显然是不对正确的。
0 x$ j$ l4 P  ]7 R; D
8 q8 G% _  k. g2 Q  @
3 D# g) p4 f7 V3 Y& e& d3 o
这里还有个小问题:如果在 APB1 的时钟是没有经过分频的,那么 RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos 得到的结果就总是小于 4 的(即 0xx,具体参见图 4),查表得到的结果就都是 0,也是没有问题的。但是1/2,1/4,1/8,1/16 这些分频系数都会出现计算错误,所以正确的方式就是手动修改这个参数即可解决问题。
& _+ y, G1 J& V* v' k. U8 i1 ~! a% ?  ?& j( j

# x( u3 R& U& r9 v3. 解决问题4 n3 U! v4 T7 O/ p8 `
手动修改 system_stm32h7xx.c 中的数组 D1CorePrescTable 中的【4 :7】中数据即可。
2 K4 i  \% ]7 j) Y  f3 d8 ~
  o% G  S. P1 |; J+ @+ y
" `& {) t2 [/ m- Q
正确:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};, W0 D0 T( W0 ?9 F: ?# z" l
: z' [9 x; p$ ^+ k
$ [  a2 [8 W- c
同时,提交 bugzilla :197431 (此号码为 ST 内部使用,外部用户无法访问)。
2 V% ~2 _5 i( R% f$ g
3 }8 |7 t% T4 c' ]$ c" S
+ H9 f5 E$ O2 t/ I0 V5 m
4. 小结
7 S4 m$ E7 P6 C( U这个问题,主要是来自时钟计算所需要的表格出错,造成串口波特率计算出来的结果错误。本文简要分析了数组在查表的方式进行的对应运算关系,并对错误范围做出了解释,未来遇到类似的问题都可以使用此方式进行分析。
5 Z6 y1 {( o0 z$ L8 b————————————————, m. |8 ]7 F7 _( {0 C

5 T. u4 P4 y+ m* G0 i
7 Z4 [6 I9 ^" m4 G- F; C
                            ' F5 y  ?( p6 g# I. M

# I+ [, `$ U# `: l8 r- a8 }
收藏 评论0 发布时间:2025-7-30 16:49

举报

0个回答

所属标签

相似技术帖

官网相关资源

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