四、电源管理模块(PMM)和供电监控简介
Power Management Module and Supply Voltage Supervisor
我觉得电源管理与监控是一个很复杂很难掌控的部分,不仅涉及到
到源模式的选择,还牵扯到复杂的中断、以及中断如何处理等等。虽然学好这一部分对实现降低功耗的目的很有帮助,但对于目前的我们来说貌似“ “功耗”一词还稍微远了点。此外,这部分控制对防止和处理供电意外( (过高过低等)的发生很有帮助,不过貌似这个开发板如果不独立拿来做项 项目而只是接在电脑USB供电的话,一般也不会有什么问题。所以,我也 也只打算简单学一下。(到后期有机会会再仔细学)。
I/O口和所有模拟单元包括晶振在内都由DVCC供电。内存(flash和RAM)和数字单元由核心电压VCORE供电。
DVCC:宽的电源电压范围1.8V-3.6V;
VCORE:DVCC经低压降电压调整器(LDO),产生的一个二次核心电压,专门为CPU数字逻辑供电,共有1.4V(0-12MHZ),1.6V(0-16MHZ),1.8V(0-20MHZ)和1.9V(0-25MHZ)四个级别。VCORE的最小允许电压依赖于选择的MCLK大小,也就是说高主频时需要配套较高的VCORE。
管理会产生复位(主要是上电期间),监控会产生中断(监控电压是否过高过低)。
我们最常用的是设置核心电压VCORE,还好有专门的函数库HAL_PMM.c/h。
在这个函数库里除了一些设置的定义外,最重要的就是定义了三个函数:
SetVCoreDown(uint8_t level):降低核心电压
SetVCoreUp(uint8_t level): 提高核心电压
SetVCore(uint8_t level):直接设置核心电压值(0-3共四级)
五、系统工作模式
第四章我们提到可以从电源层入手,达到从源头上控制功耗的目的。这一章 我们就会讲CPU工作模式,如何从次一级来控制功耗。
不同工作模式下,CPU会禁用一些模块,从而达到控制功耗的目的。
(PS:同样那句话,“功耗太远”,一般都不会去更改工作模式,所以简 单学习)
简介几句话:①改变工作模式会立即生效;
②发生中断时,当前的模式设置信息会被保存,以便恢复(除非中断服务程序中改变了工作模式);
③处于LPM4.5模式时,PMM的电源监管不会生效,所有的RAM和寄存器都会丢失,但是I/O口状态会锁定;
④从LPM4.5唤醒,有一套专门的流程,有兴趣就去看;
下面这张图很有意思,可以清楚的看清工作模式之间转换的流程与方向,以及每种工作模式是怎样设置的,又控制了哪些部分。
BOR: Brown-Out Reset 低电压检测复位(欠压复位)
POR: Power-On Reset 上电复位
PUC: Power-Up Clear 上电清除
浅色部分表示一个事件,深色部分表示一种操作或设置
①设置工作模式主要是设置寄存器SR的SCG0、SCG1、OSCOFF、CPUOFF
位,AM(Active Mode)模式时四位均置零,且系统默认为AM模式;
②除了AM,其余都为低功耗模式,处理器进入低功耗模式以后,一般由中 断来唤醒。可以是外部中断,也可以是内部的定时器等中断;
③LPM0-LPM4模式下,外围模块都会正常工作,且RTC时钟不会停止;
④要进入LPM4.5这一模式(更少用),只需在LPM4的基础上多一个 PMMREGOFF置位。该模式下,系统的所有时钟、内存和监督管理机 制都停了,连实时时钟RTC都禁止操作了。
⑤LPM0和LPM1一组,除了上图显示的特征外,该模式下SMCLK是选通的 (SMCLKOFF =0),DCO的时钟源如果是ACLK或者SMCLK,则DCO也是有 效的;
⑥ LPM2和LPM3一组,除了上图显示的特征外,该模式下SMCLK是禁止的, DCO的时钟源如果是ACLK,则DCO也是有效的;
⑦MSP430的头文件对低功耗模式有详尽的定义,如:要进入低功耗模式0,可 在程序中直接写LPM0; 进入低功耗模式4,可以直接写LMP4。退出低功 耗模式如下:
LPM0_EXIT; //退出低功耗模式0 //太方便了有木有
LPM4_EXIT; //退出低功耗模式4(LPM4.5除外)
总结实验:一个很有意思的程序
#include
void main(void)
{
WDTCTL=WDTPW+WDTCNTCL+WDTTMSEL+WDTIS1+WDTIS0;//WDT作定时器用
SFRIE1|=WDTIE; //开看门狗中断
P1DIR|=BIT1+BIT2; //P1.1接LED,设定为输出方向
P1OUT=BIT1+BIT2;
__enable_interrupt(); //开总中断
//_BIS_SR(GIE); 这句话的意思也是开总中断
LPM3; //进入LPM3低功耗模式,此模式下SMCLK被禁止
P1OUT&=~BIT2;//这句话执行不了,所以P1.2就会保持常亮,而不会变暗
}
#pragma vector=WDT_VECTOR
__interrupt void WatchTimer(void)
{
P1OUT^=BIT1; //定时翻转,以实现闪烁
}