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

【经验分享】STM32实战项目:HAL_RCC_OscConfig中程序卡死问题解决办法

[复制链接]
STMCU小助手 发布时间:2022-4-10 16:48
现象复现
- {. Z9 H9 t0 J+ r2 [; Q项目中一个是IAP程序,另一个是APP程序,两个程序都是使用STM32CubeIDE生成,当程序跳转到APP中并且执行到函数SystemClock_Config中的时候,在初始化锁相环调用HAL_RCC_OscConfig函数的时候返回HAL_ERROR或者直接卡死在里面。
$ }" p1 x/ ~7 }  f3 v( J! j+ z- x
为什么在IAP中可以初始化通过,但是在APP中却通不过,查阅STM32F4xx参考手册发现这么一段话:
; O3 K$ y, O+ q8 c1 @5 v) F; H+ v4 q. R# I1 I& Q
C5)Z[0`UUDFGQYX0P2KB{@E.png
! V8 S  x5 u1 q% K: e
- f2 ]: u$ N! r5 ]! H6 t那么出现这个问题的原因也就清楚了,因为在IAP中已经初始化了PLL,在APP中再次初始化就不成功。
* |' h8 v- n/ `2 r7 O
  E/ A! }/ f- }/ j/ Y* h8 E解决办法( ]5 l4 [9 i/ D! Y
我查找ST官方HAL固件库中对重复配置RCC时钟的时候,发现他是这么做的:3 \/ u; D3 d6 k: Q
1.先将时钟源选择为内部时钟
) }" E7 f# N  t- B: Y& u7 C2.初始化锁相环7 B- n4 [( W8 P& l7 [9 q/ h; `
3.将时钟源在切换回外部时钟源
) g, Z% s5 I5 Z( N4.禁用内部高速时钟(可选步骤,如果内部高速时钟不用的话,建议禁掉)
$ ~$ }! u; P) p: X( ~9 |* Y* ]9 ?* W. Y" Y; e; ?  K7 x" G/ G
官方代码如下:$ _7 ^4 j) i+ k: @* V+ N) r4 T% p

