你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。
chrome
firefox
safari
ie8及以上
ST
意法半导体官网
STM32
中文官网
ST
全球论坛
登录/注册
首页
技术问答
话题
资源
创客秀
视频
标签
积分商城
每日签到
【安富莱】【RTX操作系统教程】第23章 RTX低功耗之待机...
[复制链接]
baiyongbin2009
发布时间:2016-2-16 14:52
文章
文章封面:
-
文章简介:
-
本帖最后由 baiyongbin2009 于 2016-2-18 15:25 编辑
完整PDF教程和例子下载:
https://pan.baidu.com/s/1c0V2Why
ãRTXæä½ç³»ç»æç¨ã第23ç« RTXä½åèä¹å¾ æºæ¨¡å¼.pdf
(662.13 KB, 下载次数: 12)
2016-2-16 14:47 上传
点击文件名下载附件
第23章
RTX
低功耗之待机模式
低功耗是MCU的一项非常重要的指标,本章节为大家讲解STM32F103和STM32F407的低功耗方式之待机模式在RTX操作系统上面的实现方法(
RTX本身支持的tickless低功耗模式在第24章节讲解
)
本章教程配套的例子含Cortex-M3内核的STM32F103和Cortex-M4内核的STM32F407。
23.1 STM32F103待机模式介绍
23.2 STM32F407待机模式介绍
23.3 实验例程说明
23.4 总结
23.1 STM32F103待机模式介绍
说明:在RTX系统上面实现待机方式仅需了解这里讲解的知识基本就够用了,更多休眠方式的知识请看STM32F103参考手册和Cortex-M3权威指南。
在系统或电源复位以后,微控制器处于运行状态。当CPU不需继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个外部事件时。用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。
STM32F103有三种低功耗模式:
(1)
睡眠模式(Cortex™-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统滴答定时器Systick等仍在运行)。
(2)停止模式(所有的时钟都已停止)。
(3)待机模式(1.8V电源关闭)。
本章节我们主要讲解待机模式,待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失,只有备份的寄存器和待机电路维持供电。
在实际的待机模式编程时需要清楚那些问题呢? 请继续往下看。
23.1.1 STM32F103如何进入待机模式
在RTX系统中,让STM32进入待机模式比较容易,调用固件库函数PWR_EnterSTANDBYMode即可。
23.1.2 STM32F103如何退出待机模式
让STM32从待机模式唤醒可以通过外部复位(NRST引脚)、IWDG复位、WKUP引脚上的上升沿或RTC闹钟事件的上升沿。从待机唤醒后,除了电源控制/状寄存器,所有寄存器被复位。
从待机模式唤醒后的代码执行等同于复位后的执行。电源控制/状态寄存器(PWR_CSR)将会指示内核由待机状态退出。
在开发板上面是通过K2按键来唤醒,K2按键使用的引脚就是WKUP引脚。
23.1.3 STM32F103使用待机模式注意事项
待机模式要注意以下问题:
(1)
在待机模式下,所有的I/O引脚处于高阻态,除了以下的引脚:
A. 复位引脚(始终有效)。
B. 当被设置为防侵入或校准输出时的TAMPER引脚。
C. 被使能的唤醒引脚。
赞
0
收藏
0
评论
5
分享
发布时间:2016-2-16 14:52
举报
请先
登录
后回复
5个回答
baiyongbin2009
回答时间:2016-2-16 15:02:00
a0a.1 32b0c
23.2 STM32F407待机模式介绍
说明:在RTX系统上面实现待机方式仅需了解这里讲解的知识基本就够用了,更多休眠方式的知识请看STM32F407参考手册和Cortex-M4权威指南。
在系统或电源复位以后,微控制器处于运行状态。当CPU不需继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个外部事件时。用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。
STM32F407有三种低功耗模式:
(1)
睡眠模式(Cortex™-M4F内核停止,所有外设包括Cortex-M4核心的外设,如NVIC、系统滴答定时器Systick等仍在运行)。
(2)停止模式(所有的时钟都已停止)。
(3)待机模式(1.2V电源关闭)。
本章节我们主要讲解待机模式,待机模式下可达到最低功耗。待机模式基于Cortex™-M4F深度睡眠模式,其中调压器被禁止。因此1.2 V域断电。PLL、HSI振荡器和HSE 振荡器也将关闭。除备份域RTC寄存器、RTC备份寄存器和备份SRAM)和待机电路中的寄存器外,SRAM 和寄存器内容都将丢失。
在实际的待机模式编程时需要清楚那些问题呢? 请继续往下看。
23.2.1 STM32F407如何进入待机模式
在RTX系统中,让STM32进入待机模式比较容易,调用固件库函数PWR_EnterSTANDBYMode即可。
23.2.2 STM32F407如何退出待机模式
让STM32从待机模式唤醒可以通过外WKUP 引脚上升沿、RTC闹钟(闹钟A和闹钟B)、RTC唤醒事件、RTC入侵事件、RTC 时间戳事件、NRST引脚外部复位和IWDG 复位,唤醒后除了电源控制/状寄存器,所有寄存器被复位。
从待机模式唤醒后,程序将按照复位(启动引脚采样、复位向量已获取等)后的方式重新执行。PWR 电源控制/ 状态寄存器(PWR_CSR)中的SBF状态标志指示MCU已处于待机模式。
在开发板上面是通过K2按键来唤醒,K2按键使用的引脚就是RTC入侵事件检测引脚PC13。
23.2.3 STM32F407使用待机模式注意事项
待机模式要注意以下问题:
(1)
将选择的待机模式唤醒源(RTC闹钟A、RTC闹钟B、RTC唤醒、RTC入侵或RTC时间戳标志)对应的RTC标志清零,防止无法正常进入待机模式。
(2)待机模式下的 I/O 状态
A. 复位引脚(仍可用)。
B. RTC_AF1 引脚 (PC13)(如果针对入侵、时间戳、RTC闹钟输出或RTC时钟校准输出进行了配置)。
C. WKUP引脚 (PA0)(如果使能)。
赞
评论
回复
支持
反对
baiyongbin2009
回答时间:2016-2-16 15:38:36
a0a.1 32b0c
23.3 实验例程说明
23.3.1 STM32F103开发板实验
配套例子:
V4-423_RTX实验_低功耗(待机模式)
实验目的:
1. 学习RTX实验低功耗(待机模式)。
实验内容:
1. K1按键按下,串口打印。
2. K2键按下,直接发送信号量同步信号给任务AppTaskMsgPro,任务AppTaskMsgPro接收到消息后进行消息处理。K2按键还有一个功能就是将系统从待机模式唤醒。
3. K3按键按下,系统进入到待机模式。
4. 各个任务实现的功能如下:
AppTaskUserIF任务 :按键消息处理。
AppTaskLED任务 :LED闪烁。
AppTaskMsgPro任务 :消息处理,等待任务AppTaskUserIF发来的信号量同步信号。
AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现按键扫描。
5. 关于低功耗的说明:
(1) 待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器整
个1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。
(2) 从待机模式唤醒后的代码执行等同于复位后的执行。
6. 实际项目中推荐采用官方的tickless模式。
设计低功耗主要从以下几个方面着手:
1. 用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式可以使用的低功耗方式有休眠模式,待机模式,停机模式。
2. 选择了低功耗方式后就是关闭可以关闭的外设时钟。
3. 降低系统主频。
4. 注意I/O的状态。
如果此I/O口带上拉,请设置为高电平输出或者高阻态输入;
如果此I/O口带下拉,请设置为低电平输出或者高阻态输入;
a.在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态。
b.在停机模式下,所有的I/O引脚都保持它们在运行模式时的状态。
c.在待机模式下,所有的I/O引脚处于高阻态,除了以下的引脚:
● 复位引脚(始终有效)。
● 当被设置为防侵入或校准输出时的TAMPER引脚。
● 被使能的唤醒引脚。
5.注意I/O和外设IC的连接。
6.测低功耗的时候,一定不要连接调试器,更不能边调试边测电流。
RTX
配置:
RTX配置向导详情如下:
Task Configuration
Number of concurrent running tasks
允许创建4个任务,实际创建了如下四个任务:
AppTaskUserIF任务 :按键消息处理。
AppTaskLED任务 :LED闪烁。
AppTaskMsgPro任务 :消息处理,等待任务AppTaskUserIF发来的消息邮箱数据。
AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现按键扫描。
Number of tasks with user-provided stack
创建的4个任务都是采用自定义堆栈方式。
RTX
任务调试信息:
程序设计:
任务栈大小分配:
staticuint64_t AppTaskUserIFStk[512/8]; /* 任务栈 */
staticuint64_t AppTaskLEDStk[256/8]; /* 任务栈 */
staticuint64_t AppTaskMsgProStk[512/8]; /* 任务栈 */
staticuint64_t AppTaskStartStk[512/8]; /* 任务栈 */
将任务栈定义成uint64_t类型可以保证任务栈是8字节对齐的,8字节对齐的含义就是数组的首地址对8求余等于0。如果不做8字节对齐的话,部分C语言库函数,浮点运算和uint64_t类型数据运算会出问题。
系统栈大小分配:
外设初始化:
使能WKUP引脚PA0,用于将系统从待机模式唤醒。在bsp.c文件里面调用。
/*
*********************************************************************************************************
* 函 数 名: bsp_Init
* 功能说明: 初始化硬件设备。只需要调用一次。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。
* 全局变量。
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_Init(void)
{
/* 优先级分组设置为4, 优先配置好NVIC */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* 使能WKUP 引脚PA0,用于将系统从待机模式唤醒 */
PWR_WakeUpPinCmd(ENABLE);
bsp_InitUart(); /* 初始化串口 */
bsp_InitLed(); /* 初始LED指示灯端口 */
bsp_InitKey(); /* 初始化按键 */
}
复制代码
RTX
初始化:
/*
*********************************************************************************************************
* 函 数 名: main
* 功能说明: 标准c程序入口。
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
int main (void)
{
/* 初始化外设 */
bsp_Init();
/* 创建启动任务 */
os_sys_init_user (AppTaskStart, /* 任务函数 */
4, /* 任务优先级 */
&AppTaskStartStk, /* 任务栈 */
sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */
while(1);
}
复制代码
RTX
任务创建:
/*
*********************************************************************************************************
* 函 数 名: AppTaskCreate
* 功能说明: 创建应用任务
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void AppTaskCreate (void)
{
HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, /* 任务函数 */
1, /* 任务优先级 */
&AppTaskUserIFStk, /* 任务栈 */
sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */
HandleTaskLED = os_tsk_create_user(AppTaskLED, /* 任务函数 */
2, /* 任务优先级 */
&AppTaskLEDStk, /* 任务栈 */
sizeof(AppTaskLEDStk)); /* 任务栈大小,单位字节数 */
HandleTaskMsgPro = os_tsk_create_user(AppTaskMsgPro, /* 任务函数 */
3, /* 任务优先级 */
&AppTaskMsgProStk, /* 任务栈 */
sizeof(AppTaskMsgProStk)); /* 任务栈大小,单位字节数 */
}
复制代码
信号量创建:
static OS_SEM semaphore;
/*
*********************************************************************************************************
* 函 数 名: AppObjCreate
* 功能说明: 创建任务通信机制
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void AppObjCreate (void)
{
/* 创建信号量计数值是0, 用于任务同步 */
os_sem_init (&semaphore, 0);
}
复制代码
四个RTX任务的实现:
/*
*********************************************************************************************************
* 函 数 名: AppTaskUserIF
* 功能说明: 按键消息处理
* 形 参: 无
* 返 回 值: 无
* 优 先 级: 1 (数值越小优先级越低,这个跟uCOS相反)
*********************************************************************************************************
*/
__task void AppTaskUserIF(void)
{
uint8_t ucKeyCode;
while(1)
{
ucKeyCode = bsp_GetKey();
if (ucKeyCode != KEY_NONE)
{
switch (ucKeyCode)
{
/* K1键按下,打印调试说明 */
case KEY_DOWN_K1:
printf("K1键按下,使用MDK中自带的RTX调试组件,请务必使用MDK4.74版本进行调试\r\n");
break;
/* K2键按下,直接发送信号量同步信号给任务AppTaskMsgPro */
case KEY_DOWN_K2:
printf("K2键按下,直接发送信号量同步信号给任务AppTaskMsgPro\r\n");
os_sem_send (&semaphore);
break;
/* 其他的键值不处理 */
default:
break;
}
}
os_dly_wait(20);
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskLED
* 功能说明: LED闪烁。
* 形 参: 无
* 返 回 值: 无
* 优 先 级: 2
*********************************************************************************************************
*/
__task void AppTaskLED(void)
{
const uint16_t usFrequency = 200; /* 延迟周期 */
/* 设置延迟周期 */
os_itv_set(usFrequency);
while(1)
{
bsp_LedToggle(2);
bsp_LedToggle(3);
/* os_itv_wait是绝对延迟,os_dly_wait是相对延迟。*/
os_itv_wait();
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskMsgPro
* 功能说明: 消息处理,等待任务AppTaskUserIF发来的信号量同步信号
* 形 参: 无
* 返 回 值: 无
* 优 先 级: 3
*********************************************************************************************************
*/
__task void AppTaskMsgPro(void)
{
OS_RESULT xResult;
const uint16_t usMaxBlockTime = 200; /* 延迟周期 */
while(1)
{
xResult = os_sem_wait (&semaphore, usMaxBlockTime);
switch (xResult)
{
/* 无需等待接受到信号量同步信号 */
case OS_R_OK:
printf("无需等待接受到信号量同步信号\r\n");
break;
/* 信号量不可用,usMaxBlockTime等待时间内收到信号量同步信号 */
case OS_R_SEM:
printf("信号量不可用,usMaxBlockTime等待时间内收到信号量同步信号\r\n");
break;
/* 超时 */
case OS_R_TMO:
bsp_LedToggle(1);
bsp_LedToggle(4);
break;
/* 其他值不处理 */
default:
break;
}
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskStart
* 功能说明: 启动任务,也就是最高优先级任务。这里实现按键扫描。
* 形 参: 无
* 返 回 值: 无
* 优 先 级: 4
*********************************************************************************************************
*/
__task void AppTaskStart(void)
{
/* 创建任务 */
AppTaskCreate();
/* 创建任务通信机制 */
AppObjCreate();
while(1)
{
/* 按键扫描 */
bsp_KeyScan();
os_dly_wait(10);
}
}
复制代码
赞
评论
回复
支持
反对
baiyongbin2009
回答时间:2016-2-16 15:44:02
a0a.1 32b0c
23.3.2 STM32F407开发板实验
配套例子:
V5-423_RTX实验_低功耗(待机模式)
实验目的:
1. 学习RTX实验低功耗(待机模式)。
实验内容:
1. K1按键按下,串口打印。
2. K2键按下,直接发送信号量同步信号给任务AppTaskMsgPro,任务AppTaskMsgPro接收到消息后进行消息处理。
3. K2按键还有一个功能是将系统从待机模式唤醒,唤醒方式是用过K2按键对应的引脚PC13检测
RTC的入侵事件。
4. K3按键按下,系统进入到待机模式。
5. 各个任务实现的功能如下:
AppTaskUserIF任务 :按键消息处理。
AppTaskLED任务 :LED闪烁。
AppTaskMsgPro任务 :消息处理,等待任务AppTaskUserIF发来的信号量同步信号。
AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现按键扫描。
6. 关于低功耗的说明:
(1) 待机模式可实现系统的最低功耗。该模式是在Cortex-M4F深睡眠模式时关闭电压调节器整
个1.2V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。
(2) 从待机模式唤醒后的代码执行等同于复位后的执行。
7. 实际项目中推荐采用官方的tickless模式。
设计低功耗主要从以下几个方面着手:
1. 用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式可以使用的低功耗方式有休眠模式,待机模式,停机模式。
2. 选择了低功耗方式后就是关闭可以关闭的外设时钟。
3. 降低系统主频。
4. 注意I/O的状态。
如果此I/O口带上拉,请设置为高电平输出或者高阻态输入;
如果此I/O口带下拉,请设置为低电平输出或者高阻态输入;
a.在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态。
b.在停机模式下,所有的I/O引脚都保持它们在运行模式时的状态。
c.在待机模式下,所有的I/O引脚处于高阻态,除了以下的引脚:
● 复位引脚(仍可用)。
● RTC_AF1 引脚 (PC13)(如果针对入侵、时间戳、 RTC 闹钟输出或 RTC 时钟校准输出进
行了配置)。
● WKUP 引脚 (PA0)(如果使能)。
5.注意I/O和外设IC的连接。
6.测低功耗的时候,一定不要连接调试器,更不能边调试边测电流。
RTX
配置:
RTX配置向导详情如下:
Task Configuration
Number of concurrent running tasks
允许创建4个任务,实际创建了如下四个任务:
AppTaskUserIF任务 :按键消息处理。
AppTaskLED任务 :LED闪烁。
AppTaskMsgPro任务 :消息处理,等待任务AppTaskUserIF发来的消息邮箱数据。
AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现按键扫描。
Number of tasks with user-provided stack
创建的4个任务都是采用自定义堆栈方式。
RTX
任务调试信息:
程序设计:
任务栈大小分配:
staticuint64_t AppTaskUserIFStk[512/8]; /* 任务栈 */
staticuint64_t AppTaskLEDStk[256/8]; /* 任务栈 */
staticuint64_t AppTaskMsgProStk[512/8]; /* 任务栈 */
staticuint64_t AppTaskStartStk[512/8]; /* 任务栈 */
将任务栈定义成uint64_t类型可以保证任务栈是8字节对齐的,8字节对齐的含义就是数组的首地址对8求余等于0。如果不做8字节对齐的话,部分C语言库函数,浮点运算和uint64_t类型数据运算会出问题。
系统栈大小分配:
RTX
初始化:
/*
*********************************************************************************************************
* 函 数 名: main
* 功能说明: 标准c程序入口。
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
int main (void)
{
/* 初始化外设 */
bsp_Init();
/* 创建启动任务 */
os_sys_init_user (AppTaskStart, /* 任务函数 */
4, /* 任务优先级 */
&AppTaskStartStk, /* 任务栈 */
sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */
while(1);
}
复制代码
RTX
任务创建:
/*
*********************************************************************************************************
* 函 数 名: AppTaskCreate
* 功能说明: 创建应用任务
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void AppTaskCreate (void)
{
HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, /* 任务函数 */
1, /* 任务优先级 */
&AppTaskUserIFStk, /* 任务栈 */
sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */
HandleTaskLED = os_tsk_create_user(AppTaskLED, /* 任务函数 */
2, /* 任务优先级 */
&AppTaskLEDStk, /* 任务栈 */
sizeof(AppTaskLEDStk)); /* 任务栈大小,单位字节数 */
HandleTaskMsgPro = os_tsk_create_user(AppTaskMsgPro, /* 任务函数 */
3, /* 任务优先级 */
&AppTaskMsgProStk, /* 任务栈 */
sizeof(AppTaskMsgProStk)); /* 任务栈大小,单位字节数 */
}
复制代码
信号量创建:
static OS_SEM semaphore;
/*
*********************************************************************************************************
* 函 数 名: AppObjCreate
* 功能说明: 创建任务通信机制
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void AppObjCreate (void)
{
/* 创建信号量计数值是0, 用于任务同步 */
os_sem_init (&semaphore, 0);
}
复制代码
K2
按键(PC13引脚)RTC入侵事件检测的实现,在bsp.c文件中:
/*
*********************************************************************************************************
* 函 数 名: bsp_Init
* 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_Init(void)
{
/* 优先级分组设置为4, 优先配置好NVIC */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
bsp_InitUart(); /* 初始化串口 */
bsp_InitKey(); /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */
/* 针对不同的应用程序,添加需要的底层驱动模块初始化函数 */
bsp_InitLed(); /* 初始LED指示灯端口 */
bsp_rtctamper();
}
/*
*********************************************************************************************************
* 函 数 名: bsp_rtctamper
* 功能说明: 配置RTC的入侵事件来唤醒待机模式,另外用户不需要写入侵中断函数。
* 因为系统进入到待机模式后,检测到入侵事件后系统的执行过程等同于进行复位。
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void bsp_rtctamper(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
/* 使能PWR时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* 允许访问RTC */
PWR_BackupAccessCmd(ENABLE);
/* 选择RTC时钟源 LSI */
RCC_LSICmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) != RESET);
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
/* 使能外部中断 */
EXTI_ClearITPendingBit(EXTI_Line21);
EXTI_InitStructure.EXTI_Line = EXTI_Line21;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* 使能中断通道 TAMPER */
NVIC_InitStructure.NVIC_IRQChannel = TAMP_STAMP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* 禁止Tamper 1检测 */
RTC_TamperCmd(RTC_Tamper_1, DISABLE);
RTC_ClearFlag(RTC_FLAG_TAMP1F);
RTC_TamperTriggerConfig(RTC_Tamper_1, RTC_TamperTrigger_FallingEdge);
RTC_ITConfig(RTC_IT_TAMP, ENABLE);
RTC_ClearITPendingBit(RTC_IT_TAMP1);
/* 使能 Tamper 1 detection */
RTC_TamperCmd(RTC_Tamper_1, ENABLE);
}
复制代码
四个RTX任务的实现:
/*
*********************************************************************************************************
* 函 数 名: AppTaskUserIF
* 功能说明: 按键消息处理
* 形 参: 无
* 返 回 值: 无
* 优 先 级: 1 (数值越小优先级越低,这个跟uCOS相反)
*********************************************************************************************************
*/
__task void AppTaskUserIF(void)
{
uint8_t ucKeyCode;
while(1)
{
ucKeyCode = bsp_GetKey();
if (ucKeyCode != KEY_NONE)
{
switch (ucKeyCode)
{
/* K1键按下,打印调试说明 */
case KEY_DOWN_K1:
printf("K1键按下,使用MDK中自带的RTX调试组件,请务必使用MDK4.74版本进行调试\r\n");
break;
/* K2键按下,直接发送信号量同步信号给任务AppTaskMsgPro,K2按键还有一个功能就是将系统从
待机模式唤醒*/
case KEY_DOWN_K2:
printf("K2键按下,直接发送信号量同步信号给任务AppTaskMsgPro\r\n");
os_sem_send (&semaphore);
break;
/* K3键按下 进入到待机模式 */
case KEY_DOWN_K3:
printf("K3按键按下,系统进入待机模式,按K2按键将唤醒\r\n");
PWR_EnterSTANDBYMode();
break;
/* 其他的键值不处理 */
default:
break;
}
}
os_dly_wait(20);
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskLED
* 功能说明: LED闪烁。
* 形 参: 无
* 返 回 值: 无
* 优 先 级: 2
*********************************************************************************************************
*/
__task void AppTaskLED(void)
{
const uint16_t usFrequency = 200; /* 延迟周期 */
/* 设置延迟周期 */
os_itv_set(usFrequency);
while(1)
{
bsp_LedToggle(2);
bsp_LedToggle(3);
/* os_itv_wait是绝对延迟,os_dly_wait是相对延迟。*/
os_itv_wait();
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskMsgPro
* 功能说明: 消息处理,等待任务AppTaskUserIF发来的信号量同步信号
* 形 参: 无
* 返 回 值: 无
* 优 先 级: 3
*********************************************************************************************************
*/
__task void AppTaskMsgPro(void)
{
OS_RESULT xResult;
const uint16_t usMaxBlockTime = 200; /* 延迟周期 */
while(1)
{
xResult = os_sem_wait (&semaphore, usMaxBlockTime);
switch (xResult)
{
/* 无需等待接受到信号量同步信号 */
case OS_R_OK:
printf("无需等待接受到信号量同步信号\r\n");
break;
/* 信号量不可用,usMaxBlockTime等待时间内收到信号量同步信号 */
case OS_R_SEM:
printf("信号量不可用,usMaxBlockTime等待时间内收到信号量同步信号\r\n");
break;
/* 超时 */
case OS_R_TMO:
bsp_LedToggle(1);
bsp_LedToggle(4);
break;
/* 其他值不处理 */
default:
break;
}
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskStart
* 功能说明: 启动任务,也就是最高优先级任务。这里实现按键扫描。
* 形 参: 无
* 返 回 值: 无
* 优 先 级: 4
*********************************************************************************************************
*/
__task void AppTaskStart(void)
{
/* 创建任务 */
AppTaskCreate();
/* 创建任务通信机制 */
AppObjCreate();
while(1)
{
/* 按键扫描 */
bsp_KeyScan();
os_dly_wait(10);
}
}
复制代码
赞
评论
回复
支持
反对
baiyongbin2009
回答时间:2016-2-16 15:44:39
a0a.1 32b0c
23.4 总结
本章节主要为大家讲解了RTX低功耗之待机模式,这里仅是提供了一种停机模式在RTX上的实现思路,有兴趣的同学也可以想一些其它的实现思路。
赞
评论
回复
支持
反对
yanhaijian
回答时间:2016-2-16 16:41:59
a0a.1 32b0c
好东西,还是去安富莱官网下载PDF版本的。
赞
评论
回复
支持
反对
所属标签
关于
意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号
手机版
快速回复
返回顶部
返回列表
23.2.1 STM32F407如何进入待机模式
23.2.2 STM32F407如何退出待机模式
23.2.3 STM32F407使用待机模式注意事项
23.3.1 STM32F103开发板实验