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

2023-11-07

1)实验平台:正点原子stm32f103战舰开发板V4
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html#

第三十一章 睡眠模式实验

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

31.1 硬件设计
31.1.1 例程功能

  1. 按下KEY0按键,点亮LED1并进入睡眠模式,按下KEY_UP按键,退出睡眠模式并熄灭LED1
  2. LED0闪烁,指示程序正在运行
    31.1.2 硬件资源
  3. LED
    LED0 - PF9
    LED1 - PF10
  4. 按键
    KEY0 - PE4
    KEY_UP - PA0
  5. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
    31.1.3 原理图
    本章实验介绍APM32F407低功耗模式中的睡眠模式,不涉及连接原理图。
    31.2 程序设计
    31.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_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);	\
    } while (0)
#define PMU_WKUP_SYSCFG_PORT	SYSCFG_PORT_GPIOA
#define PMU_WKUP_SYSCFG_PIN		SYSCFG_PIN_0
#define PMU_WKUP_EINT_LINE		EINT_LINE_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_APB2_PERIPH_SYSCFG);	/* 使能SYSCFG时钟 */
    
    gpio_init_struct.pin	= PMU_WKUP_GPIO_PIN;		/* 唤醒引脚 */
    gpio_init_struct.mode	= GPIO_MODE_IN;				/* 输入模式 */
    gpio_init_struct.pupd	= GPIO_PUPD_DOWN;			/* 下拉 */
    GPIO_Config(PMU_WKUP_GPIO_PORT, &gpio_init_struct);	/* 配置唤醒引脚 */
    
    /* 配置引脚作为事件线 */
    SYSCFG_ConfigEINTLine(SYSCFG_PORT_GPIOA, PMU_WKUP_SYSCFG_PIN);
    
    eint_init_struct.line		= PMU_WKUP_EINT_LINE;	/* 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)
{
    /* 指令WFI,进入睡眠模式,等待任意中断唤醒 */
    __WFI();
}

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

int main(void)
{
    uint8_t key;
    uint8_t t = 0;
    
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_3);	/* 设置中断优先级分组为组3 */
    sys_apm32_clock_init(336, 8, 2, 7);					/* 配置系统时钟 */
    delay_init(168);										/* 初始化延时功能 */
    usart_init(115200);									/* 初始化串口 */
    led_init();											/* 初始化LED */
    key_init();											/* 初始化按键 */
    lcd_init();											/* 初始化LCD */
    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-M4内核便停止了,从该睡眠模式唤醒需要有任意的中断产生,因此可以由KEY_UP按键产生外部中断来唤醒睡眠。退出睡眠模式后,LED1将被熄灭。
31.3 下载验证
在完成编译和烧录操作后,可以看到LED0闪烁提示系统程序正在运行,此时可以按下KEY0按键,可以看到LED1亮起,但LED0不再闪烁,这是因为系统已经进入睡眠模式了,此时再按下KEY_UP按键,即可从睡眠模式下唤醒,可以看到LED1熄灭,LED0继续闪烁。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【正点原子STM32连载】 第三十一章 睡眠模式实验 摘自【正点原子】APM32F407最小系统板使用指南 的相关文章

  • [linux] shell 输入/输出重定向 、 文件包含

    Shell 输入 输出重定向 大多数 UNIX 系统命令从终端接受输入并将所产生的输出发送回 到终端 一个命令通常从一个叫标准输入的地方读取输入 默认情况下 这恰好是自己的终端 同样 一个命令通常将其输出写入到标准输出 默认情况下 这也是自
  • flask 视频流直播

    flask 视频流直播 本文将介绍如何本地通过浏览器查看远端服务器的摄像头采集到的视频 服务端 实现实时视频流式传输主要采用服务器推送技术 服务器在响应请求时 HTTP使用MIME报文格式来封装数据 通常一个HTTP响应只能包含一个数据块
  • 关于 Error: Cannot find module ‘webpack/lib/RuleSet‘ 的详细解决方法(亲测有效)- 以及删除脚手架的方法

    对于出现的这个错误 之前我也尝试了网上的多种解决方案 最终经过测试后 是通过将原来的 vue cli 版本降级到 4 5 15 版本 最后再重新安装 node modules 包 才得以解决 下面是我将介绍怎么安装 4 5 15 版本的脚手

