介绍
本文介绍如何在使用MC9S08QG8 单片机时达到低功耗。MC9S08QG8 属于低成本、高性能的HCS08 8 位新型单片机系列。MC9S08QG8 单片机增加了一些特别适合实现低功耗的功能。这些功能为用户提供了极大的灵活性,能为各种不同应用提供理想的运行状态。
系统时钟生成
系统时钟可以由外部(晶振、谐振器及方波)或内部时钟源生成。而且,可以用锁频环(FLL)将外部或内部时钟源提升到一个更高的频率。MC9S08QG8 可以使用低频(31.25 kHz–38.4 kHz)或高频(1 MHz–16 MHz)晶振以及谐振器。当系统启动时(从停止状态启动或复位),单片机会采用内部时钟源,从而缩短系统启动时间。根据应用的要求选择最佳的系统时钟生成方式,可以降低功耗。
怎样根据自己的需要选择停止模式
l 如果功耗最为重要,而且又不需要单片机自唤醒,停止
1 是最合适的情形。只有复位或
IRQ 的下降沿才能从该模式中唤醒单片机。
l 如果要求有最低的功耗,同时又能保持
RAM 内容和
I/O 状态,则停止
2 是最适合的。由于实时中断模块能在停止
2 中运行,所以单片机不需要外部输入也可以唤醒。
l 如果用户需要能够轻松退出的停止模式,可以采用停止3。
怎样进入停止模式
要进入
3 种停止模式的任何一种,都必须正确配置两个寄存器的三个位。在系统选项寄存器(
SOPT) 中,停止模式允许位(
STOPE)必须设置为
1。该寄存器在复位后只能写入一次,因此必须注意在同一次写入中配置其它选项。如果
STOPE 位清零,又开始执行
STOP(停止)指令,这时
STOP 指令将被当作非法操作码,单片机会强制复位。在系统电源管理状态和控制寄存器
2(
SPMSC2)中的两个位
, 断电控制位(
PDC)和部分断电控制位(
PPDC),决定执行
STOP(停止)指令时,进入
3 种停止模式中的哪种模式。此外,为了能够进入停止
2 或停止
1 模式,
SPMSC1 的
LVDSE 位必须清零。如果这一位没有清零,那么唯一能够进入的停止模式只能是停止
3。表
3-1 说明了影响停止状态选择和不同情况下状态选择的所有位
. 执行了一条
STOP指令之后进入选择了的状态
.停止1
当
PDC 位设置为逻辑
1,
PPDC 位设置为逻辑
0 时,执行
STOP(停止)指令后进入停止
1。停止
1 模式通过关闭内部稳压器及由其供电的所有片上外围设备,得到最小的电流消耗。同时,
I/O 管脚和所有内存也都关闭。由于单片机的绝大部分在停止
1 期间都会断电,进入停止
1 只需要最少的软件处理。主要的考虑是在
SOPT 寄存器中允许
STOP 指令,以及通过
SPMSC2 寄存器的
PDC 位选择停止
1。此时不需要配置各个外围设备,因为进入停止
1 后它们都会自动断电。既然
I/Q 管脚处于复位状态,那么所有
I/O 管脚都将回复为默认的输入状态并断开内部上拉。如果在停止模式中开启外部振荡器(
ICG 控制寄存器
1 的
OSCSTEN 位),那么进入停止
1 后,该位的值将被忽略,时钟电源将被关闭。 如果在停止模式中启用
LVD 模块,停止
1 就不能采用。
LVD 开启后,进入停止
1,会导致单片机进入停止
3 模式。复位和
IRQ 管脚将自动配置为停止
1 的唤醒管脚。不需要软件或外部上拉。从停止
1 唤醒后,单片机的启动与上电复位类似。由于所有寄存器回复为上电复位状态,并且
RAM 的电源也曾关断,所以没有能指示单片机是从停止
1 模式唤醒的机制。
由于上电复位会令内部4-MHz 时钟驱动系统总线时钟,因此“停止恢复”过程相当快,从而在进入正常程序流之前,能快速执行代码以完成寄存器恢复。最长延迟是内部稳压器从关闭到开启,然后稳定所需的时间。
停止2
当PDC 位和PPDC 位都设置为逻辑1 时,执行STOP(停止)指令会进入停止2。停止2 的电流消耗高于停止1,但低于停止3。RAM 继续保持供电,保持它的值和I/O 管脚都锁存当前的状态。
l 采用停止
2 模式时,需注意以下几点以确保正常操作:
l 必须打开
IRQ 脚或将其外部上拉。
l 停止时
LVD 必须关闭(
LVDSE = 0)。
l 如果在停止
2 中采用实时中断,只有内部时钟源工作。
l OSCSTEN 位在停止
2 中没有作用。此时钟源总是电源关闭。
l 只有
RAM 保持供电,其它所有
I/O 寄存器唤醒后将复位。
l 从停止2 进入后,在改变I/O 管脚的状态前,必须保持PPDF 标志清零。
必须通过写入
IRQ 状态和控制寄存器中(
IRQSC)的中断管脚允许位(
IRQPE)来开启
IRQ 引脚。否则进入停止状态后,单片机会马上从停止
2 唤醒,除非
IRQ 管脚上有外部上拉。
IRQ 中断不需要启动(
IRQSC 的
IRQIE 位)。复位脚将自动配置为停止
2 的唤醒脚。不需要软件或外部上拉。如果在停止模式中启动了
LVD 模块,就不能采用停止
2。在停止模式中启用了
LVD 后再进入停止
2, 单片机会进入停止
3 模式。在停止
2 中采用实时中断模块作为一个唤醒源时,必须使用内部时钟源,因为在停止
2 中外部时钟源不能保持供电。如果在停止模式中开启外部振荡器(
ICG 控制寄存器
1 的
OSCSTEN 位),然后进入停止
2,那么该位将被忽略,时钟电源会被关闭。一般来说,应在
SOPT 寄存器中允许停止指令,并且
SPMSC2 寄存器的
PDC 和
PPDC 位必须设置为逻辑
1。未提及的外围设备不需要任何特殊处理,因为进入停止
2 后它们的电源会自动被关闭。
从停止2 唤醒后,单片机的启动过程类似POR(上电复位)发生后的情形。但是,与停止1 不同的是,SPMSC2 寄存器的PPDF 可以指示单片机是从停止2 而不是从标准POR 唤醒的。通过使用PPDF 和PPDACK 位,用户代码能够在进入停止2 前,将所有需要的寄存器值保存到RAM 中,然后在唤醒后恢复这些值。如果在PPDACK 写为逻辑1 前,端口寄存器已经保存和恢复,那么其I/O 状态将被保留。那些没有重新配置成停止2 锁存状态的端口管脚都将回复到复位状态。同样,没有重新配置成进入停止2 之前的状态的所有外围设备也将回复到复位状态。
停止3
停止
3模式不能提供最低的
IDD 电流,但它功能多,而且在所有停止模式中影响最小。只要
SPMSC2 的
PDC 位设置为
0,即可进入停止
3。此外还应注意,如果在停止模式下启动了
LVD,或进入背景调试模式时也启动了
LVD(
BDCSCR 中的
ENBDM 位已经设定为
1),则此时唯一能够进入的停止模式是停止
3。当
ENBDM 位设置为
1 后执行停止指令,背景调试逻辑的系统时钟仍然有效,因此仍能继续背景调试通信。如果用户需要能够轻松退出的停止模式,可以采用停止
3。停止
3 有一个优点,在通过中断从停止
3 中恢复时,能保留
DCO 的原有设置。就是说在停止恢复时,
DCO 将用先前定义好的系统时钟配置进行设置。与其它停止模式不同的是,如果停止
3 通过中断退出,是不需要进行任何初始化或重新配置的。中断发生后,
CPU 开始处理堆栈操作,引导其进入中断服务程序。执行中断返回(
RTI)指令后,
CPU 会回复到紧跟在
STOP(停止)指令后的那一条指令处。另一个可能需要采用停止
3 模式的情况是必须使用键盘中断(
KBI)模块的时候。
MC9S08QG8 有
8 个键盘中断脚-每一个管脚都能从停止
3 中唤醒芯片。键盘中断模块不能在停止
1 或停止
2 中使用,但是在某些应用中,必须有多种退出停止模式的信号
表3-2为进入三种模式后,外围设备的状态特性。
下面是各种低功耗模式的功能总结:
l 停止1 是完全断电模式,所有RAM 和寄存器内容会丢失,通过IRQ 或复位可退出停止1;退出需要外部事件
l 停止2 是部分断电模式,保持RAM 内容、I/O 状态锁定通过IRQ、复位或内部自动唤醒定时器退出需要对要用 的各外围设备进行初始化
l 停止3 与M68HC08 单片机的停止模式相当,通过IRQ、键盘中断、低电压检测、内部自动唤醒定时器或复位退出允许时钟发生器运行,但不提供给外围设备,因此可以使用外部参考时钟不需要初始化外围设备
l 等待模式关闭CPU 的时钟,但可以提供给外围设备,通常用于等候中断时,如SCI 接收中断立即处理中断服务程序
下面是使用停止3模式的一段代码,唤醒方式为键盘中断唤醒,实验现象:单片机上电后,LED闪烁三次后进入停止模式,等待按键按下唤醒,LED在闪烁三次后继续进入停止模式!
#include /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
/*********************变量和函数定义****************************/
void delay(unsigned int x);
void KB_init(void);
/*********************主函数************************************/
void main(void) {
KB_init();
SOPT1_STOPE=1;//使能停止模式
SPMSC2_PDC=1; //使能掉电状态
EnableInterrupts; /* enable interrupts */
for(;;) {
__RESET_WATCHDOG(); /* feeds the dog */
PTAD_PTAD1= ~PTAD_PTAD1; //LED闪烁
delay(1000);
PTAD_PTAD1= ~PTAD_PTAD1;
delay(1000);
PTAD_PTAD1= ~PTAD_PTAD1;
delay(1000);
PTAD_PTAD1= ~PTAD_PTAD1;
delay(1000);
PTAD_PTAD1= ~PTAD_PTAD1;
delay(1000);
PTAD_PTAD1= ~PTAD_PTAD1;
delay(1000);
asm{
stop; //进入停止模式
}
}
/* please make sure that you never leave main */
}
/*******************延时函数************************************/
void delay(unsigned int x)
{
unsigned int i,j;
for(i=0;i { __RESET_WATCHDOG();
for(j=0;j<250;j++)
{;
}
}
}
/************************KB初始化********************************/
void KB_init(void){
KBIPE_KBIPE2 =1; //使能键盘管脚
KBISC_KBIE = 1; //使能键盘中断
//KBISC_KBMOD = 1;
PTAPE_PTAPE2 = 1; //使能键盘管脚上拉
KBISC_KBACK = 1; //清键盘中断标志
PTADD_PTADD0=0;
PTADD_PTADD1=1;
}
/********************************键盘中断**************************/
interrupt 18 void KBI_ISR(void) {
KBISC_KBACK = 1; //清除键盘中断标志
}