牛卧堂MCU技术交流

标题: NANO功耗Application Note_V1.12 [打印本页]

作者: admin    时间: 2014-4-29 17:16
标题: NANO功耗Application Note_V1.12
NANO功耗Application Note_V1.12.docx (200.14 KB, 下载次数: 6665)



    
Document  Information
  
    
Abstract
      
该文档介绍nano中,怎样调进入超低功耗模式时的功耗.
  
    
Apply to
      
Nano Series.
  



    
Table of  Contents
  
    
      
1        介绍... 3
  
1.1  原则.... 3
  
1.2  寄存器.... 3
  
1.3  NANO的行为.... 4
  
1.4  漏电电路.... 4
  
1.4.1                                                                                                                                                                     电路一... 4
  
1.4.2                                                                                                                                                                     电路二... 5
  
1.4.3                                                                                                                                                                     电路三... 5
  
1.5  常见问题.... 5
  
1.6  调试方法.... 5
  
1.6.1                                                                                                             打开IO口的内部上拉,功耗反而变高... 6
  
1.6.2                                                                                            打开内部上拉,功耗降低,但是耗电仍然偏高... 6
  
1.6.3                                                                                                    功耗会飘,手靠近板子,功耗会忽高忽低... 6
  
1.6.4 Power down时,LCD和RTC保持显示,正常情况下功耗应该是10uA左右,但是测得功耗16uA.. 7
  
1.6.5 大多情况下进入power down的功耗都是正常的6uA左右,但是某次进入power down时的功耗会高达1mA.. 7
  
1.7  真实案例分析.... 7
  
1.7.1                                                                        客户板子进入power down功耗5mA,到客户端分析原因... 7
  
1.7.2                                                              客户的板子放一个晚上功耗飘到了100uA,到客户端分析原因... 8
  
2        示例代码... 9
  
2.1  进入低功耗函数.... 9
  
2.2  状态保存和恢复.... 10
  
  



1      介绍

Nano系列是以Cotex-m0为内核的超低功耗MCU。进入深度睡眠模式时,所有IP都关闭的情况下的功耗为1uARTC和段式LCD屏都工作的情况下功耗10uA左右。客户的系统中往往不止MCU一颗IC,怎样让系统进入深度睡眠模式时的功耗最低?一直是客户问的最多的问题,也是问题最多的地方。本文介绍一些原则和调试的方法,希望对大家有帮助。




1.1    寄存器

涉及到的寄存器包括:






1.2     原则



1.3    NANO的行为

进入powerdown的时候,MCU会帮忙关闭HIRC(内部高频晶振)和HXT(外部高频晶振)两个高频晶振,软件不要去控制这两个晶振。外部32K和内部10K需要软件自己关闭。


这就导致使用HIRCHXT为时钟源的外设在进入powerdown的时候会自动停止工作,但是使用外部32K或者内部10K作为时钟源的外设需由软件决定在系统进入powerdown的时候是否仍然工作。例如:系统进入powerdown的时候,RTCWDT仍然工作,这就需要不能关闭32K10K晶振。


但是模拟外设是个特例,因为模拟电路工作不需要时钟。所以如果模拟外设功能使能,MCU虽然将晶振关闭,但是模拟电路部分仍会耗电。例如:ADC,系统进入power down之前需要写控制寄存器ADCR->ADENADC功能关闭,否则会漏电


如果进入powerdown的时候如果引脚设定有问题,NANO中每个IO脚漏电大概20uA,这也是一个线索。


1.4    漏电电路

1.4.1    电路一

                              


该电路从VCC->R35->R11->R12->R13形成一个通路。假设VCC=3.3V,这里漏电3.3/3 = 1.1uA


这个是LCD的驱动电路,考虑到驱动能力,加1M可能已经差不多了。大家明白这里会耗电1.1uAOK了。




1.4.2   电路二



该电路从VCC->R1->R2形成通路,假设VCC=3.3V,这里漏电3.3/2 = 1.65uA


该电路是测量电源电压的电路,ADCCHECK引脚接到ADC0模拟输入引脚,power down的时候需要将ADCCHECK引脚切为输入模式(PMD)GPIO功能(MFP),并关闭数字通路(OFFD)。解决办法:






1.4.3   电路三





该电路从UART1_RXD->R56形成通路,假设VCC=3.3V,这里漏电3.3/1 = 3.3uA


解决办法:powerdown时,将UART1_RXD引脚设为INPUT模式,但是不要打开内部上拉。




1.5     常见问题



1.6    调试方法

1.6.1   打开IO口的内部上拉,功耗反而变高

说明引脚有下拉,这个下拉可能是内部也可是外部。该引脚输出低电平时芯片内部是接地的,如果忘记将该引脚设为INPUT模式,内部就是下拉的,就会导致漏电。


外部有下拉不一定是明显的引脚加电阻接地,可能是外部芯片在输出低。




1.6.2   打开内部上拉,功耗降低,但是耗电仍然偏高

这就要考虑两种情况




