power down mode也就是sleep mode,状态位PD被清零;程序中加入sleep()便可以使IC进入sleep mode。
在sleep mode下,若watchdog使能,则watchdog被清除后,继续工作;oscillator停止工作;IO口保持进入sleep mode时的状态;MCLR 许要设置为逻辑高电平。
从sleep mode醒来的几种方式:
1、外部MCLR的reset;
2、若watchdog使能,可以利用watchdog唤醒,TO bit被清;
3、INT唤醒,portB口有外部中断的功能;
另外在datasheet中也讲解到利用外部中断(如下几种可以唤醒device)
从sleep mode唤醒后,如果GIE=0被清除,device执行sleep后的一条语句;如果GIE=1使能,唤醒后执行sleep后的一条句子后,进入中断地址0x0004H 处执行中断内容。通常在sleep后增加一条NOP()指令。
另外在datasheet中提到在执行sleep指令前、过程中、以及之后如有中断,也可能不能使PD设置为0,使device进入sleep mode。所以最好在执行sleep mode前对PD位进行一下检查。
下面的例程实现的功能是:正常工作时blink LED(RA0控制),外部中断控制是否进入sleep mode,进入sleep mode时,LED保持亮的状态。再次RB0 外部中断触发后,awake up device,LED灯继续闪烁。
#include
#define uchar unsigned char
#define uint unsigned int
// CONFIG
#pragma config FOSC = HS // 12MHZ 外部晶振
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = ON // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
#define DELAY 1000
uchar count;
void delay(uint x)
{
uint y,z;
for(y=x;y>0;y--)
for(z=25;z>0;z--);
}
void init(void)
{
TRISB0=0;
RB0=1;
TRISB0=1;
INTEDG=0;
INTF=0;
INTE=1;
GIE=1;
}
void interrupt INT()
{
if(INTE&&INTF)
{
INTF=0;
count++;
TRISB0=0;
RB0=1;
TRISB0=1;
}
}
void main(void)
{
uchar i,temp;
TRISA=0x00;
PORTA=0x00;
init();
while(1)
{
RA0 =1;
delay(DELAY);
RA0 = 0;
delay(DELAY);
if((count%2)== 1)
{
RA0=1;
SLEEP(); // go into sleep mode
NOP();
}
}
}
下面的内容是从网上找的··
/SLEEP工作方式,单片机进入休眠,可以节省电源,提高A/D转换精度(此时AD转换必须选择内部RC作为A/D转换的时钟源)
//SLEEP工作方式相爱,芯片的振荡器停诊,因此没有系统时钟。在刚进入休眠工作模式下,如看门狗定时器是能状态,系统会自动把看门狗定时器的当前计数值清零
//使其重新计数,在SLEEP模式下,I/O端口保持执行SLEEP指令之前的状态。
//INTCON.GIE=1时,唤醒SLEEP计数之后,先执行SLEEP之后的一条语句,然后进入中断服务程序若不希望执行SLEEP之后的那条语句,可加上NOP指令
//INTCON.GIN=0,则唤醒SLEEP,但不进入中断。
//INTCON.INTE=0,则不管GIE为何值,按键时都不能唤醒SLEEP
//INT中断与休眠
#include
__CONFIG(0X3F39);//调试用
void DELAY_I(unsigned int);
void interrupt INT_ISR(void);
#define LED1 RB1
#define LED2 RB2
void main(void)
{
OPTION=0b1001101;//RB0/INT下降沿中断
TRISB=0b11111001;//设置RB0/RB1为输出
LED1=0;
LED2=0;
INTE=1;//中断控制寄存器INTCON的位4INTE(INT引脚中断使能)
GIE=1;//位7全局中断使能
SLEEP();//进入休眠工作方式
NOP();//SLEEP之后要加上NOP语句
LED1=1;//唤醒后LED1亮
while(1); //等待中断
}
void interrupt INT_ISR(void)
{
char x;
if(INTF)
{
LED2=1;
DELAY_I(30);
INTF=0;
}
}
void DELAY_I(unsigned int n)
{
unsigned int j;
char k;
for(j=0;j
for(k=246;k>0;k--) NOP();
}