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

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

[复制链接]
跟风和天空对话 发布时间:2019-7-8 17:25
最近有个项目,用到STM32L151,原设计者使用外部8MHz晶振。有一天晚上调试过程中,突然发现程序跑不动了,翻到背面瞧见HSE脱落了~~~再用RCC_GetClocksFreq(&RCC_ClockFreq);观察RCC_ClockFreq.SYSCLK_Frequency,只有2.09MHz。手扶着HSE重新上电,单片机运转正常。看来就是它的锅。
( ]. y2 W& C# I2 q  s7 u% f' w) p1 i) O9 R
( E+ p5 `  x. q/ f3 V
但是,家里没有电烙铁。! ], B0 n  `5 r2 i& ^6 k$ w
9 s" [8 X$ ?, A: F9 o. [1 B
那怎么办呢?只能换用16MHz的HSI了,MSI非整就不考虑了。我从来都只是用SystemInit();初始化的,除了修改一下HSE的频率,从来没碰过里面的其他语句。
! I7 l  b4 ?$ a/ @- T; t" Z一开始,我写了一个HSI倍频到32MHz的程序,替换掉.s文件里的SystemInit,结果失败。可能是因为我写的程序本身有问题。
1 q6 O6 Q; h! f4 [
5 s/ Z/ n4 C+ ^
. D5 l. w& e" Y% a1 j
后来想想,不如向SystemInit();里面添加HSE启动失败后的代码。它里面负责将HSE倍频到32MHz的程序是/ E% X1 s3 i3 W
% {6 ?& a9 y- g" G. N

3 x* s4 b9 {( @% E/* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */
+ H: u) g  u  ?4 H  SetSysClock();9 `2 Y( z* @! x2 o: d

) l# t4 M; Z" I% H5 I, k$ t
) m$ g  g4 r  c0 {! N# {4 O在它里面,除了详细描述了HSE+PLL的启动方式,还有下列注释:
6 Q6 o8 W/ K0 v  a# s6 q
  n. k3 ~- ^& w" p2 X; n+ D
; I( {& s4 f2 f2 ?, ~( Y% A9 ~1 ?
if (HSEStatus == (uint32_t)0x01)
4 E- K( I) U3 X  Z2 y! D9 s$ q0 o{
* }; V; `& ^9 O……省略……
6 A2 k+ F& z: f7 ~}. p  s( F3 v6 w% h; z' X' f
else
, E. B0 u+ f0 e3 B8 v$ H- ~/ ]{
' A" U* m+ q* u" q: S1 L& w8 K1 b    /* If HSE fails to start-up, the application will have wrong clock( z5 n( `8 o8 l+ y+ x  v! e% K
       configuration. User can add here some code to deal with this error */3 [/ ]1 {' F8 W/ U# N
1 B: O. u3 k" P# h7 T
  //翻译:如果HSE无法启动,程序将以错误的时钟运行。用户可自行添加勘正代码# D( v) d0 `; [9 @0 a1 J  A
}
" G4 |* L" y6 F" ^# c9 n9 y3 `7 C1 S, Y5 d9 J4 d+ V
ST官方竟然提前留好了坑!9 A3 S; b/ ]7 L
6 P/ x( Q5 K) J4 Z2 j
于是,仿照着HSE+PLL启动方式,我写了下面的代码,使用HSI+PLL,并添加到else{}中,观察RCC_ClockFreq.SYSCLK_Frequency=32000000,一次性通过。5 a( ]$ [$ ?* E' h" R+ a0 [7 M+ g
" n4 }8 P* p) A9 i$ p
    /* Enable HSI */
  }# S, z0 T* u- s9 S& q    RCC->CR |= ((uint32_t)RCC_CR_HSION);+ d% |; c1 c* k  R

3 _* M! e" P: D" j% G    /* Wait till HSI is ready and if Time out is reached exit */
( t: Z9 U, Q; b# w6 O9 x$ _& S    do
7 U  `; |  z: k% q, o  w    {9 F* W/ P( O2 O, c6 f
      HSIStatus = RCC->CR & RCC_CR_HSIRDY;9 h( Q9 p4 O/ }3 J" X6 a$ S1 M' R
      StartUpCounter++;6 s5 O7 E+ k2 B9 G% J! e7 e
    } while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));
/ c2 C7 |6 i. S1 H! c3 @) Z1 M' m6 @4 d6 D* e+ [2 x+ u  R
    if ((RCC->CR & RCC_CR_HSIRDY) != RESET)
- e$ c+ q- O, l0 v! I7 \    {
2 ^& w* [" h# ?6 g* Q      HSIStatus = (uint32_t)0x01;) Y: e% U7 i, M$ n) B' Z& x* f  Z
    }$ p& }  d2 }! i7 R: ]9 a
    else& }1 Q5 z7 h9 k& j- X7 l7 m4 P
    {7 e4 X) E  z6 Q# B1 W+ M
      HSIStatus = (uint32_t)0x00;; b; l" z4 z( E5 u" d
    }
4 P1 s& q, R3 O4 C1 b& E
. o$ t2 ^5 q# K& l* I( p" t" h! L" ]    if (HSIStatus == (uint32_t)0x01)# ^" ~% [9 a2 M
    {5 I: e8 K8 L% L6 s" x. ^9 a) \- W
      /* Turn OFF the HSE oscillator */
+ b9 F7 |6 p$ p) b      RCC_HSEConfig( RCC_HSE_OFF );4 q$ F/ B$ o' v& L# `/ G5 R
7 ]$ ?. q7 H1 a+ v8 {, w
      /* Enable 64-bit access */, M% e. N( R) q9 ~7 n0 R! v
      FLASH->ACR |= FLASH_ACR_ACC64;2 }2 p, [+ x7 {7 m
( Y+ p3 |9 }  M
      /* Enable Prefetch Buffer */4 g# Y. U* A! k
      FLASH->ACR |= FLASH_ACR_PRFTEN;
& k! H) i  m) J# d" s
+ g4 x; {7 q& t6 O  Y      /* Flash 1 wait state *// [0 V# {5 L+ N6 ?$ {$ y
      FLASH->ACR |= FLASH_ACR_LATENCY;
% v6 b' h) R7 w& T9 ^2 r; t
+ U: f- t* h' `& ^% q( i. `  m7 T- _      /* Power enable */
5 X% a0 e1 Z7 v% N4 ?* H2 K      RCC->APB1ENR |= RCC_APB1ENR_PWREN;1 j* K! z- V* W) O- @

, S1 b: @: d1 `  c$ w      /* Select the Voltage Range 1 (1.8 V) */5 _+ C* C8 s% P* @2 c6 t
      PWR->CR = PWR_CR_VOS_0;
' [& e( y2 @4 E. I$ f- [/ f7 \5 F. ?9 [' E
      /* Wait Until the Voltage Regulator is ready */. a+ C: D2 G1 A+ j' Y) n; h+ H
      while((PWR->CSR & PWR_CSR_VOSF) != RESET)! R: x9 J& ~/ ?' K
      {6 a- ?" v8 @4 r, j6 B
      }
3 V$ p% u( z6 t1 H2 w0 I) O# n7 X( P3 _, c
      /* HCLK = SYSCLK /1*/
9 `/ A  d* _; g/ i( y5 q5 n      RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;6 q: h3 a" c0 e% T8 [6 G& v

2 P1 x1 O+ l" W& \1 {      /* PCLK2 = HCLK /1*/
# Z: Q( j6 G- y2 c1 w& p+ s      RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;" W, G4 v  [5 L& V
5 f$ I* x, @: h9 c/ N
      /* PCLK1 = HCLK /1*/* ~& W# Q' ?* y5 s& ^
      RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;4 x; t1 R) S& N2 S4 [
% c9 \# u# S! w! J6 W! w8 P, t4 F
      /*  PLL configuration */) m4 t5 p, i! F3 ~0 R  N/ K$ ~
      RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL |
5 G9 D* _5 l, B# U' A; [* g                                          RCC_CFGR_PLLDIV));
! v2 p& P4 ]0 Q7 t; w/ _# ?& j      RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI | RCC_CFGR_PLLMUL4 | RCC_CFGR_PLLDIV2);2 c; F9 l0 z- U. |- d+ [

5 w7 ?% h8 h- s6 H      /* Enable PLL */
* k  t5 \* ^8 n0 s      RCC->CR |= RCC_CR_PLLON;) s/ \8 M$ M+ l; |4 b$ ^- L8 v
9 v4 c& M$ o5 h$ i; y% }$ Q# L
      /* Wait till PLL is ready */
- p. J+ h- B" ^3 h) m) o% f      while((RCC->CR & RCC_CR_PLLRDY) == 0)  B3 c$ d2 G6 [: K- V* _
      {
1 @# W" Q% x6 `0 Y: c5 i: a      }
/ z" R3 X/ T# S0 M" Y0 z! O% ?* U# @; N2 G6 _( V: q% b6 W0 s0 f
      /* Select PLL as system clock source */6 N9 _3 A: ^- M, q, H
      RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
/ U+ M5 A" R+ {8 w4 \( f      RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
' \' z: N6 H& |% X, T, O8 a) {* {# @; c: m7 y- I, B. s
      /* Wait till PLL is used as system clock source */  J% ?/ B* @5 s8 d( e+ s1 t
      while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
$ e0 D- N) t; u9 h+ q1 s6 ]6 X$ X      {
* l& ]( J+ R' S; [; h, l      }   
. C+ `* X- y! M    }3 }" m; n7 e, w: k8 d

! L+ {  n+ p' k' H7 L' \. V7 H7 _4 k3 _, Y3 f' h
1 a% H% T1 C1 }+ t$ o* X( H5 G
记得在static void SetSysClock(void)的第一行添加HSIStatus的定义,即:* n' x* M1 @! _& {( Q$ N  p* N. P
__IO uint32_t StartUpCounter = 0, HSEStatus = 0, HSIStatus = 0;- E, W! ]" E, Y0 h4 y( c
4 P& u* [' e$ m3 z' }* P
收藏 评论0 发布时间:2019-7-8 17:25

举报

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