您的当前位置: 网站首页 > 新闻动态 > 公司新闻

MCU微课堂 | CKS32F4xx系列低功耗模式STOP模式

更新时间:2023-06-21 10:31:20

MCU微课堂

CKS32F4xx系列低功耗模式STOP模式

第十五期 2023.06.21

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

CKS32F4xx电源系统介绍

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(系统控制寄存器)

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

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

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

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

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

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

4.WFI与WFE指令

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

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

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

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);    
  }
}
新闻动态News
联系我们CONTACT US
  • 深圳市汇创科电子科技有限公司
  • 电话:0755-27809147
  • 传真:0755-27809147
  • 手机:13823247950
  • 网址:www.hck-tech.com
  • 销售中心:深圳市宝安区西乡街道固戍二路下围园七星创意园B座501
服务热线
0755-27809147