1.6.3   功耗会飘,手靠近板子,功耗会忽高忽低

这个问题的原因比较多,列出可能的3个原因




进入power down的时候










1.6.4   Power down时,LCDRTC保持显示,正常情况下功耗应该是10uA左右,但是测得功耗16uA

如果芯片内部IO口漏电,每根IO漏电20uA左右。该板子多耗电6uA,所以一般不是芯片内部漏电,这就需要查整个板子的电路,是否有电源到地的通路。1.4节列出了几种漏电的情况,大家可以参考看看。


1.6.5   大多情况下进入power down的功耗都是正常的6uA左右,但是某次进入power down时的功耗会高达1mA

发现关闭ADC功能之后这个问题不再重现,所以锁定ADC


ADC工作频率比较低的情况下,写到ADC寄存器中的数据要等2ADC工作时钟才会起作用,所以在进入powerdown时,关闭ADC时钟之前(APBCLK),需要延迟2ADC工作时钟。不然ADC可能还没有关闭,时钟没有了,就会漏电。




1.7    真实案例分析

1.7.1    客户板子进入power down功耗5mA,到客户端分析原因



至此,客户整个板子在进入低功耗时耗电4.2uA


1.7.2   客户的板子放一个晚上功耗飘到了100uA,到客户端分析原因

客户的板子上只有我们的NANO,功耗正常时2uA


经过分析发现客户没有外接高速晶振,但是使能了晶振(PWRCON)。将晶振关闭之后电流没有再飘。




2     示例代码

该板子外接段式LCD屏,进入power down的时候LCDRTC要保持工作,另外外部还有一颗芯片需要PB.7输出低电平让其进入power down


2.1     进入低功耗函数



void Enter_PowerDown()


{


    UNLOCKREG();  


    /* Back uporiginal setting */


    SavePinSetting();


   


    /*set to INPUT mode */


    GPIOA->PMD = 0;


    GPIOB->PMD = 0x4000;/*PB.7 OUTPUT low*/


    GPIOC->PMD = 0;


    GPIOD->PMD = 0;


    GPIOE->PMD = 0;


    GPIOF->PMD = 0;


    /* Set to GPIO模式 */


    GCR->PA_L_MFP = 0x00FFFF00;


    GCR->PA_H_MFP = 0xFFFFFF00;


    GCR->PB_L_MFP = 0x0000FF00;


    GCR->PB_H_MFP = 0xFFFFFFFF;


    GCR->PC_L_MFP = 0x0000FF00;


    GCR->PC_H_MFP = 0x0F00FFFF;


    GCR->PD_L_MFP = 0x0;


    GCR->PD_H_MFP = 0x0;


    GCR->PE_L_MFP = 0x0;


    GCR->PE_H_MFP = 0x0;


    GCR->PF_L_MFP = 0x00FF00;


   


    /*Disable Digital path of LCD pin */


    GPIOA->OFFD = 0xFC3C0000;


    GPIOB->OFFD = 0xFF0C0000;


    GPIOC->OFFD = 0x4F0C0000;


      


    /* Enable GPIOpull up */


    GPIOA->PUEN = 0xFFFF;


    GPIOB->PUEN = 0xFF7F;/*PB.7 low*/


    GPIOC->PUEN = 0xFFFF;


    GPIOD->PUEN = 0xFFFF;


    GPIOE->PUEN = 0xFFFF;


    GPIOF->PUEN = 0x0033;/* exclude GPF2 and GPF3 which are HXT OUT/IN */


   


    SYS_SetChipClockSrc(CLK_PWRCTL_LXT_EN, 1);


    SYS_SetUpPowerDown(0);   /* Disable PDWUinterrupt */


    LOCKREG();


    __WFI();   /* system really enter power down here ! */


}


2.2     状态保存和恢复

函数SavePinSetting();用来保存GPIO和MFP寄存器的状态,在系统唤醒之后,这些寄存器的状态需要恢复


__IO uint32_t _Pin_Setting[11];        /* store Px_H_MFP and Px_L_MFP */


__IO uint32_t _PullUp_Setting[6];      /* storeGPIOx_PUEN */


__IO uint32_t _PMD_Setting[6];             /* store GPIOx_PMD */


__IO uint32_t _OFFD_Setting[6];            /* store GPIOx_PMD */




void SavePinSetting()


