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

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

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

' l, P: D6 u  ^

* i9 a* l3 @# @; }1. 问题
% }  \6 T0 X! K) [# O  l* n  wSTM32CubeMX 升级到了 V6.13.0 ,与此同时 STM32Cube_FW_H7 也升级到了 V1.12.0 ,在时钟获取数组的定义中出现了问题,造成的问题现象是串口输出内容乱码,经过和 V6.12.1+ STM32Cube_FW_H7_V1.11.2 生成的代码对比,发现是时钟获取函数的数组出现的问题,修改之后即可正常。
# g  e: g6 c+ s
9 V; j/ g, |! v

( Z% w; p4 m! C) m& g6 W2 z' G/ S$ t2. 如何复现
; q3 Z/ c: {( I( a# S+ v' q在 ST 官网上下载 STM32CubeMX 6.13.0 链接:Here,选择器件型号为 STM32H743ZIT6,使能 USART3 这个外设,选择使用 STM32Cube_FW_H7_V1.12.0 库来生成代码之后,串口打印出来的内容就是乱码。
5 g% ?" N. K6 J3 g7 @; j( d, U; Y; h, F
$ Z6 |4 j& u  L! g) ^* S
时钟配置如下图 1 所示。/ h, g8 I9 R! A8 d; e- q
14.png
图1. 默认时钟配置

: U" z& {3 K& h* P+ ?# M
2.1. 代码分析& i. O8 n2 h' r5 v% {" b; n
首先,让我们看一下,不同的版本在生成代码中的主要区别,主要是 D1CorePrescTable 这个数组的内容有变化。
+ T5 F. I& n  w8 j2 M9 L  Y3 g
15.png
图2. 生成代码对比

( x" O# `- V( g7 \' {+ j3 `) ~+ R! h

2 F5 @/ q( F; f4 r由上图可见,数组 D1CorePrescTable 的【4 : 7】内容由原来的{1,2,3,4}变成了 {0,0,0,0},那么这个数组是做什么用的,又为什么会对串口有影响呢?让我们来分析一下代码。+ J, O5 f+ k, _* S9 r+ P7 y3 }$ _) Z
0 t* F7 c# X1 e4 x& B

0 l" S0 _3 b+ x3 h' F在串口初始化中有如下调用关系:' Q, V, u9 J  z- r$ t: C2 v2 q) s

3 m! E# t) f& W/ e- U) U
4 L: T, s! ]& u  [
MX_USART3_UART_Init()àHAL_UART_Init()àUART_SetConfig()àHAL_RCC_GetPCLK1Freq()! v; E) W4 h7 z& S
16.png
图3. 代码内容
+ V5 i) p/ J7 k  @) B

- g1 T9 f4 J4 j0 v6 _由图 3 中的代码,我们可以看到,这里引用了 D1CorePrescTable 的内容,这里是如何引用的呢?其实是比较巧妙的。  Z! v( }) S- @5 k

