当前位置: 首页 > news >正文

【正点原子STM32连载】 第二十九章 睡眠模式实验 摘自【正点原子】APM32E103最小系统板使用指南

1)实验平台:正点原子APM32E103最小系统板
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/docs/boards/xiaoxitongban

第二十九章 睡眠模式实验

本章介绍APM32E103低功耗模式中的睡眠模式,通过调用WFI命令进入睡眠模式后,ARM Corten-M3内核将停止以降低功耗,在该睡眠模式下可以被任意中断唤醒。通过本章的学习,读者将学习到低功耗模式中睡眠模式的使用。
本章分为如下几个小节:
29.1 硬件设计
29.2 程序设计
29.3 下载验证

29.1 硬件设计
29.1.1 例程功能

  1. 按下KEY0按键,点亮LED1并进入睡眠模式,按下KEY_UP按键,退出睡眠模式并熄灭LED1
  2. LED0闪烁,指示程序正在运行
    29.1.2 硬件资源
  3. LED
    LED0 - PB5
    LED1 - PE5
  4. 按键
    KEY0 - PE4
    KEY_UP - PA0
  5. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
    29.1.3 原理图
    本章实验介绍APM32E103低功耗模式中的睡眠模式,不涉及连接原理图。
    29.2 程序设计
    29.2.1 PMU驱动
    本章实验的PMU驱动主要负责向应用层提供睡眠模式唤醒按键的初始化和进入睡眠模式的函数,同时实现唤醒按键的中断回调函数。本章实验中,PMU的驱动代码主要包括pmu.c和pmu.h两个文件。
    PMU驱动中,睡眠模式唤醒按键的相关宏定义,如下所示:
    /* 模式唤醒引脚定义 */
#define PMU_WKUP_GPIO_PORT          GPIOA
#define PMU_WKUP_GPIO_PIN           GPIO_PIN_0
#define PMU_WKUP_GPIO_CLK_ENABLE()  do{ RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA); }while(0)
#define PMU_WKUP_INT_IRQn           EINT0_IRQn
#define PMU_WKUP_INT_IRQHandler     EINT0_IRQHandler
PMU驱动中,睡眠模式唤醒按键的初始化函数,如下所示:
/*** @brief       初始化唤醒按键* @param       无* @retval      无*/
void pmu_wkup_key_init(void)
{GPIO_Config_T gpio_init_struct;EINT_Config_T eint_init_struct;PMU_WKUP_GPIO_CLK_ENABLE();                          /* 使能唤醒引脚端口时钟 */RCM_EnableAPB2PeriphClock(RCM_APB1_PERIPH_PMU);      /* 使能PMU时钟 */gpio_init_struct.pin = PMU_WKUP_GPIO_PIN;            /* 唤醒引脚 */gpio_init_struct.mode = GPIO_MODE_IN_PD;             /* 输入模式 */GPIO_Config(PMU_WKUP_GPIO_PORT, &gpio_init_struct);  /* 配置唤醒引脚 */eint_init_struct.line=(EINT_LINE_T)PMU_WKUP_GPIO_PIN;/* EINT线 */eint_init_struct.mode=EINT_MODE_INTERRUPT;           /* 中断模式 */eint_init_struct.trigger=EINT_TRIGGER_RISING;        /* 上升沿 */eint_init_struct.lineCmd=ENABLE;                     /* 使能 */EINT_Config(&eint_init_struct);                      /* 配置EINT */NVIC_EnableIRQRequest(PMU_WKUP_INT_IRQn, 2, 0);      /* 使能中断 */
}

因为调用WFI命令进入睡眠模式后,能够被任意的中断唤醒,因此睡眠模式唤醒按键的初始化只需要配置好按键的外部中断即可。
PMU驱动中,睡眠模式唤醒按键对应的中断回调函数,如下所示:

/*** @brief       唤醒引脚外部中断服务函数* @param       无* @retval      无*/
void PMU_WKUP_INT_IRQHandler(void)
{   
/* 判断唤醒引脚事件线中断标志 */if (EINT_ReadIntFlag((EINT_LINE_T)PMU_WKUP_GPIO_PIN) == SET)
{  
/* 清除唤醒引脚事件线中断标志 */EINT_ClearIntFlag((EINT_LINE_T)PMU_WKUP_GPIO_PIN);}
}
因为睡眠唤醒按键的中断只是为了唤醒睡眠模式,因此并不需要在中断回调函数中做任何处理。
PMU驱动中,进入睡眠模式的函数,如下所示:
/*** @brief       进入睡眠模式* @param       无* @retval      无*/
void pmu_enter_sleep(void)
{   
/* 禁用SysTick的中断,防止SysTick中断唤醒 */SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
NVIC_ResetystemLowPower(NVIC_LOWPOWER_SLEEPDEEP);   /* 配置为睡眠模式 */
/* 指令WFI,进入睡眠模式,等待任意中断唤醒 */__WFI();SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;          /* 使能SysTick中断 */
}