随机推荐

  • linux svn 用户名存储,Linux下SVN账户密码保存设置

    Linux下用SVN进行更新等操作时 总是提示输入用户名和密码 很不方便 因此搜了下解决办法 总结如下 Linux下用SVN进行更新等操作时 总是提示输入用户名和密码 很不方便 因此搜了下解决办法 总结如下 打开SVN配置文件 vim ho
  • SQL注入(2)——各种注入

    本专栏是笔者的网络安全学习笔记 一面分享 同时作为笔记 前文链接 WAMP DVWA sqli labs 搭建 burpsuite工具抓包及Intruder暴力破解的使用 目录扫描 请求重发 漏洞扫描等工具的使用 网站信息收集及nmap的下
  • 亲密关系沟通-【独特性】尊重与探索他人

    忽视自己是逃避 忽视对方也是逃避 故事 理发师抱怨老婆不换空调 你有没有问过她 为什么不愿意换 谁知道她怎么想的 你承认对方的独特性 就不用做任何改变 叙述测试 你讲述经历里的别人有ta的想法吗 如何把对方从一个活生生的人变成ta就是那样的
  • HTTPS为什么安全 &分析 HTTPS 连接建立全过程

    本文将分两个专题去理解HTTPS 专题一 HTTPS为什么安全 1 http为什么不安全 http协议属于明文传输协议 交互过程以及数据传输都没有进行加密 通信双方也没有进行任何认证 通信过程非常容易遭遇劫持 监听 篡改 严重情况下 会造成
  • WSL无法保存文件(权限不足)

    sudo chown R username 其中username是你的用户名
  • windows vscode 安装+配置go环境

    一下载 go语言官方下载地址 https golang org dl 找到适合你系统的版本下载 本人下载的是windows版本 也可以下载Source自己更深层次研究go语言 二安装 一路next 三 安装后目录 Go语言安装之后 C Go
  • WebApi 打个Attribute 统一处理异常

    我们处理异常的时候通常都要写形如以下的代码 try xxxxx catch Exception ex log write ex Message 前一段时间看杨中科的视频 其中吐糟了 mvc 的管道机制 当然用在web ui 的渲染上这个还不
  • Buck电路基础知识

    版权声明 本文为博主原创文章 遵循 CC 4 0 BY SA 版权协议 转载请附上原文出处链接和本声明 本文链接 https blog csdn net weixin 42005993 article details 120144144 这
  • Windows下libmodbus库的编译和使用

    一 前言 最近要搞一个PC端Qt上位机控制机械手的移动 需要用到串口io卡 控制的话需要使用libmodbus库 就想着自己编译一下libmodbus库 过程如下 二 编译过程 2 1 libmodbus的下载和安装 下载地址 https
  • pytorch7-可视化训练过程(过程中显示)

    import torch import torch nn as nn import torchvision import torchvision utils as vutils from torch optim import SGD imp
  • 安全连载——CSDN区块链大本营出品

    史上杀伤力最大的溢出型漏洞到底是什么 看这一篇就够了 第1期 4月发生的BEC事件以及SMT事件已经沉淀一段时间了 具体的情况也被多方媒体所报道 相关的漏洞根源问题也有很多大神团队的分析和指正 近日 有安全团队将各种已经发生或可能发生的类似
  • Marshaller和Unmarshaller用法示例

    import java io FileNotFoundException import java io FileOutputStream import java io OutputStream import javax xml bind J
  • Qt之QDialog禁用右上角关闭按钮

    setWindowFlags windowFlags Qt WindowCloseButtonHint
  • 【深度学习】笔记12:win10下的VS2013编辑代码的时候,非常卡顿,怎么样解决?

    给新电脑连续配置了三天环境 双系统下的caffe和NVIDIA环境配置好之后 终于可以看代码了 结果在vs2013下对代码进行注释的时候 代码编辑器用起来非常卡顿 这个问题的解决方法如下所示 1 首先确定是不是硬件和系统的问题 据说win8
  • 2.4.1 C# 和 F# 中的类型推断

    2 4 1 C 和 F 中的类型推断 大多数的类型有简称 例如 int 或 Random 只有很少一部分需要类型推断 因为手写类型名称并不困难 C 2 0 支持泛型 因此 可以构造更复杂的类型 在函数语言中的类型 像 F 是相当复杂的 尤其
  • R语言legend函数参数详解

    legend x y NULL legend fill NULL col par col border black lty lwd pch angle 45 density NULL bty o bg par bg box lwd par
  • Scala学习系列(二)——环境安装配置

    Scala下载地址 https www scala lang org download 一 安装JDK 首先 因为Scala是运行在JVM平台上的 所以安装Scala之前要安装JDK 二 二进制安装方式 我们可以直接用二进制安装Scala
  • 合并BPL包图文教程

    Delphi IDE 本身就是一个插件模式的工具 插件的好处不用多说 运行包的BPL 其实就是众多单元的集合 因此可以再次重新组合 只要你将各个BPL包用到的单元再组合一次 本文以 http code google com p tangra
  • libuv源码分析(1)事件循环分析

    前言 libuv总是报出一些让人难以理解的错误 作为一个C的项目 不具有Java JavaScript php那样的人气 很难百度到一些问题的答案 甚至google也不行 为了用好libuv 也为了学习吧 我开始看libuv的源码 不知道自
  • 【正点原子STM32连载】 第三十一章 睡眠模式实验 摘自【正点原子】APM32F407最小系统板使用指南

    1 实验平台 正点原子stm32f103战舰开发板V4 2 平台购买地址 https detail tmall com item htm id 609294757420 3 全套实验源码 手册 视频下载地址 http www openedv