CW32 低功耗模式的特性介绍

CW32系列芯片支持3种工作模式,运行模式、休眠模式以及深度休眠模式,本文以CW32L083为例介绍低功耗模式的特性。MCU上电以后,系统自动进入运行模式,可以通过软件配置,进入休眠或者深度休眠两种低功耗模式,进入低功耗运行状态后,可以通过外设中断触发唤醒机制,使得系统返回到运行模式,三种工作模式的转换机制如下图所示:

 

三种模式下CPU、时钟及外设状态:

• 运行模式(Active mode) 

运行模式下 CPU 正常运行,所有模块用户均可正常使用。

• 休眠模式(Sleep mode) 

休眠模式下,CPU 停止运行,所有外设不受影响,所有I/O引脚保持状态不变。

• 深度休眠模式(DeepSleep mode) 

深度休眠模式下,CPU停止运行,高速时钟(HSE、HSIOSC)自动关闭,低速时钟(LSE、 LSI、RC10K、RC150K)保持原状态不变。深度休眠模式的功耗远小于休眠模式。

CW32L083可以使用等待中断专用指令,WFI(Wait for Interrupt),配合系统控制寄存器(SCR, System Control Register)的SLEEPONEXIT和SLEEPDEEP位域,可实现立即进入或退出(中断服务程序)时进入休眠模式或深度休眠模式。

• 立即进入 

执行WFI指令,MCU将立即进入休眠模式(SLEEPDEEP为0时)或深度休眠模式(SLEEPDEEP为1时) 

• 退出时进入 

将SLEEPONEXIT位置1,当退出最低优先级的中断服务程序后,MCU会进入休眠模式(SLEEPDEEP为0时)或深度休眠模式(SLEEPDEEP为 1时),而不需执行WFI指令 。

 

注:在深度休眠模式下,系统将自动关闭高速时钟,如果需要在深度休眠模式下使部分外设仍保持运行,则需要在进入深度休眠模式前,启动相应的低速时钟并将该外设时钟设置为此低速时钟。

在休眠模式或深度休眠模式下,均可通过中断来唤醒CPU,返回到运行模式。如果用户在中断服务程序中执行WFI命令进入休眠(包括深度休眠),则需要比此中断更高优先级的中断才能唤醒CPU,因此,强烈建议在准备进入休眠前,应先处理完所有中断服务程序,并且清除所有中断请求和中断标志,以下是配置进入低功耗模式时所需注意的事项。

• 建议在进入低功耗模式前加一段时间的延迟,以免出现上电就进入低功耗模式,无法烧录程序。

• 系统可以配置从Deepsleep唤醒后,系统时钟来源是HSI还是进入休眠前的时钟。

• 系统进入低功耗模式,端口状态不会发生改变,此时需要客户根据实际应用来配置端口状态来达到理想的功耗值,未用端口建议配置为模拟模式。

• 其他的RTC等低功耗运行模块因在深度休眠下高速时钟停止运行,所以如果需要在深度休眠模式下运行RTC等模块,需配置模块时钟源为LSI或LSE。

根据上述内容,可以配置CW32L083的低功耗应用的例程,具体的代码可以查看CW32L083的固件库中PWR_CurrentConsumption这一例程,配置PA04和PA05为引脚输入,并开启下降沿中断,在中断服务函数改变gKeyStatus的值,从而使得MCU在main中进入低功耗休眠模式。

volatile uint8_t gKeyStatus;  

volatile uint32_t gFlagWakeUpIrq = 0;  

int main(void)

{

    RCC_HSI_Enable( RCC_HSIOSC_DIV6); //配置系统时钟为HSI 8M

    InitTick(8000000ul); //初始化SysTick

    LED_Init();         //LED初始化

    BSP_PB_Init();  //按键初始化

    while (1)

    {

       gKeyStatus = 0;//在没有进入低功耗模式前,PC03每间隔1s翻转一次状态

       do

       {

      PC03_TOG();         //翻转LED1

       SysTickDelay(1000);   //延迟1s.

       } while (gKeyStatus == 0);       

       PC03_SETLOW();         //PC03置低

       DeepSleepModeTest();    //进入深度睡眠模式

     }

}