从上面的代码中可以看出,进入睡眠模式主要就是执行WFI命令,接下来MCU便会进入睡眠模式,等待任意的中断唤醒,因此在执行WFI命令之前,需要先关闭部分中断,以免误唤醒。
29.2.2 实验应用代码
本实验的应用代码,如下所示:

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, "SLEEP TEST", RED);lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);lcd_show_string(30, 110, 200, 16, 16, "KEY0:Enter SLEEP MODE", RED);lcd_show_string(30, 130, 200, 16, 16, "KEY_UP:Exit SLEEP MODE", RED);while (1){key = key_scan(0);if (key == KEY0_PRES){LED1(0);                               /* 点亮LED1,提示进入睡眠模式 */pmu_enter_sleep();                     /* 进入睡眠模式 */LED1(1);                               /* 熄灭LED1,提示退出睡眠模式 */}if ((t % 20) == 0){LED0_TOGGLE();}t++;delay_ms(10);}
}

从上面的代码中可以看出,在完成相关的初始化操作后,并不断地扫描按键,若扫描到KEY0按键被按下,则会点亮LED1后进入睡眠模式,此时ARM Cortex-M3内核便停止了,从该睡眠模式唤醒需要有任意的中断产生,因此可以由KEY_UP按键产生外部中断来唤醒睡眠。退出睡眠模式后,LED1将被熄灭。
29.3 下载验证
在完成编译和烧录操作后,可以看到LED0闪烁提示系统程序正在运行,此时可以按下KEY0按键,可以看到LED1亮起,但LED0不再闪烁,这是因为系统已经进入睡眠模式了,此时再按下KEY_UP按键,即可从睡眠模式下唤醒,可以看到LED1熄灭,LED0继续闪烁。

相关文章:

  • 微服务自动化docker-compose
  • 软件测试实习生的最后一天,四小时四场技术面试(三)
  • 基于uniapp封装的card容器 带左右侧两侧标题内容区域
  • 安卓adb
  • PHP开发日志 ━━ 不同方法判断某个数组中是否存在指定的键名,测试哪种方法效率高
  • 2024.01.09.Apple_UI_BUG
  • Android Retrofit使用详情
  • 行云部署成长之路 -- 慢 SQL 优化之旅 | 京东云技术团队
  • useContext
  • RetryTemplate
  • c# 人脸识别的思路
  • 【C++】取整函数ceil(),floor(),round()
  • vue computed计算不到数组或者对象的变化
  • 什么是云服务器ECS - 云服务器 ECS - 阿里云
  • zookeeper下载安装部署
  • cookie和session
  • javascript 哈希表
  • JavaScript类型识别
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • 免费小说阅读小程序
  • 前嗅ForeSpider教程:创建模板
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 三分钟教你同步 Visual Studio Code 设置
  • 世界上最简单的无等待算法(getAndIncrement)
  • 数据仓库的几种建模方法
  • 一道面试题引发的“血案”
  • 1.Ext JS 建立web开发工程
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ​油烟净化器电源安全,保障健康餐饮生活
  • #Spring-boot高级
  • (Ruby)Ubuntu12.04安装Rails环境
  • (第61天)多租户架构(CDB/PDB)
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (转)大道至简,职场上做人做事做管理
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .netcore如何运行环境安装到Linux服务器
  • .net用HTML开发怎么调试,如何使用ASP.NET MVC在调试中查看控制器生成的html?
  • .NET中的十进制浮点类型,徐汇区网站设计
  • /etc/sudoer文件配置简析
  • :=
  • @property python知乎_Python3基础之:property
  • [20171113]修改表结构删除列相关问题4.txt
  • [Erlang 0129] Erlang 杂记 VI 2014年10月28日
  • [ISCTF 2023]——Web、Misc较全详细Writeup、Re、Crypto部分Writeup
  • [java基础揉碎]方法的重写/覆盖
  • [MySQL复制异常]Cannot execute statement: impossible to write to binary log since statement is in row for
  • [node] Node.js的Web 模块
  • [office] Excel自带的编辑函数求和方法 #其他#媒体