STM8S之电源功耗管理之停机模式(halt)实现

详见博客:http://blog.csdn.net/freeape/article/details/47008805

官方资料

  可以去网络搜索中文版,或者到官方网站上去下载英文版。
  英文:

英文

  译文:

译文

主要内容简介

  • 影响功耗的主要因素
  • 电源系统
  • 时钟管理
  • 运行模式和低功耗模式
    • 运行模式
    • 等待模式
    • 活跃停机模式
    • 停机模式
  • 功耗与唤醒事件的测量与结果
  • 功耗管理要点

要点摘要

四种模式

  停机模式(Halt):此模式下单片机的功耗最低,振荡器,CPU和外设的时钟都被关闭,主电压调压器断电。可用复位或外部中断唤醒,唤醒后之前运行的寄存器数据等都保持不变,且从HALT处继续执行程序。

停机模式下的功耗测量结果(MVR关LPVR开):

停机模式下的功耗测量结果

运行模式下的功耗测量结果(从RAM运行,不是从Flash开始):

运行模式下的功耗测量结果

停机模式下的唤醒时间测量结果:

停机模式下的唤醒时间测量结果

测试程序

main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
Function: 电源管理:停机(Halt)模式测试,没有进入停机模式前,四个LED
灯是每隔1秒钟亮灭一次的,超过10秒后,自动进入停机mode,
然后可以通过外部中断来唤醒停机,此时程序从停机位置
处继续往下运行。
Date : 2015年7月21日
Note : STVD + COSMIC
Author : yicm
Version : 0.0.9
*/

#include<stm8s003f3p.h>


/*Output Pin*/
_Bool PA3 @PA_ODR:3;
_Bool PC4 @PC_ODR:4;
_Bool PC5 @PC_ODR:5;
_Bool PC6 @PC_ODR:6;
_Bool PC7 @PC_ODR:7;
/*Input Pin*/
_Bool PC3 @PC_IDR:3;

/*电量指示灯*/
#define LED1 PA3
#define LED2 PC5
#define LED3 PC6
#define LED4 PC7
/*按键指示灯*/
#define LED5 PC4
#define KEY PC3

/*主时钟频率为8Mhz*/
void Init_CLK(void)
{

CLK_ICKR |= 0X01;
CLK_CKDIVR = 0x08;
while(!(CLK_ICKR&0x02));
CLK_SWR=0xE1;
}

void Init_GPIO(void)
{

/*LED 配置为推挽输出*/
PA_DDR |= 0X08; //PA3
PA_CR1 |= 0X08;
PA_CR2 &= 0XF7;
/*PC4 -KEY LED*/
PC_DDR |= 0X10;
PC_CR1 |= 0X10;
PC_CR2 &= 0XEF;

PC_DDR |= 0XE0; //PC5/6/7
PC_CR1 |= 0XE0;
PC_CR2 &= 0X1F;

LED1 = 1;LED2 = 1;LED3 = 1;LED4 = 1;LED5 = 1;
}

void Init_TIM1(void)
{

TIM1_IER = 0x00;
TIM1_CR1 = 0x00;

TIM1_EGR |= 0x01;
TIM1_PSCRH = 199/256; // 8M系统时钟经预分频f=fck/(PSCR+1) TIM1 为16位分频器
TIM1_PSCRL = 199%256; // PSCR=0x1F3F,f=8M/(0x1F3F+1)=1000Hz,每个计数周期1ms

TIM1_CNTRH = 0x00;
TIM1_CNTRL = 0x00;

TIM1_ARRH = 400/256; // 自动重载寄存器ARR=0x01F4=500
TIM1_ARRL = 400%256; // 每记数500次产生一次中断,即500ms

TIM1_CR1 |= 0x81;
TIM1_IER |= 0x01;
}

/*PC3设置为上拉输入*/
void Init_EXTI2_GPIO(void)
{

PC_DDR &= 0XF7;
PC_CR1 &= 0XF7;
PC_CR2 |= 0X08;
}

/*上升沿和下降沿促发*/
void Init_EXTI2(void)
{

EXTI_CR1 |= 0x30;
}

main()
{
_asm("sim");
Init_CLK();
Init_GPIO();
Init_EXTI2_GPIO();
Init_EXTI2();
Init_TIM1();
_asm("rim");
while (1);
}

/*外部中断唤醒*/
@far @interrupt void EXTI2_Hand_Fun(void)
{


}

/*定时器中断函数*/
@far @interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void)
{

static unsigned int i = 0;
TIM1_SR1 &=~(0x01);

++i;
if(0 == (i%50))
{
LED1 = ~LED1;
LED2 = ~LED2;
LED3 = ~LED3;
LED4 = ~LED4;
}
if(i > 1000)
{
_asm("halt");
i = 0;
LED5 = ~LED5;
}
}
stm8_interrupt_vector.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*	BASIC INTERRUPT VECTOR TABLE FOR STM8 devices
* Copyright (c) 2007 STMicroelectronics
*/


typedef void @far (*interrupt_handler_t)(void);

struct interrupt_vector {
unsigned char interrupt_instruction;
interrupt_handler_t interrupt_handler;
};

@far @interrupt void NonHandledInterrupt (void)
{

/* in order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction
*/

return;
}

extern void _stext(); /* startup routine */
extern @far @interrupt void EXTI2_Hand_Fun(void);
extern @far @interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void);

struct interrupt_vector const _vectab[] = {
{0x82, (interrupt_handler_t)_stext}, /* reset */
{0x82, NonHandledInterrupt}, /* trap */
{0x82, NonHandledInterrupt}, /* irq0 */
{0x82, NonHandledInterrupt}, /* irq1 */
{0x82, NonHandledInterrupt}, /* irq2 */
{0x82, NonHandledInterrupt}, /* irq3 */
{0x82, NonHandledInterrupt}, /* irq4 */
{0x82, EXTI2_Hand_Fun}, /* irq5 */
{0x82, NonHandledInterrupt}, /* irq6 */
{0x82, NonHandledInterrupt}, /* irq7 */
{0x82, NonHandledInterrupt}, /* irq8 */
{0x82, NonHandledInterrupt}, /* irq9 */
{0x82, NonHandledInterrupt}, /* irq10 */
{0x82, TIM1_UPD_OVF_TRG_BRK_IRQHandler}, /* irq11 */
{0x82, NonHandledInterrupt}, /* irq12 */
{0x82, NonHandledInterrupt}, /* irq13 */
{0x82, NonHandledInterrupt}, /* irq14 */
{0x82, NonHandledInterrupt}, /* irq15 */
{0x82, NonHandledInterrupt}, /* irq16 */
{0x82, NonHandledInterrupt}, /* irq17 */
{0x82, NonHandledInterrupt}, /* irq18 */
{0x82, NonHandledInterrupt}, /* irq19 */
{0x82, NonHandledInterrupt}, /* irq20 */
{0x82, NonHandledInterrupt}, /* irq21 */
{0x82, NonHandledInterrupt}, /* irq22 */
{0x82, NonHandledInterrupt}, /* irq23 */
{0x82, NonHandledInterrupt}, /* irq24 */
{0x82, NonHandledInterrupt}, /* irq25 */
{0x82, NonHandledInterrupt}, /* irq26 */
{0x82, NonHandledInterrupt}, /* irq27 */
{0x82, NonHandledInterrupt}, /* irq28 */
{0x82, NonHandledInterrupt}, /* irq29 */
};