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

【分享】STM32L151晶振掉了~~~

[复制链接]
跟风和天空对话 发布时间:2019-7-8 17:25
最近有个项目,用到STM32L151,原设计者使用外部8MHz晶振。有一天晚上调试过程中,突然发现程序跑不动了,翻到背面瞧见HSE脱落了~~~再用RCC_GetClocksFreq(&RCC_ClockFreq);观察RCC_ClockFreq.SYSCLK_Frequency,只有2.09MHz。手扶着HSE重新上电,单片机运转正常。看来就是它的锅。: s2 c3 e& U4 z% K

4 q+ ^6 H* s7 h* s
% _! y3 u4 s: o( _* `0 I
但是,家里没有电烙铁。
2 \0 X7 E7 ?1 p  o8 j0 I$ o
/ [' ?1 B1 m9 p. O那怎么办呢?只能换用16MHz的HSI了,MSI非整就不考虑了。我从来都只是用SystemInit();初始化的,除了修改一下HSE的频率,从来没碰过里面的其他语句。
& R8 P4 t( q  `* A) _- ^: U' E一开始,我写了一个HSI倍频到32MHz的程序,替换掉.s文件里的SystemInit,结果失败。可能是因为我写的程序本身有问题。2 i" b0 G5 S1 l  d

9 d9 ^6 @0 B' S3 r
1 T! \5 N# K0 }" c6 I
后来想想,不如向SystemInit();里面添加HSE启动失败后的代码。它里面负责将HSE倍频到32MHz的程序是% i+ s- ?# X: i% Y
5 n+ P9 }( e# H! ?$ y/ v3 x

3 D/ v6 i/ D3 V3 P5 g) L/* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */
4 _; i  t. F$ _) i  SetSysClock();$ \) u, r6 G# O; T& C0 o: j
0 G! a" }3 I$ Z/ J/ X% Y  X$ S
+ U; A. n/ ~0 v8 _- {
在它里面,除了详细描述了HSE+PLL的启动方式,还有下列注释:# I) G; c4 M* x$ O) ~
7 W' k% B$ X% R7 G" `" v

  w$ E0 q8 ?4 B! e4 Nif (HSEStatus == (uint32_t)0x01)
8 _9 C3 x* e* L% D5 r' k{
9 J6 ]9 @/ q6 r……省略……& X' L$ v# P7 J0 V$ N. v+ d
}
1 H+ w4 R3 V; y' [! selse) w$ n) E, B& L' }& {7 d
{
) ^, e: U* K$ P5 I0 k    /* If HSE fails to start-up, the application will have wrong clock" m% g& e+ }% Y' A( {( X
       configuration. User can add here some code to deal with this error */
) R  Y  N( [5 ^; W7 y+ w/ r& v. c6 a4 |  b0 ~/ y, h  f( L8 G. f
  //翻译:如果HSE无法启动,程序将以错误的时钟运行。用户可自行添加勘正代码
' R7 z+ p1 e( Y  }9 i: [}4 |8 y4 i1 D; e
/ i/ Z) B7 X" @- Q% v
ST官方竟然提前留好了坑!& z2 V# L: w4 A

. z/ J' F( X) }# }于是,仿照着HSE+PLL启动方式,我写了下面的代码,使用HSI+PLL,并添加到else{}中,观察RCC_ClockFreq.SYSCLK_Frequency=32000000,一次性通过。
9 Q5 z# Z, {/ z  _: |! z/ n

0 a2 Y7 {' I3 O5 \    /* Enable HSI */
  q9 A' z# ~+ u# U0 s' @" G    RCC->CR |= ((uint32_t)RCC_CR_HSION);
5 D$ |1 a0 Q' [1 ?, l# k
2 L4 J3 i3 E$ k    /* Wait till HSI is ready and if Time out is reached exit */$ Y/ T% E: j6 A: A
    do& Z4 f' G( g! h2 q8 g- H
    {1 Y# |; l4 q5 }' T" c: v! w
      HSIStatus = RCC->CR & RCC_CR_HSIRDY;
( g$ Z" H; V, u1 |      StartUpCounter++;
7 k4 G' R1 h  I  G+ J    } while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));& t* Q/ n3 p1 T  x1 d& {8 k

6 f6 u; ]7 k: f7 b    if ((RCC->CR & RCC_CR_HSIRDY) != RESET)
) ?- I. w4 ^9 V7 \+ }! Q) n! a; @    {
' _) L; r* A: S6 z7 _' g      HSIStatus = (uint32_t)0x01;0 S) ]9 z# x! _" U/ h, j) K  g
    }
  X9 W7 P" Z/ X" f+ s; j7 ^1 f% }    else# e* N1 J" O6 B7 ]
    {: s" e% L8 A& B* m, T# {
      HSIStatus = (uint32_t)0x00;
* v' o$ Z2 c& d: Y  \1 q  I    }
5 h$ i' \% g/ u6 i3 r
/ h0 M& _; p, k. A    if (HSIStatus == (uint32_t)0x01)
, C, {& v! G" [# t    {
8 F: Q2 @* E. J  `3 S( \4 u- i      /* Turn OFF the HSE oscillator */6 f& x2 V# x: R" k. \% w) n
      RCC_HSEConfig( RCC_HSE_OFF );
; @6 L" u6 M& o1 \9 |* B' v, f) r7 x! Y  I
      /* Enable 64-bit access */6 ^; [& Z# Y# L2 }
      FLASH->ACR |= FLASH_ACR_ACC64;2 i( L  K' N1 I6 h; F
- W) p0 e+ K5 P  j: T# L
      /* Enable Prefetch Buffer */
; ?0 P3 {' P8 X4 V      FLASH->ACR |= FLASH_ACR_PRFTEN;  H9 |8 U9 T! y7 o* B  a
7 ~! @2 ~8 o) S& C+ j. X# b7 e$ c
      /* Flash 1 wait state */
9 I; R& a, \" k( `. o      FLASH->ACR |= FLASH_ACR_LATENCY;0 |# R' h1 W4 H4 d# `- B& X
& `! X& I$ _9 N5 V+ C$ R
      /* Power enable */
- A0 j0 w8 c6 C( x8 B# m- ^      RCC->APB1ENR |= RCC_APB1ENR_PWREN;' [. F: [. Z% G/ [& ^- P- S

7 [# p& a7 j: D: }- a      /* Select the Voltage Range 1 (1.8 V) */
. M+ l" P2 _5 {2 C, E- }! i      PWR->CR = PWR_CR_VOS_0;
% u( X' r. ^- y! m- v9 y! r6 ?) q+ i: |: |
      /* Wait Until the Voltage Regulator is ready */
+ o, A0 {5 G+ g  W  F  o8 {+ x      while((PWR->CSR & PWR_CSR_VOSF) != RESET)
$ U0 m  ~2 S/ Z& j3 u      {
+ [0 v0 v, G/ l3 b( G9 Z      }
0 p% e, u; o( o& @- i
& G2 D( x* N3 X1 f3 [/ \1 i9 z; z" R      /* HCLK = SYSCLK /1*/1 b$ d9 E; u! x
      RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
; T/ L% O+ p7 T9 p) |
1 E: o1 x% Z9 V$ }5 w% s" I, T      /* PCLK2 = HCLK /1*/( Q5 p: i2 M0 ]! A$ {8 `, p, c
      RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
1 |7 I5 V7 _( s/ m; r7 F; V- s( {- o
      /* PCLK1 = HCLK /1*/
* M. a; T- _  U% \8 ]      RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;' k/ K# ^- a2 I' d
2 y2 j! O6 P  r1 Q- V& r- n% u
      /*  PLL configuration */
% \- x1 r4 }# P- p. }6 A# {      RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL |
  Z7 S! p# B( g7 [* ~                                          RCC_CFGR_PLLDIV));
- q* I3 I1 O! f8 J) P; j! p      RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI | RCC_CFGR_PLLMUL4 | RCC_CFGR_PLLDIV2);
8 O) L! [8 O/ V' g% P8 K0 Y/ C( b' c1 n6 C) ?! x; P
      /* Enable PLL */
