本帖最后由 jackyhuang1988 于 2019-3-12 12:47 编辑
如果你选择了MSP430单片机来开发产品,那很可能是用来做低功耗的。MSP430单片机的低功耗特性是相当突出的。有很多这样的场合,单片机做的事情是定时唤醒,才执行一次,比如传感器,1秒或更长时间才唤醒检测一次,而产品又是电池供电的,需要做到低功耗。这种场合,MSP430是首选。 利用MSP430的低频振荡器,可以实现低功耗,定时唤醒。有两种方式,一种是外部接一只晶振,通常是32.768KHz的晶振。这种方式需外接晶振,精度高,但缺点是浪费了两个引脚,以及提高了成本。本文讲述的是另一种方式,不用外接晶振,用MSP430内部的VLO振荡器,而这个VLO振荡器是很不准确的,所以需要用DCO振荡器来校准。
由上图看出VLO振荡器的误差是极大的,而DCO的误差则比较小,因此,可以利用DCO,通过软件来校准VLO。TI官方有这个校准库,VLO_Library.s43,下面来介绍它的使用方法。
首先要把VLO_Library.s43库加到工程中,并把头文件VLO_Library.h加到文件中。其原理是通过在8个VLO周期内跑了n个DCO周期,由此设置定时器0的溢出周期,定时器0是由VLO振荡提供时钟的,休眠后是靠定时器0中断来唤醒的。代码如下:
主函数:
void main()
{
//不禁止看门狗,以保证产品的稳定
……自己的初始化代码
while (1)
{
//休眠/唤醒处理,休眠/唤醒此处统一处理
//休眠/唤醒处理
if (SleepFalg)
{
//进入休眠前的处理
dco_delta = TI_measureVLO(); //获取内部振荡VLO的校准值,dco delta = number of 1MHz cycles in 8 ACLK cycles
TACTL = 1 << 8; //选择TIMER0时钟源为ACLK,时钟分频 /1
TACCTL0 = 1 << 4; //TACCR0中断允许
TACCTL1 = 0;
TACCR0 = 8000000 / dco_delta; //设置计数n=8000000 / dco_delta * t t单位为秒
TAR = 0;
TACTL |= (1<<4); //TIMER0运行,向上计数
TimerWakeUpFlag = 0;
//进入休眠
while (TimerWakeUpFlag == 0)
{
EnterLPM3(); //进入休眠
}
SleepFalg = 0;
//退出休眠的处理
}
SleepFalg = 1;
UARTSendByte(0x55);
}
}
定时器0中断
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR (void)
{
//以下执行用户需定时的程序
ExitLPM3();
TimerWakeUpFlag = 1;
}
代码中设置的是每1秒唤醒一次,唤醒后串口发送一个0x55字节,然后继续休眠。以下是测试结果:
由图可见,校准后的VLO还是很准确的,1.003秒发送一个0x55。当然,这也侧面说明了常温下MSP430的DCO振荡器还是很准确的
|