[牛人杂谈] N79E715的电源管理

[复制链接]
1685|16
 楼主| 稳稳の幸福 发表于 2017-2-15 21:49 | 显示全部楼层 |阅读模式
作为51能有这种电源管理功能,确实很让人意外。
N79E715有几个功能模块可以帮助用户控制设备的功耗。省电的途径有掉电模式和空闲模式。为了确保
最小功耗,需要特别注意P0管脚。
在系统省电模式下,看门狗定时器需要特别注意。在进入或退出空闲或掉电模式后,硬件会自动清除
WDT计数器,以避免系统复位。

 楼主| 稳稳の幸福 发表于 2017-2-15 21:50 | 显示全部楼层
 楼主| 稳稳の幸福 发表于 2017-2-15 21:51 | 显示全部楼层
空闲模式
空闲模式下通过保持程序计数器使CPU挂起。在空闲模式下没有程序代码的取指和运行。这迫使CPU处
于待机状态。程序计数器(PC),堆栈指针 (SP),程序状态字 (PSW),累加器(ACC),和其他寄存器在空
闲模式下保持其值不变。端口引脚保持进入空闲前的逻辑状态。通常空闲模式下的功耗约为工作状态下
的一半。
既然在空闲模式下,外设电路如定时器和串口的时钟依然工作,则可以通过相应使能的中断唤醒CPU。
用户可通过向IDL (PCON.0)写1进入空闲模式。这条指令是系统进入空闲模式前的最后一条指令。
有两种方法可以中止空闲模式,方法一,任何使能的中断可以使系统退出空闲模式。这将自动清零IDL
位,中止空闲模式,且将执行中断服务程序 (ISR)。在使用指令RETI跳出ISR,所执行的将是进入空闲
模式指令后的程序。第二种方法是除软件复位外的所有复位。
 楼主| 稳稳の幸福 发表于 2017-2-15 21:52 | 显示全部楼层
