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

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

[复制链接]
STMCU小助手 发布时间:2025-7-30 16:49
* L+ }5 D$ N* X/ n# h
$ r+ v4 q' y2 x6 e# s
1. 问题) E% h& g, [& k! Z. L8 A
STM32CubeMX 升级到了 V6.13.0 ,与此同时 STM32Cube_FW_H7 也升级到了 V1.12.0 ,在时钟获取数组的定义中出现了问题,造成的问题现象是串口输出内容乱码,经过和 V6.12.1+ STM32Cube_FW_H7_V1.11.2 生成的代码对比,发现是时钟获取函数的数组出现的问题,修改之后即可正常。
# k% a9 N* B' n+ c* X) o& P# \" n" o2 {% i9 ]; Q/ V- r
" y  D" b+ M1 ~2 M
2. 如何复现
, J; ~3 S9 O; {. [在 ST 官网上下载 STM32CubeMX 6.13.0 链接:Here,选择器件型号为 STM32H743ZIT6,使能 USART3 这个外设,选择使用 STM32Cube_FW_H7_V1.12.0 库来生成代码之后,串口打印出来的内容就是乱码。+ y6 W3 z! e5 R" t( r0 e% V* @. Y

+ }) g% @( q! b+ ?" I
% e0 S+ \7 ?6 E1 w( B7 N
时钟配置如下图 1 所示。, G: g, d- ]2 S" r6 V6 h  f5 `
14.png
图1. 默认时钟配置

7 L3 u1 V3 O2 F2 W6 j
2.1. 代码分析7 i$ m% [$ [. T8 I: v
首先,让我们看一下,不同的版本在生成代码中的主要区别,主要是 D1CorePrescTable 这个数组的内容有变化。8 Q# k! P1 ~) |$ S) _, L$ Q+ E
15.png
图2. 生成代码对比
  v0 v+ j: f/ h" B
' ?* _) T- Y" S# L! o
由上图可见,数组 D1CorePrescTable 的【4 : 7】内容由原来的{1,2,3,4}变成了 {0,0,0,0},那么这个数组是做什么用的,又为什么会对串口有影响呢?让我们来分析一下代码。
1 S' I4 ?$ M' W
  c5 E8 Y' Y$ d2 g) A6 o6 K9 _
1 Z- \4 e+ c0 `/ ^
在串口初始化中有如下调用关系:
9 P$ q4 C' d) Q9 u9 B# q* x( a3 V* `

% X' o4 B6 l" fMX_USART3_UART_Init()àHAL_UART_Init()àUART_SetConfig()àHAL_RCC_GetPCLK1Freq()- E; |! Z  h' P
16.png
图3. 代码内容
7 k7 l* E& u3 Y8 x  }

0 K/ T6 r) D8 @. v  N- c9 x由图 3 中的代码,我们可以看到,这里引用了 D1CorePrescTable 的内容,这里是如何引用的呢?其实是比较巧妙的。2 L( O8 x6 B9 @* n* C3 B) E
. G% B$ G" j- N) C! O( E4 Q
: }4 ?4 E  Z) {5 z- }
我们首先看寄存器中是如何配置的。; K6 n+ ?+ _" k  c
17.png
图4. 寄存器描述
- x) o5 M$ H  M
! f- c. C) {! E% p
寄存器中的 D2PPRE1[2:0]是配置 D2 域中 APB1 的分频系数,默认是 0xx,表示不分频;100 是 1/2 分频;101 是 1/4 分频 ; 以此类推。
; O/ }+ O3 F: T* F; f
; P8 G6 E  |; l- t" F
2 }' W: E" @( q& m
在整个时钟树中的位置如图 5 所示) b0 R) L) L6 ?- K
18.png
图5. 寄存器在时钟树中位置
. F$ i# F. o$ k1 ^; i
" ~$ Z9 `: X2 [1 @0 S: n
回到代码,我们单独截取其中一句话。
# I) ~! V) {" ]! q
19.png
图6. 代码详细内容
3 U8 p$ v$ ?* f  S6 M) N
2 b/ l, J) _- S# T" f3 F, i
其中的数值定义如图 7 所示
+ j* w- ]2 I7 m' Y( s
20.png
图7. 代码定义内容

