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

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

[复制链接]
STMCU小助手 发布时间:2022-4-10 16:48
现象复现! x* P$ d+ t3 R6 {/ Y
项目中一个是IAP程序,另一个是APP程序,两个程序都是使用STM32CubeIDE生成,当程序跳转到APP中并且执行到函数SystemClock_Config中的时候,在初始化锁相环调用HAL_RCC_OscConfig函数的时候返回HAL_ERROR或者直接卡死在里面。* j, O& m6 D. F6 C1 z/ M1 ~
9 N1 l  Q/ l) n& O( l! R
为什么在IAP中可以初始化通过,但是在APP中却通不过,查阅STM32F4xx参考手册发现这么一段话:& D( n" ?8 t7 K
+ J: ?: e+ p, P0 I& P
C5)Z[0`UUDFGQYX0P2KB{@E.png 3 L' D" T( P* t8 d- C

; c- z, W2 \6 b; u那么出现这个问题的原因也就清楚了,因为在IAP中已经初始化了PLL,在APP中再次初始化就不成功。% L/ f% L4 D1 ^5 n4 ?! a
: H2 g  h4 b5 n2 K
解决办法( e! C: T* [6 k+ {0 R0 p; _& q1 h, @4 L
我查找ST官方HAL固件库中对重复配置RCC时钟的时候,发现他是这么做的:
1 M- j; U) e, S8 i9 }$ N1.先将时钟源选择为内部时钟4 y0 g; x; v* k2 W2 B4 n; L6 i
2.初始化锁相环
# e5 Q1 }" ?" w3.将时钟源在切换回外部时钟源) s& G/ r; D9 R
4.禁用内部高速时钟(可选步骤,如果内部高速时钟不用的话,建议禁掉)/ m  V/ ], A, `- ]
! c7 t, z: E0 C; D& i8 n5 J( e
官方代码如下:
7 r+ ~0 b% _( q4 S. C$ |; b+ ]
% w5 a3 j' N5 A- ?; n CWW59K4%$L~GB`~][c1EN.png 2 Y3 Y, o: G& g4 h
  J4 u3 W+ h+ f# W; j  D/ `
以下是我的示例代码:
4 p: M  n& `+ O. J
) f2 H. p; d( n3 p* i
  1. void SystemClock_Config(void)1 m  {0 E5 ]/ W" ?
  2. {- G, y$ I! {7 h9 m. b5 _( l1 O) R
  3.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};& l/ {# d' _" X$ D
  4.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};4 b/ t" w$ W5 e+ G( W+ \1 }# {' [8 L

  5. 9 x% X( _3 g1 E5 I- }* ]( a
  6.   /** Configure the main internal regulator output voltage" J, s+ z7 T1 R% v+ z; `
  7.   */
    2 J2 F( @- b1 ~5 D
  8.   __HAL_RCC_PWR_CLK_ENABLE();
    . K% ]. {9 D2 q
  9.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    ' j4 B+ U0 F; {. b+ }

  10. 2 E& j3 q) w* N/ |) c
  11.   // 先将时钟源选择为内部时钟5 {+ |9 N2 ?) q7 {1 F/ Y
  12.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;: v7 v3 h( W* W" K  s7 T
  13.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    . I2 _5 p7 l+ }! b
  14.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
    % w8 s2 y: H. k% v1 m
  15.   {5 H" Y6 N1 F2 z' u& [, K
  16.     Error_Handler();
    & i. [1 T; R0 y- i% T* Y
  17.   }- ?2 Z- N9 N4 `. i+ ]1 h6 O
  18. + b+ [3 S+ t6 i* q0 v5 R  O/ i6 b
  19.   // 初始化锁相环4 A0 G9 g- U0 ]  Q1 ~0 x
  20.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    0 h+ o! k% m4 p8 k
  21.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    ( ^1 ~) }9 j7 x, u9 ]
  22.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    + f: y$ @5 s+ ]! ^/ A% ~4 u
  23.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;0 M0 s; {  l4 q7 h) c
  24.   RCC_OscInitStruct.PLL.PLLM = 4;; ~. _4 u. o' \' {9 ~8 n
  25.   RCC_OscInitStruct.PLL.PLLN = 168;9 i4 w1 a+ V) d4 r4 Q' z  W
  26.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;" s3 W8 {2 Q0 J0 ]! ?
  27.   RCC_OscInitStruct.PLL.PLLQ = 4;: j; c7 A  w- k2 u3 j9 p. O
  28.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)# b* b: O/ q' O1 q# N
  29.   {! g. n# f/ G6 j5 a. h
  30.     Error_Handler();
    1 u( ?% a$ P8 y
  31.   }0 {! U! p! H! k& Q* \8 `' z

  32. 4 t  v& W; j6 `& ?7 h' H
  33.   // 锁相环已经初始化完毕了,将时钟源在切换回外部时钟源
    3 y2 c9 G7 o: i/ b  U+ \7 S- ^
  34.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK/ s5 ]$ _- L- @+ V: T
  35.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    ) w7 A- V* U4 G. a& q. Z
  36.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;; O7 [* X1 ^4 [1 [, W* ]& n! _+ l
  37.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    % X! D- y3 B* j, m+ L( E
  38.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;+ F2 G6 `# G+ p* X9 n5 h3 ~
  39.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;1 v# Z# k1 r$ ~6 u, B+ d
  40.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
    3 t. E* R5 u# B) ?
  41.   {
      X# d0 M2 t9 m: {% e! `
  42.     Error_Handler();
    1 M" M2 @) `4 T1 ^* p
  43.   }
    # e/ Q$ c( r4 f  s

  44. 3 n* F, o* A0 T
  45.         // 禁用内部高速时钟5 U2 Y  y$ i' q9 K: `
  46.         RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
      {% s" m7 O( E, n
  47.         RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
      f$ P3 {% _# t: K' e( Y9 Z" N
  48.         RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;' ^6 A, V; O: q( C" P, i* p
  49.         if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)4 v. k: O  Q( O4 Z  `9 s
  50.         {
    . b$ V( \# U; o% O
  51.           Error_Handler();: H# o# Q  }0 J* v$ E
  52.         }  D7 p( n- c( o9 j0 {
  53. }
复制代码
2 A% M0 V5 @+ O
通过以上操作后,问题成功解决!4 _  ]9 r5 u+ Y! _& J' K$ z

! \. q. s0 u( d( u3 Y解决F4系列这个问题之后,我又去看F1系列的参考手册,发现:
- E# a8 d" {$ Z) q
2 E" S) M2 X% D7 O8 {* w/ k1 W: N Z~BM4E0%XV9CHOD)9M{EA`A.png + D( c9 W2 u# P: S1 i6 u. @
8 A/ [2 K) t/ F+ T+ c+ b$ B( a
同样的也是需要在使能PLL之前完成时钟配置,不过在实际中发现,F1系列的IAP跳转到APP中并没有卡死在HAL_RCC_OscConfig函数中。4 b( Q. s; o6 _3 [& Q
7 |$ z; F" ]% u$ g0 J
还有一个更快捷方便的办法,就是在IAP中不使用PLL,直接使用HSE或HSI的8M晶振作为系统时钟,如下图时钟的配置:
* h- k( e! r$ q6 }) W' |
1 {' m" x: F" {' ^8 z% l  B0 Q H0$`KI_NV8G756SU`T6(}]H.png 0 v# k2 l* }6 [9 K- e& }
2 }- M2 |9 `0 f( ?% B
0 Z3 F+ X$ J0 E4 M% k
4 w) V; {/ m3 j' C
收藏 评论0 发布时间:2022-4-10 16:48

举报

0个回答

所属标签

相似技术帖

官网相关资源

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