CKS32F4xx系列低功耗模式STOP模式

cathy的头像
cathy 发布于:周二, 06/20/2023 - 15:16 ,关键词:

在本章节中,首先向大家介绍电源系统结构,接着简述三种低功耗模式,最后重点介绍CKS32F4xx系列如何进入STOP模式以及使用按键实现中断唤醒。

CKS32F4xx电源系统介绍

1.png

CKS32F4xx系列的电源系统框图

CKS32F4xx系列的器件工作电压(VDD)为1.8~3.6V。

①备份域电路:包含LSE振荡器、RTC、备份寄存器及备份SRAM。电源开关自动切换VDD和VBAT供电。

②调压器电路(1.2V域):为备份域及待机电路外的所有数字电路供电,其中包括内核、数字外设及RAM。

③ADC电路和参考电压:ADC工作电源使用VDDA引脚输入,使用VSSA作为独立的地连接,VREF引脚则为ADC提供测量使用的参考电压。

低功耗模式简介

CKS32F4xx系列按功耗由高到低排列,分别是运行、睡眠、停止(STOP)和待机(STANDBY)四种工作模式。上电复位后,CKS32F4xx系列会处于正常运行状态,当不需要继续运行内核时,就可以选择进入后面的三种低功耗模式降低功耗。这三种模式中,电源消耗不同、唤醒时间不同、唤醒源不同,用户需要根据应用需求,选择最佳的低功耗模式。其中,最低功耗的是待机模式,停机模式(STOP)是次低功耗的,最后是睡眠模式。低功耗相关寄存器主要有SCB_SCR、PWR_CR、PWR_CSR,进入各种低功耗需要调用的指令有WFI或WFE,以下做简要介绍。

1.SCB_SCR(系统控制寄存器)

2.png

3.jpg

若进入停止模式or待机模式,需将SLEEPDEEP置1。

2.PWR_CR(电源控制寄存器)

4.png

若进入停止模式,需将PDDS清0,LPDS选调节器模式;若进入待机模式,需将PDDS置1,清除唤醒位CWUF。

3.PWR_CSR(电源控制/状态寄存器)

5.png

若芯片处于待机模式下,需使用使用WKUP引脚唤醒并需要清除WUF标记位。

注:WKUP上升沿才能唤醒待机状态,清除WUF标记位实则需操作CWUF位。

4.WFI与WFE指令

实质上都是内核指令,在库文件core_cmInstr.h中把这些指令封装成了函数,调用它们都能进入低功耗模式。调用时,需要使用函数的格式“__WFI();”和“__WFE();”,这是因为__wfi及__wfe是编译器内置的函数,函数内部使用调用了相应的汇编指令。其中WFI指令决定了它需要用中断唤醒,而WFE则决定了它可用事件来唤醒。

以下表格是对三种低功耗模式的简要概述。

6.jpg

本章中,我们主要对CKS32F4xx系列的低功耗模式—停止模式(STOP)做详细介绍。该模式中,由于其1.2V区域的部分电源没有关闭,会保留内核的寄存器、内存的信息,所以从STOP模式唤醒,并重新开启时钟后,还可以从上次停止处继续执行代码。停止模式可以由任意一个外部中断(EXTI)唤醒。在停止模式中可以选择电压调节器为开模式或低功耗模式,可选择内部FLASH工作在正常模式或掉电模式。那我们如何进入STOP模式,可以按照下述表格中的步骤执行即可:

7.jpg

CKS32F4xx系列标准库把进入STOP模式这部分的操作封装到PWR_EnterSTOPMode函数中了,并且需要注意的是进入STOP模式后,CKS32F4xx系列的所有IO都保持在停止前的状态,且当它被唤醒时,CKS32F4xx系列使用HSI作为系统时钟运行,由于系统时钟会影响很多外设的工作状态,所以一般我们在唤醒后会重新开启HSE,把系统时钟设置为原来的状态。上面表格也提到在停止模式中,还可以控制FLASH的供电,使用库函数PWR_FlashPowerDownCmd配置进入掉电状态还是正常供电状态,本质上是封装了一个对FPDS寄存器位操作的语句,使用时需要再进入停止模式前被调用,可以进一步降低功耗。

采用EXTI唤醒STOP模式实验

程序设计主要要点如下:

① 初始化用于唤醒的中断按键;