掉电模式
掉电模式是N79E715进入的最低功耗状态,保持功耗在“微安uA” 级。此时停止内部RC时钟或外部晶
振。 CPU和外设如定时器或UART都待机,Flash 内存也停止,所有动作完全停止,功耗降至最低。可
以通过向PD (PCON.1)写1进入掉电模式。在掉电模式下,RAM 保存其内容,端口引脚的值也保持不
变。
N79E715有两种方法可以退出掉电模式。 一,除软件复位外的所有复位.。欠压检测复位将把CPU由掉
电模式唤醒,在系统进入掉电模式之前要确保使能欠压检测。除最低功耗外,很少在掉电模式下使能欠
压检测,也不推荐这种用法。当然RST引脚的复位或上电复位也可以唤醒掉电状态。RST引脚复位或上
电复位后,CPU初始化,并开始执行程序。
N79E715可以通过外部中断脚唤醒掉电模式,并有自己的中断向量和终端标志。在中断条件设定的情况
下,外部中断信号会唤醒内部同步时钟从而唤醒系统,设备执行相应的外部中断的中断服务例程
(ISR)。 ISR完成后,如果程序执行掉电指令,系统会再进入掉电模式。.
低电压检测中断BOD,是唤醒掉电模式的另一个来源。如前所述BOD检测电路的功耗较大,用户如果开
启BOD唤醒系统在掉电模式下功耗也会增加,所以这不是一个典型的应用。
芯片可通过BOD、看门狗或KBI中断唤醒掉电模式。但需注意:如采用BOD唤醒模式,打开BOD侦测模
块,会在掉电模式下,使芯片消耗更多的电流。如采用KBI中断模式,若为下降边沿唤醒,则在进入掉
电模式前,端口电位必须为高;若为上升边沿唤醒,在进入掉电模式前,端口电位必须为低。
 楼主| 稳稳の幸福 发表于 2017-2-15 21:53 | 显示全部楼层
  1. /*---------------------------------------------------------------------------------------------------------*/
  2. /*                                                                                                         */
  3. /* Copyright(c) 2015 Nuvoton Technology Corp. All rights reserved.                                         */
  4. /*                                                                                                         */
  5. /*---------------------------------------------------------------------------------------------------------*/

  6. //***********************************************************************************************************
  7. //  Nuvoton Technology Corp.
  8. //  E-mail: MicroC-8bit@nuvoton.com
  9. //***********************************************************************************************************
  10. //  Application: Power Down Wake up
  11. //  External interrupt 0 Wake up  => P1.3 input low(falling edge).
  12. //  External interrupt 1 Wake up  => P1.4 input low(falling edge).
  13. //  Keyboard interrupt   Wake up  => P0 input low(falling edge)
  14. //  Brown out interrupt  Wake up  => Vdd < 3.8V
  15. //  Watch dog interrupt  Wake up  => Watch dog timer time out
  16. //  ADC interrupt        Wake up  => ADC conversion finish
  17. //
  18. //  Output : UART show result on hyper-terminal
  19. //           P1.7 toggle when MCU wake up every once
  20. //           P1.4 flash when power down pass
  21. //           P2.1 flash when power down pass
  22. //***********************************************************************************************************

  23. //------------------------- <<< Use Configuration Wizard in Context Menu >>> --------------------------------
  24. // <h> Power down wake up source
  25. //          <o0.0> External interrupt0
  26. //                  <0=> Disable
  27. //                  <1=> Enable
  28. //          <o1.0> External interrupt1
  29. //                  <0=> Disable
  30. //                  <1=> Enable
  31. //          <o2.0> Key board interrupt
  32. //                  <0=> Disable
  33. //                  <1=> Enable
  34. //          <o3.0> Brown out detect interrupt
  35. //                  <0=> Disable
  36. //                  <1=> Enable
  37. //          <o4.0> Watch dog timer interrupt
  38. //                  <0=> Disable
  39. //                  <1=> Enable
  40. //          <o5.0> ADC interrupt
  41. //                  <0=> Disable
  42. //                  <1=> Enable
  43. // </h>
  44. // <h> KBI  Enable
  45. //          <q6.0> KBI.0
  46. //          <q6.1> KBI.1
  47. //          <q6.2> KBI.2
  48. //          <q6.3> KBI.3
  49. //          <q6.4> KBI.4
  50. //          <q6.5> KBI.5
  51. //          <q6.6> KBI.6
  52. //          <q6.7> KBI.7
  53. // </h>
  54. //<o7.0..2> WDT Prescalar Select
  55. //      <0=> 1/1    <1=> 1/2    <2=> 1/8    <3=> 1/16
  56. //      <4=> 1/32   <5=> 1/64   <6=> 1/128  <7=> 1/256
  57. //
  58. //     <o8.6> UART pin Select
  59. //          <0=> Select P1.0, P1.1 as UART pin(default)
  60. //          <1=> Select P2.6, P2.7 as UART pin(28 pin only)
  61. //-------------------------------- <<< end of configuration section >>> -------------------------------------

  62. #define  EXT_INT0_EN        1
  63. #define  EXT_INT1_EN        1
  64. #define  KBI_INT_EN         1
  65. #define  BOD_INT_EN         1
  66. #define  WDT_INT_EN         1
  67. #define  ADC_INT_EN         1
  68. #define  KBI_Enable         0xFF
  69. #define  WDT_CLK_DIV        0x07
  70. #define  Uart_Port_Sel      0x00

  71. #include <stdio.h>
  72. #include "N79E715.h"
  73. #include "Typedef.h"
  74. #include "Define.h"
  75. #include "Common.h"
  76. #include "Delay.h"
  77. #include "ISR.h"
  78. #include "wdt.h"
  79. #include "Version.h"

  80. UINT16 i;
  81. bit EA_Save_bit;
  82. //-----------------------------------------------------------------------------------------------------------
  83. void main()
  84. {
  85.     AUXR1 |= Uart_Port_Sel;                 // Select P10/P11 as UART pin(default)
  86.     InitialUART0_Timer1(9600);              // 9600 Baud Rate [url=home.php?mod=space&uid=72445]@[/url] 11.0592MHz
  87.     printf ("\n*===================================================================");
  88.     printf ("\n*  Name: N79E715 Series PowerDown Wake-up Sample Code.");
  89.     printf ("\n*===================================================================");
  90.     printf ("\nPower Down Wake up Demo Start.\n");
  91.     P0 = 0x00;
  92.     for(i = 0; i<60000; i++);
  93.     P0 = 0xFF;
  94.     P17 = 0;
  95.     EA = 1;

  96.     //********************** External interrupt0 ************************
  97.     #if EXT_INT0_EN == 1
  98.         printf ("\nDemo INT0 Wake Up Function...");
  99.         clr_IE0;                            // Clear external interrupt0 flag first
  100.         EX0 = 1;                            // Enable External interrupt0
  101.         PCON |= SET_BIT1;                   // Enter power down mode
  102.         printf ("\nMCU Wake Up...");
  103.         P17 = ~P17;
  104.     #endif
  105.     //********************** External interrupt1 ************************
  106.     #if EXT_INT1_EN == 1
  107.         printf ("\nDemo INT1 Wake Up Function...");
  108.         clr_IE1;                            // Clear external interrupt1 first
  109.         EX1 = 1;                            // Enable external interrupt1
  110.         PCON |= SET_BIT1;                   // Enter power down mode
  111.         printf ("\nMCU Wake Up...");
  112.         P17 = ~P17;
  113.     #endif
  114.     //********************** Keyboard interrupt **************************
  115.     #if KBI_INT_EN == 1
  116.         printf ("\nDemo KBI Wake Up Function...");
  117.         clr_KBIF0;                          // Clear keyboard interrupt flag first
  118.         KBIE = KBI_Enable;                  // Enable P1 that cause keyboard
  119.         EKB = 1;                            // Enable key board interrupt
  120.         PCON |= SET_BIT1;                   // Enter power down mode
  121.         printf ("\nMCU Wake Up...");
  122.         P17 = ~P17;
  123.     #endif
  124.     //********************** Brown out detect ***************************
  125.     #if BOD_INT_EN == 1
  126.         printf ("\nDemo Brown-Out Wake Up Function...");
  127.         TA = 0xAA;
  128.         TA = 0x55;
  129.         PMCR = 0xC0;
  130.         EBO = 1;                            // Enable brown out detect
  131.         PCON |= SET_BIT1;
  132.         printf ("\nMCU Wake Up...");
  133.         P17 = ~P17;
  134.     #endif
  135.     //********************** Watch dog timer ****************************
  136.     #if WDT_INT_EN == 1
  137.         printf ("\nDemo Watch Dog Wake Up Function...");
  138.         TA = 0xAA;
  139.         TA = 0x55;
  140.         WDCON0 |= WDT_CLK_DIV;              // Select bit length of WDT counter
  141.         TA = 0xAA;
  142.         TA = 0x55;
  143.         WDCON0 |= SET_BIT4;
  144.         clr_WDTF;                           // Clear WDT flag
  145.         EWDI = 1;                           // Enable WDT interrupt
  146.         set_WDCLR;                          // Clear WDT counter
  147.         set_WDTEN;                          // Enable WDT
  148.         PCON |= SET_BIT1;                   // Enter power down mode
  149.         printf ("\nMCU Wake Up...");
  150.         P17 = ~P17;
  151.     #endif
  152.     //********************** ADC interrupt ******************************
  153.     #if ADC_INT_EN == 1
  154.         printf ("\nDemo ADC Wake Up Function...");
  155.         clr_ADCI;                           // Clear ADC flag first
  156.         ADCCON1 |= 0x82;                    // ADC clock is RC/2 clock and enable ADC
  157.         EADC = 1;                           // Enable ADC interrupt
  158.         ADCS = 1;                           // ADC run
  159.         PCON |= SET_BIT1;                   // Enter power down mode
  160.         printf ("\nMCU Wake Up...");
  161.         P17 = ~P17;
  162.     #endif
  163.     printf ("\nPower Down Wake Up Test OK!");
  164.     P17 = 1;
  165.     while(1)
  166.     {
  167.         P14 = 1;
  168.         P21 = 1;
  169.         Delay1ms(500);
  170.         P14 = 0;
  171.         P21 = 0;
  172.         Delay1ms(500);
  173.     }
  174. }
  175. //-----------------------------------------------------------------------------------------------------------
  176. void INT0_ISR(void) interrupt 0             // Vector @  0x03
  177. {
  178.     clr_IE0;
  179.     EX0 = 0;
  180. }
  181. //-----------------------------------------------------------------------------------------------------------
  182. void INT1_ISR(void) interrupt 2             // Vector @  0x13
  183. {
  184.     clr_IE1;
  185.     EX1 = 0;
  186. }
  187. //-----------------------------------------------------------------------------------------------------------
  188. void KBI_ISR(void)  interrupt 7             // Vector @  0x3B
  189. {
  190.     clr_KBIF0;
  191.     EKB = 0;
  192. }
  193. //-----------------------------------------------------------------------------------------------------------
  194. void BOD_ISR(void)  interrupt 8             // Vector @  0x43
  195. {
  196.     clr_BOF;
  197.     EBO = 0;
  198. }
  199. //-----------------------------------------------------------------------------------------------------------
  200. void WDT_ISR(void)  interrupt 10            // Vector @  0x53
  201. {
  202.     clr_WDTF;
  203.     clr_WDTEN;
  204.     EWDI = 0;
  205. }
  206. //-----------------------------------------------------------------------------------------------------------
  207. void ADC_ISR(void)  interrupt 11            // Vector @  0x5B
  208. {
  209.     clr_ADCI;
  210.     EADC = 0;
  211. }
  212. //-----------------------------------------------------------------------------------------------------------


 楼主| 稳稳の幸福 发表于 2017-2-15 21:55 | 显示全部楼层
  PCON |= SET_BIT1;                   // Enter power down mode
