打印
[技术问答]

Mini58如何进入掉电模式

[复制链接]
1918|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 magic2004301 于 2017-8-27 15:54 编辑

最近刚开始搞Mini58,需求是设备在停止供电后(接下来有备用电池供电)进入掉电模式,然后每隔10分钟唤醒系统。CPU时钟为HIRC。按照我的理解,进入掉电模式后CPU应该停止运行??
但我按照新唐SDK中提供的例子调用CLK_PowerDown()函数后,发现程序依然在执行:


这是我的程序:
//系统时钟初始化:
/* Enable HIRC clock (Internal RC 22.1184MHz) and LIRC clock */
CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk | CLK_PWRCTL_LIRCEN_Msk);

/* Wait for HIRC and LIRC clock ready */
CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk | CLK_STATUS_LIRCSTB_Msk);

/* Select HCLK clock source as HIRC and and HCLK source divider as 1 */
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV_HCLK(4));


//进入掉电模式
void System_Sleep()
{
        /* Unlock protected registers to let CPU enter power down mode */
        SYS_UnlockReg();
        
        //Enter Power Down Mode
        CLK_PowerDown();
}


这是新唐SDK里面的例子:
while(1) {
        // Wait 'til UART FIFO empty to get a cleaner console out
        while(!UART_IS_TX_EMPTY(UART0));
        CLK_PowerDown();
    }


都是调用CLK_PowerDown()函数,为何我的程序仍然继续执行呢??

请各位大神帮我解答一下以下两个问题:
1、掉电模式在CPU时钟为HIRC的情况下能否进入?
2、如果能够进入,是通过调用CLK_PowerDown()函数进入吗?




请各位大神不吝赐教,新人第一天注册论坛,没有什么分,在此只能“空手套白狼”了!

PS:设备外部电源停止供电后,还有备用电池供电,所以还是有时间进入掉电模式的~~~
沙发
mintspring| | 2017-8-27 15:37 | 只看该作者
不清楚的,电都没了,怎么还继续设置掉电模式啊

使用特权

评论回复
板凳
mintspring| | 2017-8-27 15:38 | 只看该作者
应该是有电的时候的一种模式吧,进入这个模式就好比电视用遥控器关机了一样,或者手机关机了一样。

使用特权

评论回复
地板
magic2004301|  楼主 | 2017-8-27 15:52 | 只看该作者
mintspring 发表于 2017-8-27 15:37
不清楚的,电都没了,怎么还继续设置掉电模式啊

还有备用电池供电,还能撑一段时间

使用特权

评论回复
5
magic2004301|  楼主 | 2017-8-27 15:57 | 只看该作者
mintspring 发表于 2017-8-27 15:38
应该是有电的时候的一种模式吧,进入这个模式就好比电视用遥控器关机了一样,或者手机关机了一样。 ...

其实是深度睡眠模式,在这种模式下大部分时钟都关掉,主要是为了省电。问题是怎么进入Power Down模式呢?

掉电模式.png (250.01 KB )

掉电模式.png

使用特权

评论回复
6
mintspring| | 2017-8-27 16:13 | 只看该作者
     printf("Enter to Power-Down ......\n");
        while(!UART_IS_TX_EMPTY(UART0));
        CLK_PowerDown();

使用特权

评论回复
7
mintspring| | 2017-8-27 16:14 | 只看该作者
/**************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url]     main.c
* [url=home.php?mod=space&uid=895143]@version[/url]  V2.10
* $Date: 15/10/12 8:06p $
* [url=home.php?mod=space&uid=247401]@brief[/url]    Show how to wake up system from Power-down mode by GPIO interrupt.
*
* @note
* Copyright (C) 2012 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#include <stdio.h>
#include "mini51series.h"
#include "GPIO.h"

/**
* @brief       Port0/Port1 IRQ
*
* @param       None
*
* [url=home.php?mod=space&uid=266161]@return[/url]      None
*
* [url=home.php?mod=space&uid=1543424]@Details[/url]     The Port0/Port1 default IRQ, declared in startup_Mini51.s.
*/
void GPIO01_IRQHandler(void)
{
    /* To check if P1.5 interrupt occurred */
    if (P1->ISRC & BIT5) {
        P1->ISRC = BIT5;
        printf("P1.5 INT occurred. \n");

    } else {
        /* Un-expected interrupt. Just clear all PORT0, PORT1 interrupts */
        P0->ISRC = P0->ISRC;
        P1->ISRC = P1->ISRC;
        printf("Un-expected interrupts. \n");
    }
}