② 配置不用的I/O端口;

③ 设置停滞状态是FLASH掉电以及选择电压调节器的工作模式并进入停止状态;

④ 使用按键中断唤醒芯片;

⑤ 重启HSE时钟,使系统完全恢复停止之前的状态。

1)初始化用于唤醒的中断按键

此处选择连接PB1引脚的按键用于将芯片从STOP模式唤醒,代码如下:

void CKS_EXTI_Init(void)
{  
    GPIO_InitTypeDef   GPIO_InitStructure;  
    EXTI_InitTypeDef  EXTI_InitStructure;  
    NVIC_InitTypeDef  NVIC_InitStructure;
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    
  /* Configure PB1 as EXTI */  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;    
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  
  GPIO_Init(GPIOB, &GPIO_InitStructure); 
  
  /* Configure PB1 to EXTI line 1 */    
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB,EXTI_PinSource1);
  
  /* EXTI configuration */  
  EXTI_InitStructure.EXTI_Line = EXTI_Line1;  
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;  
  EXTI_Init(&EXTI_InitStructure);
  
  /* NVIC configuration */  
  NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;  
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  NVIC_Init(&NVIC_InitStructure);
}

在CKS_EXTI_Init函数中,首先使能GPIOB时钟,又因为用到外部中断,所以必须先使能SYSCFG时钟,接着对GPIOB初始化为上拉输入,并调用函数 SYSCFG_EXTILineConfig配置GPIOB.1连接到中断线1,最后初始化EXTI中断线以及NVIC中断优先级。

void EXTI1_IRQHandler(void)
{  
    if(EXTI_GetITStatus(EXTI_Line1) != RESET)   
    {       
        EXTI_ClearITPendingBit(EXTI_Line1);       
    }  
}

在中断服务函数EXTI1_IRQHandler内,主要是清除LINE1上的中断标志位。

2)配置未使用的I/O口

进入STOP模式之前,需要对I/O进行处理,若不处理很多配置为输入浮空的I/O口在受到外界干扰的时候,状态不定,消耗大量的电流,代码如下:

void CKS_Stop_Mode_IO_Set(void)
{  
    /* set pins not used to AIN */  
    GPIO_InitTypeDef    GPIO_InitStructure;
  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOI, ENABLE);
   
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;  
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
   
   GPIO_Init(GPIOA, &GPIO_InitStructure);   
   GPIO_Init(GPIOC, &GPIO_InitStructure);   
   GPIO_Init(GPIOD, &GPIO_InitStructure);     
   GPIO_Init(GPIOF, &GPIO_InitStructure);    
   GPIO_Init(GPIOG, &GPIO_InitStructure);     
   GPIO_Init(GPIOH, &GPIO_InitStructure);    
   GPIO_Init(GPIOI, &GPIO_InitStructure);   
    
   GPIO_InitStructure.GPIO_Pin = (~GPIO_Pin_1);      
   GPIO_Init(GPIOB, &GPIO_InitStructure);  
}

由上述代码可知,我们将没用到的I/O全部设置为模拟输入,保留PB1作为按键,产生外部中断来将芯片从STOP模式唤醒。

3)芯片进入STOP模式

该部分代码一般是程序执行一段时间再调用,我们先使用PWR_FlashPowerDownCmd配置停止模式下FLASH使用掉电模式,随后调用PWR_EnterSTOPMode把调压器设置在低功耗模式,最后使用WFI指令进入停止状态。由上文可知,WFI进入停止模式可由任意的EXTI的中断唤醒,所以此处使用按键中断唤醒是可行的,代码如下:

void CKS_Set_Stop_Mode(void)
{  
    PWR_FlashPowerDownCmd (ENABLE);  
    PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);
}

4)主函数配置

本例程中主函数主要对上文所述函数调用,程序编译下载至开发板,先进行相关外设初始化后,直接进入STOP模式,此时按下按键,芯片可立即被唤醒,随即又进入STOP模式,循环往复,主函数代码如下:

int main(void)
{    
    GPIO_Configuration();  
    CKS_EXTI_Init();  
    CKS_Stop_Mode_IO_Set();
   while (1)  
   {          
       CKS_Stop_Mode_IO_Set();    
       CKS_Set_Stop_Mode();    
       SystemInit();        
       Delay(0xffffff);      
   }
}

来源:中科芯MCU

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 36