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

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

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

* Z- V! G+ V3 O' {4 O

3 y, M) j, z9 X0 M. ^& l- U( k1. 问题9 {, D6 v! r! q' ]
STM32CubeMX 升级到了 V6.13.0 ,与此同时 STM32Cube_FW_H7 也升级到了 V1.12.0 ,在时钟获取数组的定义中出现了问题,造成的问题现象是串口输出内容乱码,经过和 V6.12.1+ STM32Cube_FW_H7_V1.11.2 生成的代码对比,发现是时钟获取函数的数组出现的问题,修改之后即可正常。$ B: t6 I+ N/ }8 F; ?# v
" B# G$ B1 G0 p
9 b3 o% |; {7 |# e1 X5 @, ?
2. 如何复现! \7 e) d8 K" F) k
在 ST 官网上下载 STM32CubeMX 6.13.0 链接:Here,选择器件型号为 STM32H743ZIT6,使能 USART3 这个外设,选择使用 STM32Cube_FW_H7_V1.12.0 库来生成代码之后,串口打印出来的内容就是乱码。
# y! F& X7 c. j. L7 u) L
+ s, V* V6 z* `7 d' `! h9 Q

* L4 ^$ |: {7 W, j时钟配置如下图 1 所示。: U: D: s& @' R
14.png
图1. 默认时钟配置

- A9 j# \$ l# G  G9 R- m" e+ P
2.1. 代码分析
' F$ t- L. F( |0 w首先,让我们看一下,不同的版本在生成代码中的主要区别,主要是 D1CorePrescTable 这个数组的内容有变化。
1 Q; ]8 o9 C( p0 q
15.png
图2. 生成代码对比
% m% {0 A, U7 F& W: t0 F. G7 L
: {  I1 Y. u, k1 i" u
由上图可见,数组 D1CorePrescTable 的【4 : 7】内容由原来的{1,2,3,4}变成了 {0,0,0,0},那么这个数组是做什么用的,又为什么会对串口有影响呢?让我们来分析一下代码。
  @1 `% |; \! [* b: O/ J- n" m! K( ?0 V6 }
5 L) |$ Y" \. Z4 q
在串口初始化中有如下调用关系:* u* X& Y" k5 g* q# X5 k

5 n3 P3 X' S# r; {; R" ^
$ G* b) w2 o  E% L4 j% ~; a( i
MX_USART3_UART_Init()àHAL_UART_Init()àUART_SetConfig()àHAL_RCC_GetPCLK1Freq()
% B" m: h9 q( q* D
16.png
图3. 代码内容

' Z/ t# L4 ~1 N2 a! i' R

- f* P% ?/ R  {由图 3 中的代码,我们可以看到,这里引用了 D1CorePrescTable 的内容,这里是如何引用的呢?其实是比较巧妙的。, ~( a2 _& S$ i, [+ ~! c

( C$ I* ~! ^# m; l- m& ~

" o6 y7 Y! [0 p$ {0 y* l我们首先看寄存器中是如何配置的。
6 g8 y* M9 s# `
17.png
图4. 寄存器描述

6 U, T2 x: p% K8 c$ h5 n7 I4 W
8 S% ^9 c/ J1 X% R% \
寄存器中的 D2PPRE1[2:0]是配置 D2 域中 APB1 的分频系数,默认是 0xx,表示不分频;100 是 1/2 分频;101 是 1/4 分频 ; 以此类推。
1 w! U/ ]2 k4 S" X; |% k- t
0 e  x+ F6 B0 `

2 h! v, ^0 a" v1 f在整个时钟树中的位置如图 5 所示$ X1 K8 _" V) K9 T( S
18.png
图5. 寄存器在时钟树中位置

  ?. N9 j9 h9 {: I
. f$ N7 K7 {1 E. A$ n# R+ I8 `
回到代码,我们单独截取其中一句话。( Q$ @+ V# F7 p- h$ ~. y
19.png
图6. 代码详细内容

: |4 L/ F0 g' q# j
( M0 w  f) R2 f3 g  L" n, J& t
其中的数值定义如图 7 所示
8 h" M4 Y) W: D
20.png
图7. 代码定义内容
( X$ U( T6 t  K
; l$ c. I$ ~4 M' E
这个地方通过读取寄存器(RCC->D2CFGR 中的 D2PPRE1)的配置,就能得到 APB1总线上的时钟分频参数,其先通过函数 HAL_RCC_GetHCLKFreq()得到系统时钟的频率,再将其进行右移操作(右移 1 位代表除以 2)。具体右移多少位就是通过查找 D1CorePrescTable 这个表来决定的。- Z* j' Y$ a: o( K, k# r. c

* M+ T0 j  w+ z% ^: p

( I1 b8 L. w$ }, @8 W( N0 R比如,这里如果是 1/2 分频,那么 RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos 得到的结果就是 0b100,再和 0x1FU 进行“与操作”得到也是 0b100,即十进制的 4。通过正确的 D1CorePrescTable 表格,即可得到 D1CorePrescTable【4】=1,(注意数组是从 0 开始的)那么就是系统时钟进行右移 1 位的操作,得到除以 2 的效果。7 c1 _  I9 Q3 |7 B$ M- i4 Z# D

1 B+ T7 x% m/ h7 z" \) f
7 x* l3 u8 T( t' i* I, o$ Y
正确数组:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
& H! v( P, E) h- L" z8 G0 g4 }) q& K9 _
3 _0 y# r0 p' o1 R& l. K

8 M" B% }! ?, ~' K( n1 g# Z  P, z) Y错误数组:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};# S! l7 B( z$ u* s

; m* E9 [5 K1 f+ d- p) a

! c$ H# P; Z9 y但是如果是错误的数组,查到的就是 D1CorePrescTable【4】=0,这是不需要右移的,就是没有经过 1/2 分频,显然是不对正确的。
3 M4 @: c4 \4 V  {) T  p& v; [0 H. F* o2 q
* @; b. b: {* |4 L
这里还有个小问题:如果在 APB1 的时钟是没有经过分频的,那么 RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos 得到的结果就总是小于 4 的(即 0xx,具体参见图 4),查表得到的结果就都是 0,也是没有问题的。但是1/2,1/4,1/8,1/16 这些分频系数都会出现计算错误,所以正确的方式就是手动修改这个参数即可解决问题。- P6 C! k- W9 h6 @

7 K( z4 H0 H( X/ F5 y, c3 `

: n7 ~/ |2 X5 z% _2 V( Y( E* U3. 解决问题
$ B2 t" V% I8 d7 K+ `; R: P7 C手动修改 system_stm32h7xx.c 中的数组 D1CorePrescTable 中的【4 :7】中数据即可。8 E( y2 \; g4 z+ l2 k

. S# v' L' w4 J* Q6 P6 y$ U8 U
: p: A" W- ^3 ~9 {- l/ `
正确:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};$ X9 ^4 w$ ?) r5 E- a( y
! _. I+ a: r2 R  [0 D1 U. O

9 N2 M" w# I9 E2 q6 w' z同时,提交 bugzilla :197431 (此号码为 ST 内部使用,外部用户无法访问)。& U$ Q' K, [6 ~, Y& K0 m4 y0 r, C

1 s: `9 ^7 o" \* `7 q/ Y

8 z9 U1 K& s* M4. 小结, y& A- L$ z% E1 b$ j
这个问题,主要是来自时钟计算所需要的表格出错,造成串口波特率计算出来的结果错误。本文简要分析了数组在查表的方式进行的对应运算关系,并对错误范围做出了解释,未来遇到类似的问题都可以使用此方式进行分析。
0 b' r* S  s( ^( D8 ]  F————————————————% a/ P% K) j2 O% X  L

: X; P( k9 Q' N1 P4 I

+ Q$ k* S( F. A( F                            ) o; A& ~" l0 y5 C7 x
, U1 a6 ]5 R+ A1 D; G
赞 收藏 评论0 发布时间:2025-7-30 16:49

举报

0个回答

所属标签

相似技术帖

官网相关资源

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