这个刚好是对应        PD (PCON.1)写1进入掉电模式
xinyipcb 发表于 2017-2-16 01:32 | 显示全部楼层
关键是功耗,功耗不下来受限很大。
天灵灵地灵灵 发表于 2017-2-16 19:18 | 显示全部楼层
空闲模式下的功耗约为工作状态下的一半。
zhuotuzi 发表于 2017-2-17 08:38 | 显示全部楼层
电源管理的终极目的就是省电。空闲模式下的功耗约为工作状态下的一半,另外一种模式几乎跟关机一样。
天灵灵地灵灵 发表于 2017-2-17 22:28 | 显示全部楼层
掉电模式是N79E715进入的最低功耗状态,保持功耗在“微安uA” 级。基本上就是关机了。
734774645 发表于 2017-2-19 18:48 | 显示全部楼层
这也是新唐的51跟传统51的区别,传统的很简单,新唐的扩充了很多功能。新增了不少外设。
 楼主| 稳稳の幸福 发表于 2017-2-20 00:22 | 显示全部楼层
对于51单片机有两种节能方式就很不错了。可以实现低功耗的需求。
zhuomuniao110 发表于 2017-2-20 20:47 | 显示全部楼层
ISR完成后,如果程序执行掉电指令,系统会再进入掉电模式。.
huangcunxiake 发表于 2017-2-21 20:05 | 显示全部楼层
程序计数器(PC),堆栈指针 (SP),程序状态字 (PSW),累加器(ACC),和其他寄存器在空闲模式下保持其值不变。这样恢复后继续可以工作。
wahahaheihei 发表于 2017-2-21 20:22 | 显示全部楼层
任何使能的中断可以使系统退出空闲模式。这将自动清零IDL
位,中止空闲模式,且将执行中断服务程序 (ISR)。
dongnanxibei 发表于 2017-2-22 13:52 | 显示全部楼层
在进入或退出空闲或掉电模式后,硬件会自动清除WDT计数器,以避免系统复位。
wgc2015 发表于 2017-3-4 17:03 | 显示全部楼层
但是唤醒时每次第一次都会LED闪烁一下,是怎么回事?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

204

主题

3450

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部