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

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

[复制链接]
STMCU小助手 发布时间:2022-4-10 16:48
现象复现
3 A' P1 }1 G' A! R( Q7 W. e项目中一个是IAP程序,另一个是APP程序,两个程序都是使用STM32CubeIDE生成,当程序跳转到APP中并且执行到函数SystemClock_Config中的时候,在初始化锁相环调用HAL_RCC_OscConfig函数的时候返回HAL_ERROR或者直接卡死在里面。
8 A: o' [( L9 {) G0 o
7 t& [& S( H$ ]; V5 b为什么在IAP中可以初始化通过,但是在APP中却通不过,查阅STM32F4xx参考手册发现这么一段话:
: k& H& q+ E' S: L" m
3 ?  M% V7 I8 G0 x1 F- X C5)Z[0`UUDFGQYX0P2KB{@E.png
& l$ a# o3 \# f; k
8 ^( K* U) O* r+ G# g那么出现这个问题的原因也就清楚了,因为在IAP中已经初始化了PLL,在APP中再次初始化就不成功。% _! A. t# k: f8 k
1 s$ S9 t' B3 [0 `( V2 x+ j
解决办法9 O& p; J$ [! p& x7 O8 b1 O  C- z
我查找ST官方HAL固件库中对重复配置RCC时钟的时候,发现他是这么做的:
5 j7 N  d  L% |! l  z5 y1.先将时钟源选择为内部时钟
8 s* h. ~  w) D6 d6 v8 i' m  ?1 ~2.初始化锁相环) Y! L1 ~0 x7 p1 Y) m' w5 q" j
3.将时钟源在切换回外部时钟源
* C! H* I% Q- {7 C  j4.禁用内部高速时钟(可选步骤,如果内部高速时钟不用的话,建议禁掉)
8 s0 ^' r. x$ W5 R% }1 X2 P4 a9 s$ z; J
官方代码如下:- {' Q/ |% v7 [% a# b/ L6 T- G3 `
$ {& c0 d0 {: J
CWW59K4%$L~GB`~][c1EN.png - Z% w, C2 q6 v1 N

' A8 B; s! y  ?1 o以下是我的示例代码:
, l% [: i; h8 Z; J3 ]( j  M2 F$ I' b9 m" U$ _
  1. void SystemClock_Config(void)
    3 y2 \9 f9 R0 l% `' B
  2. {
    $ _. A" u' l' r- Z0 k
  3.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    ( K/ X% f9 R5 z4 l: y- J
  4.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};7 t: k2 x1 O2 W
  5. 3 f8 S2 x: K: P
  6.   /** Configure the main internal regulator output voltage" o/ U9 t0 v" a" S# ^0 t
  7.   */) ^0 z; i1 }/ k( m
  8.   __HAL_RCC_PWR_CLK_ENABLE();
    9 ^0 u& g$ R1 Z
  9.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);  {* `3 ^- }  j! E

  10. 3 {" l! L% }( A* i% Z; V* V# T. l
  11.   // 先将时钟源选择为内部时钟1 }4 U( c0 I% e4 r, D# r9 D
  12.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;4 k: a. H' W( z. g, t1 Z5 p2 |
  13.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    2 g8 K- T( A4 @/ @8 G# d8 T
  14.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
    6 r3 ]) s5 x: Z& U0 |9 o
  15.   {4 M/ s: S: E& d  g+ a% m: v9 L
  16.     Error_Handler();
    6 d/ E( @) |& w  K: R" }
  17.   }9 |( x/ s& q# {& i: [8 ~

  18. + \: d! C1 A, r! V; s/ b
  19.   // 初始化锁相环! P  r+ j+ S* ]: \% a2 j% w
  20.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    7 }7 f+ [2 Q6 h
  21.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    7 b6 I7 w9 o% a& m! E
  22.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;, R; B1 S7 Z/ }2 K
  23.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;  ?2 t9 B7 l, j  }
  24.   RCC_OscInitStruct.PLL.PLLM = 4;
    * j3 g4 t3 {" v3 P$ R# o0 h5 E
  25.   RCC_OscInitStruct.PLL.PLLN = 168;
    8 J* q( {. Q: x2 Z# x. _8 W/ k
  26.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;  v) ^7 q% n- C$ h1 m- U( y7 E
  27.   RCC_OscInitStruct.PLL.PLLQ = 4;- G/ |; f/ E/ R* a5 K+ `% O7 V% y
  28.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)8 Z; a+ @1 _. h- |) L
  29.   {
    " d) `8 |/ }5 T! J' r/ W) B
  30.     Error_Handler();
    1 c$ N/ A6 o$ F8 ?
  31.   }
    ! s1 H  h) C5 v$ _& ^$ Z

  32. ) T* D. L* x$ c/ r* W- X) N
  33.   // 锁相环已经初始化完毕了,将时钟源在切换回外部时钟源
    7 z/ C$ v" N$ @# A
  34.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK: w* _( m  T0 g0 E. w% x
  35.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;! f' d9 r% |* {' I7 Y( g' t
  36.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    + ]3 Y+ {. D" u0 ~( {
  37.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    4 R+ q% ?# k! l
  38.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
    7 f0 _1 R( p8 ?6 B2 z
  39.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;$ D  ~5 J% z* V+ e( d# d7 }7 C$ p2 G
  40.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)/ [8 W' k+ @8 b
  41.   {* O8 t1 x- Y  O3 ~1 a/ }
  42.     Error_Handler();
    ; c0 t6 |; U5 D8 c' H
  43.   }% C6 g, q$ i: R+ T# C9 Q1 [  W

  44. 1 d* p$ [! n7 @, t! K. u, c5 A
  45.         // 禁用内部高速时钟
      f& m2 k4 i  D# r7 Y) o
  46.         RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;. T# s; r& Z8 y5 ?' d
  47.         RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
      ]9 N' C$ i4 \; P
  48.         RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;# N. W1 B+ _: l1 Q0 Y# d5 T
  49.         if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    5 Q. `. ^/ G, C+ Q3 a- V' R
  50.         {' w% G9 u4 t( Y# u
  51.           Error_Handler();
    * x5 F9 X5 R" d
  52.         }
    , u: X' C# B/ p% k: `
  53. }
复制代码
. Y3 _7 |9 i* J5 k: L) \
通过以上操作后,问题成功解决!
: |- B- G) |/ o( H9 A! y" W# n9 X7 \
解决F4系列这个问题之后,我又去看F1系列的参考手册,发现:' a3 b* I) s& U$ a; h

6 S6 E9 _' S. s+ }+ r$ T Z~BM4E0%XV9CHOD)9M{EA`A.png
$ n0 b7 M, ~4 y, Y# t/ A
/ B/ ?1 S7 {7 W) J同样的也是需要在使能PLL之前完成时钟配置,不过在实际中发现,F1系列的IAP跳转到APP中并没有卡死在HAL_RCC_OscConfig函数中。
' }6 b# G3 ]3 B2 p* Q
; I4 {/ v; I3 G' ^还有一个更快捷方便的办法,就是在IAP中不使用PLL,直接使用HSE或HSI的8M晶振作为系统时钟,如下图时钟的配置:3 D/ \; l' ]. ~1 u1 D( |6 L

  o" J- u' D. J) F2 G/ v" [" h H0$`KI_NV8G756SU`T6(}]H.png
$ n7 O- G/ t& I5 D, O0 ^; Q' q" C4 \" D

1 n2 U* m, e5 [, g: R, E
9 f. T: `4 P/ q' |6 i$ H
收藏 评论0 发布时间:2022-4-10 16:48

举报

0个回答

所属标签

相似分享

官网相关资源

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