MSP430单片机内部振荡VLO校准

2020-03-08 19:19发布

本帖最后由 jackyhuang1988 于 2019-3-12 12:47 编辑

       如果你选择了MSP430单片机来开发产品,那很可能是用来做低功耗的。MSP430单片机的低功耗特性是相当突出的。有很多这样的场合,单片机做的事情是定时唤醒,才执行一次,比如传感器,1秒或更长时间才唤醒检测一次,而产品又是电池供电的,需要做到低功耗。这种场合,MSP430是首选。              利用MSP430的低频振荡器,可以实现低功耗,定时唤醒。有两种方式,一种是外部接一只晶振,通常是32.768KHz的晶振。这种方式需外接晶振,精度高,但缺点是浪费了两个引脚,以及提高了成本。本文讲述的是另一种方式,不用外接晶振,用MSP430内部的VLO振荡器,而这个VLO振荡器是很不准确的,所以需要用DCO振荡器来校准。
609055c872f8808542.png
500165c8734f366b6d.png
      由上图看出VLO振荡器的误差是极大的,而DCO的误差则比较小,因此,可以利用DCO,通过软件来校准VLO。TI官方有这个校准库,VLO_Library.s43,下面来介绍它的使用方法。
      首先要把VLO_Library.s43库加到工程中,并把头文件VLO_Library.h加到文件中。其原理是通过在8个VLO周期内跑了n个DCO周期,由此设置定时器0的溢出周期,定时器0是由VLO振荡提供时钟的,休眠后是靠定时器0中断来唤醒的。代码如下:
      主函数:
  1. void main()
  2. {
  3.         //不禁止看门狗,以保证产品的稳定
  4.         ……自己的初始化代码

  5.         while (1)
  6.         {        
  7.                 //休眠/唤醒处理,休眠/唤醒此处统一处理
  8.                 //休眠/唤醒处理
  9.                 if (SleepFalg)
  10.                 {
  11.                         //进入休眠前的处理                        
  12.                         dco_delta = TI_measureVLO();   //获取内部振荡VLO的校准值,dco delta = number of 1MHz cycles in 8 ACLK cycles
  13.                         TACTL = 1 << 8;                    //选择TIMER0时钟源为ACLK,时钟分频 /1
  14.                         TACCTL0 = 1 << 4;                   //TACCR0中断允许
  15.                         TACCTL1 = 0;
  16.                         TACCR0 = 8000000 / dco_delta;           //设置计数n=8000000 / dco_delta * t  t单位为秒
  17.                         TAR = 0;
  18.                         TACTL |= (1<<4);            //TIMER0运行,向上计数
  19.                         TimerWakeUpFlag = 0;
  20.                         
  21.                         //进入休眠
  22.                         while (TimerWakeUpFlag == 0)
  23.                         {
  24.                                 EnterLPM3();                //进入休眠
  25.                         }
  26.                         SleepFalg = 0;
  27.                         
  28.                         //退出休眠的处理
  29.                         
  30.                 }        
  31.                
  32.                 SleepFalg = 1;               
  33.                 UARTSendByte(0x55);        
  34.         }
  35. }
复制代码     定时器0中断
  1. #pragma vector = TIMER0_A0_VECTOR
  2. __interrupt void TIMER0_A0_ISR (void)
  3. {
  4.         //以下执行用户需定时的程序
  5.         ExitLPM3();
  6.         TimerWakeUpFlag = 1;
  7. }
复制代码

       代码中设置的是每1秒唤醒一次,唤醒后串口发送一个0x55字节,然后继续休眠。以下是测试结果:
538405c87378d815d0.png
        由图可见,校准后的VLO还是很准确的,1.003秒发送一个0x55。当然,这也侧面说明了常温下MSP430的DCO振荡器还是很准确的


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。