void SYS_Init(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/

    /* Set P5.0 and P5.1 -> XTAL  */
    SYS->P5_MFP &= ~(SYS_MFP_P50_Msk | SYS_MFP_P51_Msk);
    SYS->P5_MFP |= (SYS_MFP_P50_XTAL1 | SYS_MFP_P51_XTAL2);

    /* Enable external 12MHz XTAL, internal 22.1184MHz */
    CLK->PWRCON |= CLK_PWRCON_XTL12M | CLK_PWRCON_IRC22M_EN_Msk;

    /* Waiting for clock ready */
    CLK_WaitClockReady(CLK_CLKSTATUS_XTL_STB_Msk | CLK_CLKSTATUS_IRC22M_STB_Msk);

    /* Switch HCLK clock source to XTL */
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_XTAL,CLK_CLKDIV_HCLK(1));

    /* STCLK to XTL STCLK to XTL */
    CLK_SetSysTickClockSrc(CLK_CLKSEL0_STCLK_S_XTAL);

    /* Enable IP clock */
    CLK_EnableModuleClock(UART_MODULE);

    /* Select IP clock source */
    CLK_SetModuleClock(UART_MODULE,CLK_CLKSEL1_UART_S_XTAL,CLK_CLKDIV_UART(1));

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set P0 multi-function pins for UART RXD and TXD */
    SYS->P0_MFP &= ~(SYS_MFP_P01_Msk | SYS_MFP_P00_Msk);
    SYS->P0_MFP |= (SYS_MFP_P01_RXD | SYS_MFP_P00_TXD);

    /* Set P3 multi-function pins for Clock Output */
    SYS->P3_MFP = SYS_MFP_P36_CKO;

    /* To update the variable SystemCoreClock */
    SystemCoreClockUpdate();

    /* Lock protected registers */
    SYS_LockReg();
}

void UART_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset IP */
    SYS_ResetModule(SYS_IPRSTC2_UART_RST_Msk);

    /* Configure UART and set UART Baudrate */
    UART_Open(UART, 115200);

}

/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function                                                                                           */
/*---------------------------------------------------------------------------------------------------------*/
int main (void)
{

    /* Init System, IP clock and multi-function I/O */
    SYS_Init(); //In the end of SYS_Init() will issue SYS_LockReg() to lock protected register. If user want to write protected register, please issue SYS_UnlockReg() to unlock protected register.

    /* Init UART for printf */
    UART_Init();

    printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);

    printf("+--------------------------------------+ \n");
    printf("|    MINI51 GPIO Wake-up Sample Code   | \n");
    printf("+--------------------------------------+ \n");

    /* Configure P1.5 as Input mode and enable interrupt by rising edge trigger */
    GPIO_SetMode(P1, BIT5, GPIO_PMD_INPUT);
    GPIO_EnableInt(P1, 5, GPIO_INT_RISING);
    NVIC_EnableIRQ(GPIO01_IRQn);

    /* Waiting for interrupts */
    while (1) {
        printf("Enter to Power-Down ......\n");
        while(!UART_IS_TX_EMPTY(UART0));
        CLK_PowerDown();
        printf("System waken-up done.\n\n");
    }

}

使用特权

评论回复
8
天灵灵地灵灵| | 2017-8-27 16:26 | 只看该作者
这个估计时钟是有一定关系的。

使用特权

评论回复
9
magic2004301|  楼主 | 2017-8-27 16:29 | 只看该作者
mintspring 发表于 2017-8-27 16:13
printf("Enter to Power-Down ......\n");
        while(!UART_IS_TX_EMPTY(UART0));
        CLK_Po ...

谢谢!已经发现问题,不是没进入掉电模式,而是我1s的定时器瞬间就把系统从掉电模式中唤醒了......不过好奇怪,我设置1s的定时器在中断120次后才开始使能唤醒系统功能,不知道怎么第1次中断就把系统还行了,还得再继续跟踪。

使用特权