//按键初始化,设置PA05沿下降沿触发中断

void BSP_PB_Init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure = {0};

    //打开GPIOA时钟

    REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOA_Msk);

    GPIO_InitStructure.Pins = GPIO_PIN_5;

    GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;

    GPIO_InitStructure.IT = GPIO_IT_FALLING;

    GPIO_Init(CW_GPIOA, &GPIO_InitStructure);

    GPIO_ConfigFilter(CW_GPIOA, GPIO_PIN_5, GPIO_FLTCLK_RC10K);

    //设置GPIOA的中断等级为3

    NVIC_SetPriority(GPIOA_IRQn, 0x03);

    GPIOA_INTFLAG_CLR(GPIOx_ICR_PIN5_Msk );

    NVIC_EnableIRQ(GPIOA_IRQn);

}



//LED I/O初始化

void LED_Init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure = {0};

    //打开GPIO时钟

    REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOC_Msk);

    GPIO_InitStructure.Pins = GPIO_PIN_2 | GPIO_PIN_3;

    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_Init(CW_GPIOC, &GPIO_InitStructure);

    PC03_SETLOW();

}



void DeepSleepModeTest(void)

{

  GPIO_InitTypeDef GPIO_InitStructure = { 0 };

  PWR_InitTypeDef PWR_InitStructure = { 0 };



  //打开GPIO时钟

  REGBITS_SET(CW_SYSCTRL->AHBEN,SYSCTRL_AHBEN_GPIOA_Msk|\

  SYSCTRL_AHBEN_GPIOB_Msk | \

  SYSCTRL_AHBEN_GPIOC_Msk | SYSCTRL_AHBEN_GPIOF_Msk);



  GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;

  GPIO_InitStructure.IT = GPIO_IT_NONE;

  GPIO_InitStructure.Pins = GPIO_PIN_All;

  GPIO_Init(CW_GPIOA, &GPIO_InitStructure);

  GPIO_Init(CW_GPIOB, &GPIO_InitStructure);

  GPIO_Init(CW_GPIOC, &GPIO_InitStructure);

  GPIO_Init(CW_GPIOF, &GPIO_InitStructure);

  //关闭GPIO时钟

  REGBITS_CLR(CW_SYSCTRL->AHBEN,SYSCTRL_AHBEN_GPIOA_Msk| \

  SYSCTRL_AHBEN_GPIOB_Msk | \

  SYSCTRL_AHBEN_GPIOC_Msk | SYSCTRL_AHBEN_GPIOF_Msk);

  BSP_PB_Init();             //按键初始化

  // 唤醒后自动使用内部高速时钟(HSI)

  RCC_WAKEUPCLK_Config(RCC_SYSCTRL_WAKEUPCLKEN);

  PWR_InitStructure.PWR_Sevonpend = PWR_Sevonpend_Disable;

  PWR_InitStructure.PWR_SleepDeep = PWR_SleepDeep_Enable;

  PWR_InitStructure.PWR_SleepOnExit = PWR_SleepOnExit_Disable;

  PWR_Config(&PWR_InitStructure);

  PWR_GotoLpmMode();

  SYSCLKConfig_DeepSleep();

  LED_Init();

  SysTickDelay(200);

  PC02_SETHIGH();

  }

}

//GPIOA中断服务函数

void GPIOA_IRQHandler(void)

{

 if(REGBITS_GET(CW_GPIOA->ISR, GPIOx_ISR_PIN5_Msk) > 0)

    {

        gKeyStatus = 1;

        GPIOA_INTFLAG_CLR(GPIOx_ICR_PIN5_Msk);//清除CW_GPIO中断标志

    }

}

上述代码可以看到在未进入低功耗模式之前,LED1每1s翻转一次,通过按键KEY2进入低功耗模式后,LED1灯灭,当再次按下KEY2后,重新回到正常的运行模式,LED1每一秒翻转一次。通过测量可以得到,进入到低功耗模式之后,功耗显著降低。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值