本篇博文最后修改时间:2016年12月14日,14:48。
一、简介
本文介绍STM8L系列如何实现:默认低功耗模式,用按键实现唤醒并发射红外信号,随即又进入低功耗模式 。
二、实验平台
编译软件:IAR for STM8 1.42.2
硬件平台:stm8l101f3p6开发板
仿真器:ST-LINK
库函数版本:STM8L_STMTouch_Lib_V1.1.0
三、版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn.NET/feilusia
联系方式:[email protected]
香瓜BLE之CC2541群:127442605
香瓜BLE之CC2640群:557278427
香瓜BLE之Android群:541462902
四、基础知识
1、STM8L有几个模式?
答:
1)非低功耗模式(1个)
Run mode(运行模式)
2)低功耗模式(3个)
Wait(等待模式)、Active-halt(活跃停机模式)、Halt(停机模式)。
2、STM8L低功耗的3个模式有什么区别?
答:
简单地来说,就是:
1)wait(等待模式):时钟关闭、外设可用。通过中断、外部中断、复位,能退出本模式。
2)Active-halt(活跃停机模式):时钟关闭、外设关闭、RTC开启。通过RTC中断、外部中断、复位,能退出本模式。
3)Halt(停机模式)(功耗最低):时钟关闭、外设关闭。通过外部中断、复位,能退出本模式。
另外,上图同时说明了默认上电时是运行模式,在运行模式时可通过如下方法降低功耗:
1)降低时钟频率。
2)关闭没用的外设时钟。
3)(香瓜补充)无用的IO口配置为输出低。
3、进入低功耗模式与低功耗唤醒的流程是如何的?
答:
1)进入低功耗模式的流程
①关闭外设时钟。
②所有IO设置为输出低(注意低电平使能的得设置为输出高)。
③初始化中断口的IO。
④时钟频率降至最低(2M)。
⑤打开中断总开关。
⑥调用停机模式的函数。
2)低功耗唤醒的流程
①初始化系统时钟。
②初始化用到的外设。
五、实验前提
在进行本文步骤前,请先阅读并实现以下博文:
1、《STM8L之红外发射(PWM产生38K信号)》:http://blog.csdn.net/feilusia/article/details/53417291
2、《STM8L之定时器3的精确延时》:http://blog.csdn.net/feilusia/article/details/53407818
六、实验步骤
1、工程中添加自己写的低功耗的驱动
1)写一个驱动GUA_LowPowerConsumption.c(存放在工程的USER文件夹中)
//******************************************************************************
//name: GUA_LowPowerConsumption.c
//introduce: 低功耗驱动
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
#include "stm8l10x.h"
#include "GUA_LowPowerConsumption.h"
#include "GUA_Key.h"
#include "GUA_Key_2.h"
#include "GUA_Timer2_PWM.h"
#include "GUA_Timer3.h"
#include "GUA_Clk.h"
/*********************宏定义************************/
#ifndef U8
typedef unsigned char U8;
#endif
#ifndef U16
typedef unsigned short U16;
#endif
#ifndef U32
typedef unsigned long U32;
#endif
/*********************内部变量************************/
static u8 sGUA_LowPowerConsumption_State = GUA_LOW_POWER_CONSUMPTION_STATE_HALT;
/*********************内部函数声明************************/
static void GUA_LowPowerConsumption_Halt_Peripheral(void);
static void GUA_LowPowerConsumption_Halt_GPIO_Default(void);
static void GUA_LowPowerConsumption_Halt_GPIO_Interrupt(void);
static void GUA_LowPowerConsumption_Halt_InterruptSwitchOn(void);
static void GUA_LowPowerConsumption_Halt_Enable(void);
static void GUA_LowPowerConsumption_Active_Clk(void);
static void GUA_LowPowerConsumption_Active_Peripheral(void);
//******************************************************************************
//name: GUA_LowPowerConsumption_Halt_PeripheralCLK
//introduce: 关闭外设时钟
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
static void GUA_LowPowerConsumption_Halt_Peripheral(void)
{
//时钟失能
CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_TIM3, DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_TIM4, DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_I2C, DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_SPI, DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_USART, DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_AWU, DISABLE);
}
//******************************************************************************
//name: GUA_LowPowerConsumption_Halt_GPIO_Default
//introduce: 所有IO口设置为输出低(注意低电平使能的得设置为输出高)
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
static void GUA_LowPowerConsumption_Halt_GPIO_Default(void)
{
//IO配置为输出
GPIO_Init(GPIOA, GPIO_Pin_2 | GPIO_Pin_3, GPIO_Mode_Out_PP_High_Fast);
GPIO_Init(GPIOB, GPIO_Pin_0 | GPIO_Pin_1 |GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 |GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7, GPIO_Mode_Out_PP_High_Fast);
GPIO_Init(GPIOC, GPIO_Pin_0 | GPIO_Pin_1 |GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4, GPIO_Mode_Out_PP_High_Fast);
//IO配置为输出低(注意低电平使能的得设置为输出高)
GPIO_WriteBit(GPIOA, GPIO_Pin_2 | GPIO_Pin_3, RESET);
GPIO_WriteBit(GPIOB, GPIO_Pin_0 | GPIO_Pin_1 |GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 |GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7, RESET);
GPIO_WriteBit(GPIOC, GPIO_Pin_0 | GPIO_Pin_1 |GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4, RESET);
}
//******************************************************************************
//name: GUA_LowPowerConsumption_Halt_GPIO_Interrupt
//introduce: 初始化中断口的IO
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
static void GUA_LowPowerConsumption_Halt_GPIO_Interrupt(void)
{
//按键初始化
GUA_Key_Init();
//按键2初始化
GUA_Key_2_Init();
}
//******************************************************************************
//name: GUA_LowPowerConsumption_Halt_Clk
//introduce: 时钟配置为2M
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
static void GUA_LowPowerConsumption_Halt_Clk(void)
{
//寄存器重置
CLK_DeInit();
//时钟8分频,2MHz
CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv8);
}
//******************************************************************************
//name: GUA_LowPowerConsumption_Halt_InterruptSwitchOn
//introduce: 打开中断总开关
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
static void GUA_LowPowerConsumption_Halt_InterruptSwitchOn(void)
{
//开全局中断
asm("rim");
}
//******************************************************************************
//name: GUA_LowPowerConsumption_Halt_Enable
//introduce: 进入停机模式
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
static void GUA_LowPowerConsumption_Halt_Enable(void)
{
//进入停机模式
halt();
}
//******************************************************************************
//name: GUA_LowPowerConsumption_Active_Clk
//introduce: 初始化时钟
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
static void GUA_LowPowerConsumption_Active_Clk(void)
{
//晶振初始化
GUA_CLK_Init();
}
//******************************************************************************
//name: GUA_LowPowerConsumption_Active_Peripheral
//introduce: 初始化外设
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
static void GUA_LowPowerConsumption_Active_Peripheral(void)
{
//定时器2的PWM初始化
GUA_Timer2_PWM_Init();
//定时器3的初始化
GUA_Timer3_Init();
}
//******************************************************************************
//name: GUA_LowPowerConsumption_Get
//introduce: 低功耗读取状态函数
//parameter: none
//return: GUA_LOW_POWER_CONSUMPTION_STATE_ENABLE or GUA_LOW_POWER_CONSUMPTION_STATE_DISABLE
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
U8 GUA_LowPowerConsumption_Get(void)
{
return sGUA_LowPowerConsumption_State;
}
//******************************************************************************
//name: GUA_LowPowerConsumption_Set
//introduce: 低功耗设置状态函数
//parameter: nGUA_LowPowerConsumption_State: GUA_LOW_POWER_CONSUMPTION_STATE_ENABLE or GUA_LOW_POWER_CONSUMPTION_STATE_DISABLE
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
void GUA_LowPowerConsumption_Set(U8 nGUA_LowPowerConsumption_State)
{
sGUA_LowPowerConsumption_State = nGUA_LowPowerConsumption_State;
}
//******************************************************************************
//name: GUA_LowPowerConsumption_Cmd
//introduce: 低功耗控制函数
//parameter: nGUA_LowPowerConsumption_State: GUA_LOW_POWER_CONSUMPTION_STATE_ENABLE or GUA_LOW_POWER_CONSUMPTION_STATE_DISABLE
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
void GUA_LowPowerConsumption_Cmd(U8 nGUA_LowPowerConsumption_State)
{
//开启低功耗
if(nGUA_LowPowerConsumption_State == GUA_LOW_POWER_CONSUMPTION_STATE_HALT)
{
//关闭外设时钟
GUA_LowPowerConsumption_Halt_Peripheral();
//所有IO口设置为输出低(注意低电平使能的得设置为输出高)
GUA_LowPowerConsumption_Halt_GPIO_Default();
//初始化中断口的IO
GUA_LowPowerConsumption_Halt_GPIO_Interrupt();
//时钟配置为2M
GUA_LowPowerConsumption_Halt_Clk();
//打开中断总开关
GUA_LowPowerConsumption_Halt_InterruptSwitchOn();
//置位标志位
GUA_LowPowerConsumption_Set(GUA_LOW_POWER_CONSUMPTION_STATE_HALT);
//进入停机模式
GUA_LowPowerConsumption_Halt_Enable();
/*******************************************************************/
//初始化时钟
GUA_LowPowerConsumption_Active_Clk();
//初始化外设
GUA_LowPowerConsumption_Active_Peripheral();
//置位标志位
GUA_LowPowerConsumption_Set(GUA_LOW_POWER_CONSUMPTION_STATE_ACTIVE);
}
//关闭低功耗
else
{
}
}
//******************************************************************************
//name: GUA_LowPowerConsumption.h
//introduce: 低功耗驱动的头文件
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
#ifndef _GUA_LOW_POWER_CONSUMPTION_H_
#define _GUA_LOW_POWER_CONSUMPTION_H_
/*********************宏定义************************/
//低功耗控制宏
#define GUA_LOW_POWER_CONSUMPTION_STATE_HALT 0
#define GUA_LOW_POWER_CONSUMPTION_STATE_ACTIVE 1
/*********************外部函数声明************************/
unsigned char GUA_LowPowerConsumption_Get(void);
void GUA_LowPowerConsumption_Set(unsigned char nGUA_LowPowerConsumption_State);
void GUA_LowPowerConsumption_Cmd(unsigned char nGUA_LowPowerConsumption_State);
#endif
4)添加驱动的路径
$PROJ_DIR$\..\USER
注意USER文件夹是与“Project”等文件夹同级的自定义文件,用于存放香瓜写的代码。
2、应用层中调用
1)main.c
//******************************************************************************
//name: main.c
//introduce: 主函数
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
#include "stm8l10x.h"
#include "main.h"
#include "GUA_Key.h"
#include "GUA_Key_2.h"
#include "GUA_Timer2_PWM.h"
#include "GUA_Infrared_Send.h"
#include "GUA_Timer3.h"
#include "GUA_Clk.h"
#include "GUA_LowPowerConsumption.h"
/*********************宏定义************************/
#ifndef U8
typedef unsigned char U8;
#endif
#ifndef U16
typedef unsigned short U16;
#endif
#ifndef U32
typedef unsigned long U32;
#endif
#ifndef int32
typedef signed long int32;
#endif
/*********************外部变量************************/
U8 gGUA_Function = 0; //功能码
/*********************内部函数声明************************/
static void GUA_Init(void);
//******************************************************************************
//name: GUA_TEST
//introduce: 测试
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
static void GUA_TEST(void)
{
}
//******************************************************************************
//name: GUA_Init
//introduce: 初始化
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
static void GUA_Init(void)
{
//关全局中断
asm("sim");
//晶振初始化
GUA_CLK_Init();
//按键初始化
GUA_Key_Init();
//按键2初始化
GUA_Key_2_Init();
//定时器2的PWM初始化
GUA_Timer2_PWM_Init();
//定时器3的初始化
GUA_Timer3_Init();
//开全局中断
asm("rim");
}
//******************************************************************************
//name: main
//introduce: 主函数
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
void main(void)
{
//初始化
//GUA_Init();
//测试
//GUA_TEST();
while(1)
{
switch(gGUA_Function)
{
//空闲
case FUNC_IDLE_EVENT:
{
//低功耗模式
if(GUA_LowPowerConsumption_Get() == GUA_LOW_POWER_CONSUMPTION_STATE_HALT)
{
GUA_LowPowerConsumption_Cmd(GUA_LOW_POWER_CONSUMPTION_STATE_HALT);
}
//正常模式
else
{
GUA_LowPowerConsumption_Cmd(GUA_LOW_POWER_CONSUMPTION_STATE_ACTIVE);
}
break;
}
//短按键处理
case FUNC_GUA_KEY_SHORT_EVENT:
{
//发送红外键值
GUA_Infrared_Send(0x00FF00FF);
//置位低功耗标志位
GUA_LowPowerConsumption_Set(GUA_LOW_POWER_CONSUMPTION_STATE_HALT);
//返回空闲状态
gGUA_Function = FUNC_IDLE_EVENT;
break;
}
//短按键2处理
case FUNC_GUA_KEY2_SHORT_EVENT:
{
//发送红外键值
GUA_Infrared_Send(0x00FF02FD);
//置位低功耗标志位
GUA_LowPowerConsumption_Set(GUA_LOW_POWER_CONSUMPTION_STATE_HALT);
//返回空闲状态
gGUA_Function = FUNC_IDLE_EVENT;
break;
}
//其他
default:
{
//返回空闲状态
gGUA_Function = FUNC_IDLE_EVENT;
break;
}
}
}
}
//******************************************************************************
//name: main.h
//introduce: 主函数的头文件
//author: 甜甜的大香瓜
//email: [email protected]
//QQ group 香瓜单片机之STM8/STM32(164311667)
//changetime: 2016.12.06
//******************************************************************************
#ifndef _MAIN_H_
#define _MAIN_H_
/*********************宏定义************************/
//主轮询的宏
#define FUNC_IDLE_EVENT 0x00 //空闲
#define FUNC_GUA_KEY_SHORT_EVENT 0x10 //短按键处理事件
#define FUNC_GUA_KEY_LONG_EVENT 0x11 //长按键处理事件
#define FUNC_GUA_KEY2_SHORT_EVENT 0x12 //短按键2处理事件
#define FUNC_GUA_KEY2_LONG_EVENT 0x13 //长按键2处理事件
/*********************外部变量************************/
extern u8 gGUA_Function; //功能码
#endif
七、实验结果
将万用表的电流档串入VCC的跳线中,待机时为1uA~2uA之间跳变。
当按下按键发射红外时,电流值瞬间为1mA~2mA,随后又降低至待机状态。
对比datasheet的数据:“Halt: 0.3 µA、Active-halt: 0.8 µA、Dynamic Run:150 µA/MHz”。
比文档上的略高些,但已实现基本的低功耗。
因此,实验成功。
后续:有群友反馈增加“PWR_UltraLowPowerCmd(ENABLE);”可进一步降低功耗至0.3uA,待香瓜实测,先mark。