, {9 {) R: P5 r5 E0 H. C4 M      RCC->CR |= RCC_CR_PLLON;0 {- B0 W) N$ O1 X& k7 m

. n- q$ T; {6 E+ s- W2 x. {9 |      /* Wait till PLL is ready */
( M: B7 t$ V8 O3 K& _0 J* Q8 t/ P/ X      while((RCC->CR & RCC_CR_PLLRDY) == 0)
* p3 m) c! o" X* D0 q; W      {
- t1 W: C% [  N5 `  L      }
# d3 H0 m1 \$ `' x% C4 z% J6 I. d5 I. J* z1 g& P: c
      /* Select PLL as system clock source */; E" A/ J- g' A& y
      RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
9 V# i7 E0 C, C" n  z      RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
+ N3 h, E0 H$ x! d6 [" Y8 B+ y; Z; G# M, W6 W& ]
      /* Wait till PLL is used as system clock source */
% ~( B" j* c7 O5 y      while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)+ n' g( N. ^9 n. O
      {
' Q9 d" ?! o( {& a) N6 ~" {      }   
! b8 V) `$ v; d4 `1 u  T& `    }
; E/ i2 A' ~- M9 f$ E/ r4 p# h
3 E* S1 h6 T, X3 p! _9 T7 h* K9 a! ~7 L5 a/ Z# Y

* Z" s, P; i; s% V! t3 p. d记得在static void SetSysClock(void)的第一行添加HSIStatus的定义,即:
) ]+ g* j! \% q
__IO uint32_t StartUpCounter = 0, HSEStatus = 0, HSIStatus = 0;
  a  [" q; ~& `0 A8 C/ M

& j! i# l2 e  [5 z/ Y0 E
收藏 评论0 发布时间:2019-7-8 17:25

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版