1)实验平台:正点原子APM32E103最小系统板
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/docs/boards/xiaoxitongban
本章介绍APM32E103低功耗模式中的待机模式,进入待机模式后,MCU内部的电压调压器将断开1.3V电源域的电源,这意味着内核和外设都将停止工作,并且内核寄存器和内存中的数据都将丢失,但这也是功耗最低的模式,待机模式下可被WKUP引脚的上升沿唤醒。通过本章的学习,读者将学习到低功耗模式下待机模式的使用。
本章分为如下几个小节:
31.1 硬件设计
31.2 程序设计
31.3 下载验证
31.1 硬件设计
31.1.1 例程功能
#include "apm32e10x.h"
#include "apm32e10x_pmu.h"
void example_fun(void)
{
/* 使能WKUP引脚功能 */
PMU_EnableWakeUpPin();
}
②:清除PMU事件标志
该函数用于清除PMU的事件标志,其函数原型如下所示:
void PMU_ClearStatusFlag(PMU_FLAG_T flag);
该函数的形参描述,如下表所示:
形参 描述
flag 指定清除的PMU事件标志
例如:PMU_FLAG_WUE、PMU_FLAG_SB(在apm32e10x_pmu.h文件中有定义)
表31.2.1.3 函数PMU_ClearStatusFlag()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
无 无
表31.2.1.4 函数PMU_ClearStatusFlag()返回值描述
该函数的使用示例,如下所示:
#include "apm32e10x.h"
#include "apm32e10x_pmu.h"
void example_fun(void)
{
/* 清除PMU唤醒事件标志 */
PMU_ClearStatusFlag(PMU_FLAG_WUE);
}
③:进入待机模式
该函数用于进入待机模式,其函数原型如下所示:
void PMU_EnterSTANDBYMode(void);
该函数的形参描述,如下表所示:
形参 描述
无 无
表31.2.1.5 函数PMU_EnterSTANDBYMode()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
无 无
表31.2.1.6 函数PMU_EnterSTANDBYMode()返回值描述
该函数的使用示例,如下所示:
#include "apm32e10x.h"
#include "apm32e10x_pmu.h"
void example_fun(void)
{
/* 进入待机模式 */
PMU_EnterSTANDBYMode();
}
31.2.2 PMU驱动
本章实验的PMU驱动主要负责向应用层提供进入待机模式的函数。本章实验中,PMU的驱动代码主要包括pmu.c和pmu.h两个文件。
PMU驱动中,进入待机模式的函数,如下所示:
/**
* @brief 进入待机模式
* @param 无
* @retval 无
*/
void pmu_enter_standby(void)
{
/* 进入待机模式前,需先关闭EMMC时钟 */
RCM->AHBCLKEN_B.EMMC = DISABLE;
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU); /* 使能PMU时钟 */
/* 配置KEY_UP按键用于唤醒MCU */
PMU_EnableWakeUpPin();
PMU_ClearStatusFlag(PMU_FLAG_SB); /* 清除待机标志 */
PMU_ClearStatusFlag(PMU_FLAG_WUE); /* 清除唤醒标志 */
PMU_EnterSTANDBYMode(); /* 进入待机模式 */
}
从上面的代码中可以看出,在进入待机模式前还关闭了EMMC的时钟,这点非常重要,若进入待机模式时,EMMC的时钟为使能状态,则无法正常进入待机模式。随后还依次使能了WKUP引脚功能和清除唤醒标志,最后调用函数PMU_EnterSTANDBYMode()进入待机模式。
31.2.3 实验应用代码
本实验的应用代码,如下所示:
int main(void)
{
uint8_t key;
uint8_t t = 0;
NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_4); /* 设置中断优先级分组为组4 */
sys_apm32_clock_init(15); /* 配置系统时钟 */
delay_init(120); /* 初始化延时功能 */
usart_init(115200); /* 初始化串口 */
led_init(); /* 初始化LED */
lcd_init(); /* 初始化LCD */
key_init(); /* 初始化按键 */
lcd_show_string(30, 50, 200, 16, 16, "APM32", RED);
lcd_show_string(30, 70, 200, 16, 16, "STANDBY TEST", RED);
lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
lcd_show_string(30, 110, 200, 16, 16, "KEY0:Enter STANDBY MODE", RED);
lcd_show_string(30, 130, 200, 16, 16, "KEY_UP:Exit STANDBY MODE", RED);
while (1)
{
key = key_scan(0);
if (key == KEY0_PRES)
{
pmu_enter_standby(); /* 进入待机模式 */
}
if ((t % 20) == 0)
{
LED0_TOGGLE();
}
t++;
delay_ms(10);
}
}
从上面的代码中可以看出,在完成相关的初始化操作后,便不断地扫描按键,若扫描到KEY0按键被按下,则会进入待机模式,进入待机模式后LED0便不再闪烁,说明此时程序已经停止运行,进入了待机模式,此时可以按下KEY_UP按键进行待机模式唤醒,随后便可看到LED0恢复闪烁,说明程序再次运行。
33.3 下载验证
在完成编译和烧录操作后,可以看到 LED0 闪烁提示系统正在运行,此时可以按下 KEY0 按键,可以看到 LED0 不再闪烁,这是因为系统已经进入待机模式了,此时再按下 KEY_UP 按键,即可从待机模式下唤醒,可以看到 LED0 继续闪烁。