本帖最后由 wenyangzeng 于 2017-12-2 22:00 编辑 ( b8 ~' l4 U& L% G n* G+ ?9 q$ m6 X% |
# [9 e9 c/ L8 h3 E9 ~8 ^" D; s9 m STM32F407VG使用固件库进行串行通讯波特率出错故障的排除
( {6 |: `) O$ s5 {7 Z( x+ C
& @7 t/ A/ f' d7 ` 芯片型号: STM32F407VG,与上位机串口通讯交换数据:
1 E; N: x# A/ z, j' c( ?/ b, X 系统时钟:外部晶振8MHZ,倍频到168MHZ;3 b% U; x7 o7 T0 W4 N2 L8 j$ S
固件库:stm32f4xx_DSP_StdPeriph_Lib_V1.8.0;8 p0 v% U C5 ]' m2 f8 h
在MDK5中运行stm32f4xx_DSP_StdPeriph_Lib_V1.8.0串口通讯,结果发现串口发送和接收数据都是乱码;8 q2 o' M. Y# K
: n; S0 v P; Q故障分析:
- Z$ j1 D4 p) K V; o4 e1 H 打开system.stm32f4xx.c关于时钟配置的说明:( P6 h/ e. k5 ^4 U& z& O& L
- * Supported STM32F40xxx/41xxx devices
% Z8 V" c9 C! d+ A0 s9 x - *-----------------------------------------------------------------------------
& D& W4 q, E* M9 x) p - * System Clock source | PLL (HSE)
) ^; @4 T0 s1 D - *-----------------------------------------------------------------------------8 U1 J# Y" x/ [, v
- * SYSCLK(Hz) | 168000000
8 ~9 O. ~: s4 p1 ~& e - *-----------------------------------------------------------------------------
5 U6 p* Q; _7 t; ^) A7 w - * HCLK(Hz) | 168000000
1 F! t$ Y* f. ^ - *-----------------------------------------------------------------------------. @, _- P# r* I# n' `) m& ~
- * AHB Prescaler | 16 }0 r7 X5 f0 C
- *-----------------------------------------------------------------------------
1 w# \! E3 @4 d4 k0 x/ h9 T - * APB1 Prescaler | 4- i$ D" W! H7 Q. X+ O
- *-----------------------------------------------------------------------------
+ X9 c0 ? c" W# M: c6 W - * APB2 Prescaler | 2
. c. o p1 w. C7 Z% \ - *-----------------------------------------------------------------------------6 |( e E3 S% z
- * HSE Frequency(Hz) | 25000000
2 i( {3 [/ ^9 _% J4 {+ w0 e, L - *-----------------------------------------------------------------------------
6 T+ ]9 F: e9 G: a/ X - * PLL_M | 25
1 }) y; S' k7 _+ G - *-----------------------------------------------------------------------------, N( l( ?/ v6 L2 Z5 P& w# E5 d
- * PLL_N | 336
' T9 s' B2 Z! k0 z( d: k% q$ s - *-----------------------------------------------------------------------------
+ U2 h8 M7 _) }" S" r, f, ^ - * PLL_P | 2) J! T* B% m; {8 S
- *-----------------------------------------------------------------------------
, ]' c4 ?; R3 n3 ?9 z6 c" f6 j6 i - * PLL_Q | 7+ J% p8 |+ i* D) F+ u5 A" Y
- *-----------------------------------------------------------------------------
复制代码 从说明中可知stm32f4xx_DSP_StdPeriph_Lib_V1.8.0演示代码中对于STM32F40xxx/41xxx系列芯片系统时钟的默认配置如下:
7 ^7 m5 D0 ]% f% e' h( c, V
. }# W8 D9 }2 i! l1 A. I! d& fHSE Frequency(Hz) : 使用外部25MHZ晶振;
$ N9 _/ P' {( CSystem Clock source: PLL (HSE),
. G3 `* {8 a* o& nSYSCLK : 168MHZ.6 \' ]% v# C2 X8 B k7 k4 M4 g8 u
PLL_M :256 ?9 B3 M Q6 Z
PLL_N :336
; Y n, p- I7 _# sPLL_P :2
7 u% ^; Q' V" x* A: W# j: {PLL_Q :7; R% q& o7 W- u! ^6 h# }. w
由于实际使用的晶振为8MHZ,按照默认的时钟配置当然无法得到正确的波特率,从而导致串口通讯失败。
" H. E- h- o! n3 o }: c( l解决方法:
2 n+ A$ H# P( h5 o; k G借助STM32CubeMX,可以方便地配置系统时钟:
; v0 b' o+ i4 T* j7 M- n
* }& d1 V8 h6 Z: o
$ y5 p3 M" G- i1 A! q: Z y5 e+ B3 W; K& A
根据上图配置系统时钟所需正确参数:, `2 L6 c8 Z' _* D/ } x# a
M=4 ( PLL_M). Q2 A) B7 x4 J' Z1 A# ~( w! {
N=168 (PLL_N)
3 p1 ]6 d) r4 ^; H5 R) d( C( Y5 }P=2 (PLL_P), G" ?7 b( Z+ l6 o
Q=4 (PLL_Q)
: Y0 `& o$ I( N6 t- w9 d' X1 ]( v1 @% ?# H5 o2 d
接下来修改相关文件:2 E, P' J' _4 b7 \
1、在stm32f4xx.h的70行定义芯片型号:
, `4 h. q5 o$ E9 s" p& o2 q1 f, W2 b I/ c, l; M
' \2 ?8 P3 j9 b7 ?- ^
# Z) e: B! F7 E& B5 q& o# l3 L) Z8 F
4 f& o" j) Z$ _: G- i: s6 n5 t/ f
2、在stm32f4xx.h的144行定义晶振频率
9 A% x, k9 e1 g* P" m s- #define HSE_VALUE ((uint32_t)8000000)
复制代码
( O7 x! Y* f9 d' s/ Z9 R! q5 s
( f2 Z* ?& U% n* ~( H6 P% n: ?$ d1 t. E% A/ D. z* R) T& v# `$ X i# z
3、在system_stm32f4xx.c中修改
& I! C: k f8 y, v1 X# v371行0 N6 _% R* ]3 V: G% A$ @4 Y, g* D' s- s
7 `6 F" N% d; K3 G6 k$ I( k. c
t, u& M& l% N8 D! Z# W384行$ W" E- l2 |! _
# {7 g. @1 q4 v0 j
( H; e8 d+ G# N. e, r401行. g2 F2 ?* r) f9 k) E1 S0 l4 f3 K
% D. H0 ?9 i) S& T: a3 V/ F3 s
, y* M# u0 v0 c" A. y7 o4 x 经过以上修改,编译运行,串口通讯工作正常。
6 { o7 E+ c% h/ N$ S总结:在使用ST传统固件库开发产品过程中,当目标板使用与ST固件库默认值不同的外部晶振时,不能一味拿来就用。应该认真阅读ST官方关于固件库的说明,及时修改相关参数,才能避免多走弯路。7 l# Z* [: T0 C( D5 J
N9 Q9 ]( I+ S8 f% g& S3 A
# p- i1 T; {7 d |
MARK 谢谢 小白学习了。但自己的回复怎么下次找不到呢?