- h6 i) {) E7 C  {3 d# {- x. A& H CWW59K4%$L~GB`~][c1EN.png
( O/ S4 a2 {- V9 Q3 W$ t( q: u3 K  e6 J1 @  y4 e/ w7 `
以下是我的示例代码:
+ P  j0 ~2 r1 b) @' I" b2 ^4 w) L. |9 u1 f  a( T
  1. void SystemClock_Config(void)  h4 _$ ]9 }  G9 n
  2. {
    0 o2 N2 _! g( s  Q
  3.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};; }  S. a' p. B+ `  S
  4.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};: U$ u, l0 `: W# E; j/ F6 n
  5. 0 Q7 f# `$ `2 r% E) N  B4 b9 l
  6.   /** Configure the main internal regulator output voltage
    . E$ x2 f! J+ h% \3 F: j
  7.   */
    9 [( `/ L+ G: G  W) Z/ b9 o1 {
  8.   __HAL_RCC_PWR_CLK_ENABLE();
    ' L' e1 l/ q9 n% |
  9.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    ; _1 ~8 K7 ]: @" z

  10. ) |7 M: M; R$ g) m5 i& h; I8 a
  11.   // 先将时钟源选择为内部时钟" F1 E# a# C% a1 c1 q2 ~* v
  12.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
    , D* h, w7 x8 G; ?4 C! o
  13.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;) o/ f9 t0 P. l$ ~, l, Q
  14.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
    9 s1 L# ^9 h  f, E# \, x
  15.   {
    % u2 A9 }; t! U! b) m8 W
  16.     Error_Handler();
    5 _% C) C* M9 S* Y. [1 B* f+ a
  17.   }
      w+ E* M0 w: L, F+ a7 X9 u( |
  18. % v5 h* y9 J3 L) j
  19.   // 初始化锁相环+ g/ a( a9 a- F+ g" R5 x4 ~
  20.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;* s7 F$ H! i+ ^
  21.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;& p: V; p: [* ~5 m9 U$ a
  22.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    # `0 k0 S8 }5 o0 G
  23.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    & A/ g0 C0 y; g% Z) J
  24.   RCC_OscInitStruct.PLL.PLLM = 4;
    - [, _, Y# D0 Q# p0 ^) M/ a* A
  25.   RCC_OscInitStruct.PLL.PLLN = 168;- ~6 s: B+ `8 a2 R8 H
  26.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    ' ]" N; D# a2 P# j1 a! y
  27.   RCC_OscInitStruct.PLL.PLLQ = 4;
    / `! H" V, F$ V; T* d+ [: _
  28.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)0 s- k: f& N( ^6 K' O) x
  29.   {
    8 \; B' o; ]4 w9 D9 r
  30.     Error_Handler();
    * O% a4 m. ?3 g5 r. z% `
  31.   }7 g) d* I& L3 k$ D  ~4 F8 [

  32. 8 d% n, l* D8 }& F8 f' ]
  33.   // 锁相环已经初始化完毕了,将时钟源在切换回外部时钟源
    6 i, ^( d6 f0 j9 ~8 Y$ ~0 ~
  34.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK0 @- z7 Z4 }( k0 t* E
  35.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    4 F, m. |  L% `. N+ t
  36.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;: T# T" r' q4 g! e/ P* o, k0 W
  37.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    7 G) X- T( I1 L
  38.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
    3 f5 a& Y2 i! g
  39.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
    7 d, k! i/ r8 J9 E) D- @
  40.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)8 Y! p5 Y) ?/ k7 g4 f% x
  41.   {
    , N* M7 l+ [, D  \5 A% w" v
  42.     Error_Handler();
    ; c: h! [' g' X: u! Z5 l
  43.   }5 x+ Y$ H7 y* J  _  B' J! `7 L

  44.   ^: Z2 d; u3 w7 }
  45.         // 禁用内部高速时钟
    3 b& r+ l% V  z4 r" J* b
  46.         RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;0 s8 Q4 y& E8 F, E$ u
  47.         RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
    4 \0 ?! b( ], k/ B  \
  48.         RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;9 }& j! W$ f8 p( V' T
  49.         if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    7 t- u/ d7 O& V6 v# [
  50.         {
    : ]. c; u7 D% s, q
  51.           Error_Handler();
    + |# N6 p% F# w; }
  52.         }
    1 g% t/ {% Y; [* N' A
  53. }
复制代码

( u# }7 i# y! P- z通过以上操作后,问题成功解决!
* I8 o( g# O$ I8 [: _+ y
! j8 E" I1 q6 C" {3 ^( a解决F4系列这个问题之后,我又去看F1系列的参考手册,发现:: ?% a% ^" R* k& W+ K5 y
0 l# @3 r# E7 @& J& R. n+ N
Z~BM4E0%XV9CHOD)9M{EA`A.png
" j7 }( l, [; @* O9 p% }) x! Z, w# q9 q! I' ^% a" M
同样的也是需要在使能PLL之前完成时钟配置,不过在实际中发现,F1系列的IAP跳转到APP中并没有卡死在HAL_RCC_OscConfig函数中。
. {9 q0 m% W0 C' R. J0 c0 J
3 z, k) L' m9 d* K还有一个更快捷方便的办法,就是在IAP中不使用PLL,直接使用HSE或HSI的8M晶振作为系统时钟,如下图时钟的配置:
: B+ h  T  R8 l" ^7 a9 [- }% A6 o7 y' G
H0$`KI_NV8G756SU`T6(}]H.png ! z; B. f( t& |  u. ]1 B

$ V# Y* M" i4 R( a
& x! ^; y' f! X+ j5 l7 ]
  m2 L; ?) ?9 R3 r6 J' H, @
赞 收藏 评论0 发布时间:2022-4-10 16:48

举报

0个回答

所属标签

相似技术帖

官网相关资源

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