; r2 X. O2 B$ I, c) ^8 P

. R7 Z  r. T. q这个地方通过读取寄存器(RCC->D2CFGR 中的 D2PPRE1)的配置,就能得到 APB1总线上的时钟分频参数,其先通过函数 HAL_RCC_GetHCLKFreq()得到系统时钟的频率,再将其进行右移操作(右移 1 位代表除以 2)。具体右移多少位就是通过查找 D1CorePrescTable 这个表来决定的。& A  J* `9 e. G' u& ~$ b
6 e" l8 h7 ^8 r% q3 n
: C  M3 J, y5 Z$ q5 z
比如,这里如果是 1/2 分频,那么 RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos 得到的结果就是 0b100,再和 0x1FU 进行“与操作”得到也是 0b100,即十进制的 4。通过正确的 D1CorePrescTable 表格,即可得到 D1CorePrescTable【4】=1,(注意数组是从 0 开始的)那么就是系统时钟进行右移 1 位的操作,得到除以 2 的效果。
# s$ G' l- n& h3 v0 C# q8 D; O
2 l5 M& C- E1 \( b/ s) j1 ?* z5 Z
; b( B% B5 t1 W' w2 q
正确数组:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};7 m9 N% K; W. u- y
  y8 _3 t* z, A# P9 r& _

& N! }& @4 m2 V- C; ~  p* `0 [% y) |错误数组:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};% x2 g' {- o) ]# f) S( f0 l. a

# }# P- w+ O' K( u
7 t, A0 d4 l' N2 |0 D
但是如果是错误的数组,查到的就是 D1CorePrescTable【4】=0,这是不需要右移的,就是没有经过 1/2 分频,显然是不对正确的。( H( P3 Q* p0 l; L. C/ V

5 K1 E  Q( M! I) {0 u
. D+ }0 N  ~* E$ I# ^) @. w
这里还有个小问题:如果在 APB1 的时钟是没有经过分频的,那么 RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos 得到的结果就总是小于 4 的(即 0xx,具体参见图 4),查表得到的结果就都是 0,也是没有问题的。但是1/2,1/4,1/8,1/16 这些分频系数都会出现计算错误,所以正确的方式就是手动修改这个参数即可解决问题。
4 Z" r) [8 `3 E7 S" a+ y+ s- z* V/ F4 q. [/ [( P

6 p. I, ^& z5 _; O3 @3. 解决问题
( }# |% O7 U6 a+ `6 U手动修改 system_stm32h7xx.c 中的数组 D1CorePrescTable 中的【4 :7】中数据即可。
% v% ~& E( s6 \5 o3 O  {. n& w+ u" H/ I9 ]' R
) S7 C/ Q1 I  ^8 c
正确:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
$ w7 w" @1 g  y; C( {/ K' Q
, d- ]. W5 h# M! }5 m
. g! A* P+ B, O# y2 E" R
同时,提交 bugzilla :197431 (此号码为 ST 内部使用,外部用户无法访问)。
% b: b( M9 |  W9 |4 Z
- Z* P- P" g; {$ d4 g" V# p6 \

5 {  u, I5 H5 m6 M: G4. 小结. b2 L6 w' O  B8 y
这个问题,主要是来自时钟计算所需要的表格出错,造成串口波特率计算出来的结果错误。本文简要分析了数组在查表的方式进行的对应运算关系,并对错误范围做出了解释,未来遇到类似的问题都可以使用此方式进行分析。: o# w9 [! C8 `5 p( c
————————————————# N6 `/ Q. T0 F" ~
6 V/ N  @2 \& T, Q! S1 P

  t; m/ [5 h7 i. K- B  ~$ x  B                            % G% f0 q1 b9 G7 v2 i+ S
6 O5 M! H$ w- h$ t! p7 u
收藏 评论0 发布时间:2025-7-30 16:49

举报

0个回答

所属标签

相似技术帖

官网相关资源

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