+ A( X. w  [* S+ ^( ?

0 e. R( g. O& [我们首先看寄存器中是如何配置的。
( s/ c* G  p1 e) L9 d
17.png
图4. 寄存器描述

: y2 M; h: K4 `* K9 [9 T& R% c

/ y' ?% i8 `& Z4 h寄存器中的 D2PPRE1[2:0]是配置 D2 域中 APB1 的分频系数,默认是 0xx,表示不分频;100 是 1/2 分频;101 是 1/4 分频 ; 以此类推。
1 {/ Q& g; n9 A, Z3 B, h
2 S6 O5 D% Q4 o9 j) e$ D* H" T. h

, U/ e, a3 w$ |! R: y在整个时钟树中的位置如图 5 所示; U$ x0 P( W6 H" @$ U- r, J) [
18.png
图5. 寄存器在时钟树中位置

+ d# w9 ?* o6 o% S8 x

" Y: M" F, Z- s& T3 q9 Y& c回到代码,我们单独截取其中一句话。
" m1 ]3 L# ]0 h6 d4 d  \
19.png
图6. 代码详细内容

; w. g: R6 ?/ U# S

( w& i7 h6 [: o3 n+ Y其中的数值定义如图 7 所示, O& q+ Z5 O/ `4 a1 a9 d
20.png
图7. 代码定义内容
) k+ ^7 O5 i" R2 Q9 x2 K
! }: Y) j, A9 Q) p$ j; u
这个地方通过读取寄存器(RCC->D2CFGR 中的 D2PPRE1)的配置,就能得到 APB1总线上的时钟分频参数,其先通过函数 HAL_RCC_GetHCLKFreq()得到系统时钟的频率,再将其进行右移操作(右移 1 位代表除以 2)。具体右移多少位就是通过查找 D1CorePrescTable 这个表来决定的。
1 q: V4 G; ^6 b) l& n
$ d* F( k" d. s9 k; |1 t

# o$ ^4 ]  X- G6 Z9 K" n9 B比如,这里如果是 1/2 分频,那么 RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos 得到的结果就是 0b100,再和 0x1FU 进行“与操作”得到也是 0b100,即十进制的 4。通过正确的 D1CorePrescTable 表格,即可得到 D1CorePrescTable【4】=1,(注意数组是从 0 开始的)那么就是系统时钟进行右移 1 位的操作,得到除以 2 的效果。
3 Q. l( s7 ?0 ?( ^& h1 }2 J5 R
* ~( k) e8 E* \0 Z9 Q# X
8 b/ ^7 T" |' {' a5 r
正确数组:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};( }% x; j9 C/ N

: K) x6 B: {$ i4 Y; t. E* ~
+ r% X& J3 e. u# r4 l! _' t2 J
错误数组:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};7 b7 |' S6 P, N

0 r" ~9 }6 t! \/ V$ o

  `  P6 e& |. s但是如果是错误的数组,查到的就是 D1CorePrescTable【4】=0,这是不需要右移的,就是没有经过 1/2 分频,显然是不对正确的。
8 `& j  a1 q: b. D) P- Q' y2 D. S' z  ^$ p3 ?3 R2 Z  a$ S

! `5 h( v, w+ I, b+ W这里还有个小问题:如果在 APB1 的时钟是没有经过分频的,那么 RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos 得到的结果就总是小于 4 的(即 0xx,具体参见图 4),查表得到的结果就都是 0,也是没有问题的。但是1/2,1/4,1/8,1/16 这些分频系数都会出现计算错误,所以正确的方式就是手动修改这个参数即可解决问题。
& a. D) o, K( g. A& S& o& S) `9 K9 d7 e8 A" Z. F4 ^+ `( B
! [" z( g! m9 k/ V+ o6 |
3. 解决问题
: t: O/ }9 b$ k3 p4 l手动修改 system_stm32h7xx.c 中的数组 D1CorePrescTable 中的【4 :7】中数据即可。
* ~) u; n+ L" `  i
5 G" \8 ?7 E, f8 X5 A9 D( e

- S, z( N; I" R! V% `* P正确:const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
( V" L* Y; Y* W
2 t  \1 F4 @5 y
: i& B% e) Z+ i9 h7 k6 |/ Z8 g
同时,提交 bugzilla :197431 (此号码为 ST 内部使用,外部用户无法访问)。3 s$ @6 w, q2 V; r, O% M

/ V$ F! J4 u. i4 J
. w% N) C9 H. o" N
4. 小结7 ~  g9 P( c0 l
这个问题,主要是来自时钟计算所需要的表格出错,造成串口波特率计算出来的结果错误。本文简要分析了数组在查表的方式进行的对应运算关系,并对错误范围做出了解释,未来遇到类似的问题都可以使用此方式进行分析。. R! _5 [: e) D$ i+ O; K
————————————————# j' v0 o* \  W/ }3 O2 q

5 d+ C- a) E  k; y" a7 J

1 N9 C, X; P3 y3 s! f* [* V                            , j% S# A# l- x" Y+ w) ^
7 S7 \; Q& u0 a# _. l
赞 收藏 评论0 发布时间:2025-7-30 16:49

举报

0个回答

所属标签

相似技术帖

官网相关资源

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