CKS32F4xx系列MCU的低功耗模式之睡眠模式

控制/MCU

1882人已加入

描述

 

本课讲为大家讲解CKS32F4xx系列产品的低功耗模式之睡眠(Sleep)模式。MCU为满足某些应用场景:如小型化低容量设备,长期监测设备等,低功耗应运而生,其中根据需求,用户可以选择睡眠模式、停止模式及待机模式,今天本课将带大家一起配置睡眠模式。

电源系统及低功耗

 

首先,MCU要做到低功耗,必须要知道电源是怎么分配的,CKS32F4xx系列的电源系统框图如下所示:

转换器

电源框图中,第1部分是备份域电路,由VDD或Vbat电池供电,接入3V纽扣电池后,可保证VDD掉电时,能够保留关键数据。

第2部分为电压调压器供电,由于其输出约为1.2V,又称1.2V域。1.2V域给除备份域和待机电路以外的所有数字电路供电,在低功耗的三种模式中,1.2V域也对应三种状态:正常开启、低功耗和关闭。

第3部分为A/D转换器及参考电压供电,故为VDDA供电区,目的是使用独立电源能更好的滤波,从而提高精度,也可以在Vref上外接高精度电源,进一步提高进度。

所谓低功耗,即是关闭相应功耗路线,1)睡眠模式仅关闭第二部分中的内核时钟;2)停止模式关闭所有时钟,且调压器可选择正常开启或低功耗运行;3)待机模式关闭所有时钟以及调压器,仅保留备份域及待机电路;

 

外部中断唤醒睡眠模式验证

接下来举一个低功耗睡眠模式且由外部中断唤醒的例子,睡眠模式比较简单,直接调用编译器内置函数__WFE()或__WFI(),取决于使用事件唤醒还是中断唤醒;另外默认SCR(系统控制寄存器)的SLEEPDEEP位和SLEEPONEXIT位置0,效果是立即触发睡眠,如果将SLEEPONEXIT置1可以设置成中断退出后触发睡眠,也就是说内核将会只在中断内工作。

验证流程如下图,电源串联万用表电流档,直观比较睡眠模式开启前后的电流大小。

转换器

程序配置及中断服务函数

 

1)开启时钟及GPIO初始化如下,按键直连PE10,按下为低电平。

 

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE ,ENABLE);    
 //开启按键GPIO口的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); 
//由于使用外部中断需要使能 SYSCFG 时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;           //选择按键PE10的引脚   
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;     //设置引脚为输入模式
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  //不上拉也不下拉
GPIO_Init( GPIOE, &GPIO_InitStructure);            //使用上面的结构体初始化按键

 

2)总中断NVIC初始化如下,GPIO外部中断源一共对应7个通道,PX0~PX4分别对应EXTI0~EXTI4的5个通道,PX5~PX9对应通道EXTI_9_5,PX10~PX15 对应通道EXTI_15_10,故PE10对应中断服务函数EXTI15_10_IRQHandler()。

 

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);          //配置NVIC为优先级组1
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;   //按键PE10使用中断源EXTI15_10
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //配置抢占优先级:1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;       //配置子优先级:1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;      //使能中断通道
NVIC_Init(&NVIC_InitStructure);                   //使用上面的结构体初始化总中断

 

3)外部中断配置如下,主要在初始化中对中断屏蔽寄存器EXTI_IMR及下降沿触发选择寄存器EXTI_FTSR配置,将EXTI_IMR的MR10位置1,可开放相应通道中断请求。

 

SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource10); //连接外部中断源到PE10
EXTI_InitStructure.EXTI_Line = EXTI_Line10; //选择EXTI中断源
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //选择为中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断/事件线
EXTI_Init(&EXTI_InitStructure); //使用上面的结构体初始化外部中断:EXTI_IMR的MR10位置1等

 

4)中断服务函数如下,触发后验证标志位,确保发生的是外部线中断;其次外部中断线发生事件后,中断挂起寄存器EXTI_PR会置1,通过 EXTI_ClearITPendingBit再次在PR写入1,从而清除它,进入下一次外部中断等待。

 

void EXTI15_10_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line10) != RESET)        //验证是否产生了外部线中断
  {
    Delay(0x1FFFFFF);                         //简单延时验证电流
    EXTI_ClearITPendingBit(EXTI_Line10);         //清除标志位
  }  
}

 

 

主函数及现象

Main函数首先初始化GPIO、NVIC中断、外部中断,进入主循环后先延迟观测电流,测得19.3mA,延迟后,__WFI()自动触发睡眠模式,电流测得13.3mA,如果不进行按键操作,MCU将一直睡眠,不再执行任何代码,此时按下轻触开关,触发外部中断,电流回升至19.3mA,睡眠模式唤醒时间无延迟,执行完中断服务程序后,会回到代码睡眠时的句段,继续执行。PS:如果需要设置成中断退出后触发睡眠模式,则将SLEEPONEXIT置1。

 

int main(void)
{ 
EXTI_Config();      //配置及初始化GPIO、NVIC中断、外部中断
  while(1)
  {  
  Delay(0x1FFFFFF);    
    //SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;  //如需设置成中断退出后触发睡眠
模式
    __WFI();            //进入睡眠模式,电流从19.3mA降至13.3mA
  }
}

 

 

  审核编辑:汤梓红
 
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分