评论回复
10
magic2004301|  楼主 | 2017-8-27 16:31 | 只看该作者
天灵灵地灵灵 发表于 2017-8-27 16:26
这个估计时钟是有一定关系的。

嗯嗯,掉电模式下HIRC、HXT这些高速时钟都被停掉了。不过我的CPU时钟是HIRC,按理说在掉电模式下是应该被停掉的。

使用特权

评论回复
11
magic2004301|  楼主 | 2017-8-27 16:47 | 只看该作者
本帖最后由 magic2004301 于 2017-8-27 16:48 编辑

发现问题了:已经进入了掉电模式,但是瞬间就被1s定时器TIMER0给唤醒了:
#define TIMER0_TIMEOUT_SECS 1
#define MCU_AWAKE_INTV 2*60
#define TIMER0_MCU_AWAKE_MAX_TIMEOUT_CNT (MCU_AWAKE_INTV/TIMER1_TIMEOUT_SECS)

void TMR0_IRQHandler(void)
{
        //static uint32_t timer0_timeout_cnt = 0;
        
        timer0_timeout_cnt++;
        
        if(TIMER_GetIntFlag(TIMER0) == 1)
       {
          //Clear Timer0 time-out interrupt flag
         TIMER_ClearIntFlag(TIMER0);
       }
        
        // Clear wake up flag
        if(TIMER_GetWakeupFlag(TIMER0) == 1)
        {
                TIMER_ClearWakeupFlag(TIMER0);
               
                //Disable timer wake up system
                TIMER_DisableWakeup(TIMER0);
               
                timer0_timeout_cnt = 0;
               
                gISREventFlag |= EVENT_TIMER0_BIT;
        }
        

        if (timer0_timeout_cnt == TIMER0_MCU_AWAKE_MAX_TIMEOUT_CNT)
        {
                ///Enable timer wake up system
               TIMER_EnableWakeup(TIMER0);
        }
        
}


不过奇怪的是,掉电模式下通过定时器唤醒系统必须通过TIMER_EnableWakeup(TIMER0)函数来使能,我设置的是第120次也就是2分钟后才使能。但现在来看第一次中断就唤醒系统了,怪哉!
从现象上来看,唤醒系统的时机不太对,TIMER0第一次中断时,还没有使能唤醒系统(我已经用JLINK观察出来第一次中断时使能标志尚未置1),但系统照样被唤醒了。
感觉进入的不是掉电模式,而是任何中断都能唤醒系统的空闲模式!

使用特权

评论回复
12
jiekou001| | 2017-8-27 22:29 | 只看该作者
这个严重了,看看官方的例程序能否实现这个GPIO唤醒掉电。

使用特权

评论回复
13
magic2004301|  楼主 | 2017-8-28 08:59 | 只看该作者
jiekou001 发表于 2017-8-27 22:29
这个严重了,看看官方的例程序能否实现这个GPIO唤醒掉电。

我已经联系了新唐的技术支持,他们也需要看一下。我现在需要支持定时器唤醒和GPIO唤醒两种方式,GPIO还在试

使用特权

评论回复
14
山东电子小菜鸟| | 2017-8-28 20:25 | 只看该作者
支持

使用特权

评论回复
15
magic2004301|  楼主 | 2017-8-31 14:48 | 只看该作者
技术支持都表示很费解,哎~实测功耗也表明进入的是Idle模式,功耗是mA级别,离Power Down模式下uA级别的耗电相去甚远,领导说一定要改

使用特权

评论回复
16
magic2004301|  楼主 | 2017-9-7 14:02 | 只看该作者
没有用过Mini58掉电模式的大神么?问题还没解决!

使用特权

评论回复
17
yiy| | 2017-9-11 21:47 | 只看该作者
你定时器唤醒干啥了?是不是可以设置唤醒等级。。

使用特权

评论回复
18
yiy| | 2017-9-11 21:48 | 只看该作者
或者指定不用定时器唤醒。。。或者必须在定时器中断函数设置什么才能唤醒。。不懂这个,真没用过。都是瞎猜的。

使用特权

评论回复
19
天灵灵地灵灵| | 2017-9-13 23:10 | 只看该作者
不清楚这个情况,定时器中断肯定可以唤醒,要不然还要中断干啥

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

14

帖子

0

粉丝