1)实验平台:正点原子APM32E103最小系统板
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/docs/boards/xiaoxitongban
第三十章 停止模式实验
本章介绍APM32E103低功耗模式中的停止模式,进入停止模式后,所有的时钟都将被停止以降低功耗,在停止模式下可以被任意中断唤醒。通过本章的学习,读者将学习到低功耗模式中停止模式的使用。
本章分为如下几个小节:
30.1 硬件设计
30.2 程序设计
30.3 下载验证
30.1 硬件设计
30.1.1 例程功能
- 按下KEY0按键,点亮LED1并进入停止模式,按下KEY_UP按键,退出停止模式并熄灭LED1
- LED0闪烁,指示程序正在运行
30.1.2 硬件资源 - LED
LED0 - PB5
LED1 - PE5 - 按键
KEY0 - PE4
LEY_UP - PA0 - 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
30.1.3 原理图
本章实验介绍APM32E103低功耗模式中的停止模式,不涉及连接原理图。
30.2 程序设计
30.2.1 Geehy标准库的PMU驱动
Geehy标准库中提供了配置进入停止模式的驱动函数,其配置步骤如下:
①:进入停止模式
在Geehy标准库中对应的驱动函数如下:
①:进入停止模式
该函数用于进入停止模式,其函数原型如下所示:
void PMU_EnterSTOPMode(PMU_REGULATOR_T regulator, PMU_STOP_ENTRY_T entry);
该函数的形参描述,如下表所示:
形参 描述
regulator 停止模式下调压器的工作状态
例如:PMU_REGULATOR_ON、PMU_REGULATOR_LOWPOWER(在apm32e10x_pmu.h文件中有定义)
entry 进入停止模式的方式
例如:PMU_STOP_ENTRY_WFI、PMU_STOP_ENTRY_WFE(在apm32e10x_pmu.h文件中有定义)
表30.2.1.1 函数PMU_EnterSTOPMode()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
无 无
表30.2.1.2 函数PMU_EnterSTOPMode()返回值描述
该函数的使用示例,如下所示:
#include "apm32e10x.h"
#include "apm32e10x_pmu.h"void example_fun(void)
{/* 配置以WFI方式进入停止模式,同时配置调压器进入低功耗模式 */PMU_EnterSTOPMode(PMU_REGULATOR_LOWPOWER, PMU_STOP_ENTRY_WFI);
}
30.2.2 PMU驱动
本章实验的PMU驱动主要负责向应用层提供停止模式唤醒按键的初始化和进入停止模式的函数,同时实现唤醒按键的中断回调函数。本章实验中,PMU的驱动代码主要包括pmu.c和pmu.h两个文件。
因为本章实验中停止模式的唤醒方式与上一章实验中睡眠模式的唤醒方式一致,都是可以由任意的中断唤醒,且均使用了KEY_UP按键的外部中断进行唤醒,因此本章实验中停止模式唤醒按键的相关宏定义、停止模式唤醒按键的初始化及其中断回调函数均与上一章实验一致,因此请读者自行查看上一章中的相关内容。
PMU驱动中,进入睡眠模式的函数,如下所示:
/**
- @brief 进入停止模式
- @param 无
- @retval 无
/
void pmu_enter_stop(void)
{
/ 禁用SysTick的中断,防止SysTick中断唤醒 /
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
/ 执行WFI,进入停止模式,同时设置调节器工作在低功耗模式 /
PMU_EnterSTOPMode(PMU_REGULATOR_LOWPOWER, PMU_STOP_ENTRY_WFI);
/ 使能SysTick中断 */
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
}
从上面的代码中可以看出,该函数调用了函数PMU_EnterSTOPMode()以WFI方式进入停止模式,接下来MCU便会进入停止模式,等待任意的中断唤醒,因此在执行此函数前,需要先关闭部分中断,以免误唤醒。
30.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(); /* 初始化按键 */pmu_wkup_key_init(); /* 初始化唤醒按键 */lcd_show_string(30, 50, 200, 16, 16, "APM32", RED);lcd_show_string(30, 70, 200, 16, 16, "STOP TEST", RED);lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);lcd_show_string(30, 110, 200, 16, 16, "KEY0:Enter STOP MODE", RED);lcd_show_string(30, 130, 200, 16, 16, "KEY_UP:Exit STOP MODE", RED);while (1){key = key_scan(0);if (key == KEY0_PRES){LED1(0); /* 点亮LED1,提示进入停止模式 */pmu_enter_stop(); /* 进入停止模式 */LED1(1); /* 熄灭LED1,提示退出停止模式 */}if ((t % 20) == 0){LED0_TOGGLE();}t++;delay_ms(10);}
}
从上面的代码中可以看出,在完成相关的初始化操作后,便不断地扫描按键,若扫描到KEY0按键被按下,则会点亮LED1后进入停止模式,此时所有的时钟将会停止,从该停止模式唤醒需要有任意的中断产生,因此可以由KEY_UP按键产生外部中断来唤醒停止模式。退出停止模式后,LED1将被熄灭。
30.3 下载验证
在完成编译和烧录操作后,可以看到LED0闪烁提示系统正在运行,此时可以按下KEY0按按键,可以看到LED1亮起,但LED0不再闪烁,这是因为系统已经进入停止模式了,此时再按下KEY_UP按键,即可从停止模式下唤醒,可以看到LED1熄灭,LED0继续闪烁。