STM32开发 -- 低功耗模式详解(2)
2019-09-02 来源:eefocus
简单的总结了一下低功耗的三种模式。
但是还留了不少问题需要搞清楚。
接下来继续总结。。
一、其他几种退出待机模式的方法:
上篇文章只介绍了通过WKUP引脚上的上升沿退出待机模式。接下来再看一下剩下的RTC闹钟事件的上升沿、 NRST引脚上外部复位、 IWDG复位该如何操作呢?
RTC闹钟事件的上升沿
RTC部分之前是有讲过的:
参看:STM32开发 – RTC详解
参看:STM32开发 – 时钟系统详解
参看:STM32开发 – Systick定时器
软件实现:
参看:stm32f103的RTC作为闹钟唤醒单片机待机模式RTC_Alarm.rar
或者 百度网盘下载
●RTC中断配置
static void RTC_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQChannel; //RTC全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占优先级1位,从优先级3位
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能该通道中断
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}
●RTC闹钟初始化:启动时钟、配置LSI做RTC时钟、设置预分频40000得到1Hz设置运行时间WORK_TIMES
void RTC_Alarm_Configuration(void)
{
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
/* Reset Backup Domain */
BKP_DeInit();
/* RTC clock source configuration ----------------------------------------*/
/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{
}
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* 使能RTC闹钟中断*/
RTC_ITConfig(RTC_IT_ALR, ENABLE);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
RTC_SetPrescaler(40000);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
//中断配置
RTC_NVIC_Config();
//设置运行WORK_TIMES
RTC_SetAlarm(RTC_GetCounter() + WORK_TIMES);
RTC_WaitForLastTask();
}
●设置闹钟时长并进入待机,s为中断秒数
void RTC_Enter_StandbyMode(u32 s)
{
RTC_SetAlarm(RTC_GetCounter() + s);
RTC_WaitForLastTask();
// 进入待机模式, 此时所有1.8V域的时钟都关闭,HIS和HSE的振荡器关闭, 电压调节器关闭.
// 只有WKUP引脚上升沿,RTC警告事件,NRST引脚的外部复位,IWDG复位.
/* Request to enter STANDBY mode (Wake Up flag is cleared in PWR_EnterSTANDBYMode function) */
PWR_EnterSTANDBYMode();
}
●中断服务函数
void RTC_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)//闹钟中断
{
RTC_ClearITPendingBit(RTC_IT_ALR); //清闹钟中断
RTC_Enter_StandbyMode(STANDBY_TIMES);//进入待机
}
}
上面的这个示例,不是真正的RTC闹钟唤醒。而是通过闹钟来进入待机模式的。
不过根据需要更改一下代码,就可以得到相关的功能了。
重点在于RTC中断配置,和RTC_SetAlarm闹钟设置,这些倒是我之前没有总结过的。
IWDG复位
看门狗之前也有讲过的,参看:STM32开发 – 看门狗详解
//保存 WWDG 计数器的设置值,默认为最大.
u8 WWDG_CNT=0x7f;
//初始化窗口看门狗
//tr :T[6:0],计数器值
//wr :W[6:0],窗口值
//fprer:分频系数(WDGTB) ,仅最低 2 位有效
//Fwwdg=PCLK1/(4096*2^fprer).
void WWDG_Init(u8 tr,u8 wr,u32 fprer)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 时钟使能
WWDG_CNT=tr&WWDG_CNT; //初始化 WWDG_CNT.
WWDG_SetPrescaler(fprer); //设置 IWDG 预分频值
WWDG_SetWindowValue(wr); //设置窗口值
WWDG_Enable(WWDG_CNT); //使能看门狗,设置 counter
WWDG_ClearFlag(); //清除提前唤醒中断标志位
WWDG_NVIC_Init(); //初始化窗口看门狗 NVIC
WWDG_EnableIT(); //开启窗口看门狗中断
}
//重设置 WWDG 计数器的值
void WWDG_Set_Counter(u8 cnt)
{
WWDG_Enable(cnt); //使能看门狗,设置 counter .
}
//窗口看门狗中断服务程序
void WWDG_NVIC_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //WWDG 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占 2 子优先级 3 组 2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //抢占 2,子优先级 3,组 2
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure); //NVIC 初始化
}
void WWDG_IRQHandler(void)
{
WWDG_SetCounter(WWDG_CNT); //当禁掉此句后,窗口看门狗将产生复位
WWDG_ClearFlag(); //清除提前唤醒中断标志位
LED1=!LED1; //LED 状态翻转
}
在待机模式下,使用窗口看门狗,然后产生看门狗复位。
这个代码只做参考,没试过不知道能不能用。。。
二、低功耗模式概念介绍
上图里低功耗模式介绍里的内核、外设、系统时钟、1.8v内核电源,这些都是什么??
需要了解一下的。
1、电源
STM32的工作电压(VDD)为2.0~3.6V。通过内置的电压调节器提供所需的1.8V电源。
当主电源VDD掉电后,通过VBAT脚为实时时钟(RTC)和备份寄存器提供电源。
可以看出VDD为STM32提供供电,通过内置的电压调节器提供所需的1.8V电源,
1.8V供电区域为CPU核心存储器和内置数字外设。
当主电源VDD掉电后,通过VBAT脚为实时时钟(RTC)和备份寄存器提供电源。
VBAT是后备供电也就是通过后备电池来供电的。其供电区域为LSE 32K晶体振荡器、后备寄存器RCC BDCR和寄存器RTC。
现在再看这张低功耗的图。
停机和待机模式关闭的是所有1.8V区域的时钟。
其中待机对于VDD区域时钟的影响是HSI和HSE的振荡器关闭。
也就是说待机电路(唤醒逻辑和IWDG)是没有影响的,所以才能通过WKUP引脚的上升沿、IWDG复位等来唤醒呀。
2、外设
这里又有问题了,那么1.8V供电区域的置数字外设包含什么呢?
没有找到包含的数字外设,不过所有的内置外设倒是可以看一下。
其实最直观的就是看它的系统结构不就好了嘛。哈哈
3、系统时钟
上面老是提时钟时钟的,到底包含哪些时钟?
其实之前讲过的啦。
参看:STM32开发 – RTC详解
参看:STM32开发 – 时钟系统详解
那么停机和待机模式下,关闭所有1.8V区域的时钟。
是不是意味着关闭了内置数字外设时钟 APB1和APB2线上外设时钟PCKL1/PCLK2??
而在睡眠模式下CPU时钟关闭,对其他时钟和ADC时钟无影响。
这里的CPU时钟是不是就是Cortex系统时钟HCLK 呢??
(请大佬告知)
三、STM32F4低功耗模式
主要是比较一下:
stm32f10x_pwr.c 和 stm32f4xx_pwr.c
下载:百度网盘
发现多出了一些功能。
多出什么功能呢?? 下次有时间再写。。。
四、HAL库低功耗操作
还有以上讲的都是标准库,那么具体到HAL库低功耗又该如何操作?
首先HAL库和标准库的比较,需要了解一下。
参看:HAL库和标准库的比较 (哈哈,还没写)
然后这部分其实专门问过正点原子,2015年以后的都用HAL库。
那就简单了,网上找到对应的开发资料,程序源码里都是HAL库版本的例程。
加以参看说明就是了。
下载:正点原子阿波罗STM32F429开发板资料
或者参看:STM32MX电源管理低功耗模式
这里就不再重复讲了,重要的是学会举一反三。
五、总结思考
这篇文章主要是讲了一下待机模式通过RTC闹钟和看门狗复位进行退出待机功能、还有一些系统时钟、外设、电源等的概念。
还是剩下一些问题没有讲:
这三种低功耗模式该如何选择呢?
具体硬件该怎么测低功耗呢?
GPS/4G模块/蓝牙进入休眠和其他功能电路供电切断 这些又该如何操作?
且听下回分解!!!