{


       /* SavePin selection setting */


       _Pin_Setting[0]= GCR->PA_L_MFP;


       _Pin_Setting[1]= GCR->PA_H_MFP;


       _Pin_Setting[2]= GCR->PB_L_MFP;


       _Pin_Setting[3]= GCR->PB_H_MFP;


       _Pin_Setting[4]= GCR->PC_L_MFP;


       _Pin_Setting[5]= GCR->PC_H_MFP;


       _Pin_Setting[6]= GCR->PD_L_MFP;


       _Pin_Setting[7]= GCR->PD_H_MFP;


       _Pin_Setting[8]= GCR->PE_L_MFP;


       _Pin_Setting[9]= GCR->PE_H_MFP;


       _Pin_Setting[10]= GCR->PF_L_MFP;


      


       /* SavePull-up setting */


       _PullUp_Setting[0]=  GPIOA->PUEN;


       _PullUp_Setting[1]=  GPIOB->PUEN;


       _PullUp_Setting[2]=  GPIOC->PUEN;


       _PullUp_Setting[3]=  GPIOD->PUEN;


       _PullUp_Setting[4]=  GPIOE->PUEN;


       _PullUp_Setting[5]=  GPIOF->PUEN;




/*Save PMD setting */


       _PMD_Setting[0]=  GPIOA->PMD;


       _PMD_Setting[1]=  GPIOB->PMD;


       _PMD_Setting[2]=  GPIOC->PMD;


       _PMD_Setting[3]=  GPIOD->PMD;


       _PMD_Setting[4]=  GPIOE->PMD;


       _PMD_Setting[5]=  GPIOF->PMD;




/*Save OFFD setting */


       _OFFD_Setting[0]=  GPIOA->OFFD;


       _OFFD_Setting[1]=  GPIOB->OFFD;


       _OFFD_Setting[2]=  GPIOC->OFFD;


       _OFFD_Setting[3]=  GPIOD->OFFD;


       _OFFD_Setting[4]=  GPIOE->OFFD;


       _OFFD_Setting[5]=  GPIOF->OFFD;


}




void RestorePinSetting()


{


       /*Restore Pin selection setting */


       GCR->PA_L_MFP= _Pin_Setting[0];


       GCR->PA_H_MFP= _Pin_Setting[1];


       GCR->PB_L_MFP= _Pin_Setting[2];


       GCR->PB_H_MFP= _Pin_Setting[3];


       GCR->PC_L_MFP= _Pin_Setting[4];


       GCR->PC_H_MFP= _Pin_Setting[5];


       GCR->PD_L_MFP= _Pin_Setting[6];


       GCR->PD_H_MFP= _Pin_Setting[7];


       GCR->PE_L_MFP= _Pin_Setting[8];


       GCR->PE_H_MFP= _Pin_Setting[9];


       GCR->PF_L_MFP= _Pin_Setting[10];


      


       /* RestorePull-up setting */


       GPIOA->PUEN= _PullUp_Setting[0];


       GPIOB->PUEN= _PullUp_Setting[1];


       GPIOC->PUEN= _PullUp_Setting[2];


       GPIOD->PUEN= _PullUp_Setting[3];


       GPIOE->PUEN= _PullUp_Setting[4];


       GPIOF->PUEN= _PullUp_Setting[5];




/* RestorePMD setting */


       GPIOA->PMD= _PMD_Setting[0];


       GPIOB->PMD= _PMD_Setting[1];


       GPIOC->PMD= _PMD_Setting[2];


       GPIOD->PMD= _PMD_Setting[3];


       GPIOE->PMD= _PMD_Setting[4];


       GPIOF->PMD= _PMD_Setting[5];




/* RestoreOFFD setting */


       GPIOA->OFFD= _OFFD_Setting[0];


       GPIOB->OFFD= _OFFD_Setting[1];


       GPIOC->OFFD= _OFFD_Setting[2];


       GPIOD->OFFD= _OFFD_Setting[3];


       GPIOE->OFFD= _OFFD_Setting[4];


       GPIOF->OFFD= _OFFD_Setting[5];


}


保存和恢复的函数将所有的寄存器都保存和恢复了,如果用户确定某个寄存器不需要保存可以将相关代码拿掉,特别在SRAM不够用的时候,buffer可以定义小一点。




    
Revision  History
      
  
    
Rev.
      
Date
      
Description
  
    
1.00
      
1-21-2014
      
Initially issued.
  
    
1.10
      
4-11-2014
      
添加AHBCLK和APBCLK处理
  
添加一些有问题原理图分析
  
    
1.12
      
4-25-2014
      
功耗飘时多添加2种肯能原因
  
如果量不到LDO为1.6v原因说明
  







Important Notice





Nuvoton productsare not designed, intended, authorized or warranted for use as components insystems or equipment intended for surgical implantation, atomic energy controlinstruments, airplane or spaceship instruments, transportation instruments,traffic signal instruments, combustion control instruments, or for otherapplications intended to support or sustain life. Furthermore, Nuvoton productsare not intended for applications wherein failure of Nuvoton products couldresult or lead to a situation wherein personal injury, death or severe propertyor environmental damage could occur.


Nuvoton customersusing or selling these products for use in such applications do so at their ownrisk and agree to fully indemnify Nuvoton for any damages resulting from suchimproper use or sales.





Pleasenote that all data and specifications are subject to change without notice. Allthe trademarks of products and companies mentioned in this datasheet belong totheir respective owners.







作者: 我爱下载    时间: 2014-5-5 09:16
相当不错的文档
作者: harvardx    时间: 2014-5-9 23:00
非常好 正需要这样的电路




欢迎光临 牛卧堂MCU技术交流 (http://nuvoton-mcu.com/) Powered by Discuz! X3.2