STM32L1开发心得(一、RCC/PWR篇)
+ o$ N- p8 \( q/ w2 h2 ^- 因为电压及功耗方面的要求,需要从STM32F103将程序移植到STM32L151上面,以下内容就是程序移植过程中的心得体会。
6 N2 `. i3 |" r- k- H) \, t; R1 J8 ^ - STM32F系列的应用很多,网上大把都是F系列的经验文章和例程,但是L系列的文章就很少,尤其是中文的资料就更少,所以使用L系列最痛苦的就是必须啃英文资料,这里写的开发心得就算是为同样英文不好工程师参考吧。" u1 C9 o8 @- c9 C
- 本篇主要说说RCC/PWR的配置。
% V8 }$ T0 [! S/ O* Q - 与F1系列相比,L1系列有以下几个关键地方不太一样,需要特别注意:
: ~& q1 V8 T1 e0 s! y. o' H/ g4 e - 1、 L1系列的最高频率只能达到32M
0 M! X7 H8 n/ p$ }- [: p1 ` - 2、L1系列的HSI是16M的% h( h* q- Y7 m {% I7 C6 z$ O% v
- 3、L1系列的内部RC振荡器除了HSI外,还增加了一个MSI,但MSI不能做为PLL的源7 w/ t c& l) o1 x- M
- 4、MSI提供了从64K到4M之间几种超低频率,特别适合那种不能睡眠又没多少事干的节能应用场合
# H# U5 ?6 l& W( U' @. H3 T5 W- R - 5、内核电压Vcore是可以配置的,而Vcore的不同也影响最大工作频率和FLASH的配置" k/ Y U3 H# O+ `7 ?, ~
- 6、L1的最低可运行电压为1.65V,用ADC或DAC时最低1.8V
* d( e+ k: u9 B% n7 _1 W4 f$ j2 } - 7、某些外设的总线改变,比如GPIOA在L1系列被映射到AHB总线上& \ P1 ~% f t# ^1 O$ z" D
- 除了以上需要注意的事项外,笔者在调试RCC时,发现按照F1系列的通常例程修改后很难调通,建议编程时以ST公司提供的例程为蓝本,在此基础上修改成自已所需要的参数,以下是例程(HSI源的PLL):9 L4 C6 O. R& t6 G; M
- RCC_DeInit();
5 Y6 |6 V6 f0 A3 `! Z! v; V - RCC_HSICmd(ENABLE); //开启内部晶振HSI
~ c8 r- c- ]: ^. A$ v( V - while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY)== RESET); //等待HSI就绪
2 s2 J) j2 w- r1 P- ~6 r1 m - FLASH->ACR |= FLASH_ACR_ACC64; //使能64位FLASH% x% Y( [3 o& h% W0 _: N
- FLASH->ACR |= FLASH_ACR_PRFTEN; //使能FLASH预取功能5 t# }9 [+ S0 ~" ?
- FLASH->ACR |= FLASH_ACR_LATENCY; //1个等待周期
: _2 O" [& U0 V1 l - RCC->APB1ENR |= RCC_APB1ENR_PWREN; //使能POWER6 ^. E' {& y: v: }& b
- PWR->CR = PWR_CR_VOS_0; //选择内核电压1级(1.8V)
9 @8 U( R9 n' C4 T& G' q$ a l% N! j - while((PWR->CSR & PWR_CSR_VOSF) != RESET) {}; //等待内核电压稳定# l0 C0 p) V% i' B3 X# `) Q3 ^7 k
- RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; //HCLK
# d2 g* B5 {6 r+ }8 P - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; //PCLK2
0 P% o" ]. g: b' F: H/ J: n - RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; //PCLK13 v( H+ ?$ g+ n+ N
- // PLL =16MHZ*2=32MHZ 5 [4 u. I( B/ X
- RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL |; q) S3 w' M1 z8 P+ ]" g& O* x( v
- RCC_CFGR_PLLDIV));- w4 g; T1 k7 Z3 p
- RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI | RCC_CFGR_PLLMUL6 | RCC_CFGR_PLLDIV3);
9 }0 n/ W3 k# Q8 |7 Q; r( i - RCC->CR |= RCC_CR_PLLON; //使能RCC8 W* | h- M& K: T) u1 H
- while((RCC->CR & RCC_CR_PLLRDY) == 0){} //等待PLL稳定9 v, j% V. m0 Q- }9 E
- //选择PLL做为系统时钟 6 r* X! P0 T0 r2 ~# Q/ i+ u
- RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+ S9 _3 a+ e3 Q$ T; j - RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
2 x. r7 ]4 b0 Z5 l* n0 ^9 m" G - //等待PLL稳定0 p2 b. {6 N- n
- while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL){}/ [6 M2 i# B6 ^
- //上面配置完成后,就可以将外设联接到时钟总线上了,比如联接GPIOA; K" [5 ?- }/ F$ E' l
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
复制代码 8 J) |/ f+ {6 u9 G) J
) W! X( i1 U* m P! d0 y5 Y% y
) [5 q! p# Q/ c0 `: W+ C |