单片机
返回首页

单片机的电源选项

2017-01-09 来源:eefocus

单片机的空闲和掉电模式的应用

注意:电源管理寄存器PCON,它的最低两位IDL和PD分别用来设定是否单片机进入空闲模式和掉电模式

因此,单片机进入掉电模式只需要PCON= 0x01;进入空闲模式只需要PCON = 0x02;

空闲模式:

单片机进入空闲模式的时候,除了cpu处于休眠状态外,其余的硬件全部处于活动状态,芯片中未涉及的数据存储器和特殊功能寄存器中的数据在空闲模式期间都将保持原值

单片机在空闲模式下可由任何一个中断或者是硬件复位唤醒,值得注意的是,使用中断唤醒单片机,程序将从原来的停止的地方继续运行,当使用硬件复位时,程序将从头开始执行

 

掉电模式:

当单片机进入掉电模式(也叫休眠模式)外部晶振停止震动,cpu,定时器,串口全部停止工作,只有外部中断继续工作,使单片机进入掉电模式的指令将成为休眠前单片机工作的最后一条指令,值得注意的是,使用中断唤醒单片机,程序将从原来的停止的地方继续运行,当使用硬件复位时,程序将从头开始执行

示例代码:(此代码实现,在单片机上开启两个外部中断,设置为低电平触发,用定时器计数并且显示在数码管的前两位,当计数到5时,单片机进入空闲或者是休眠模式,当单片机响应外部中断时,从休眠模式(空闲模式)返回 ,并同时启动定时器

错误代码:


#include

#define uint unsigned int

#define uchar unsigned char 


sbit dula = P2^6;

sbit wela = P2^7;

uchar num ,gw,sw,aa;

uchar code table[]={0x3f,0x06,0x5b,0x4f,

                    0x66,0x6d,0x7d,0x07,

                    0x7f,0x6f,0x77,0x7c,

                    0x39,0x5e,0x79,0x71};


void init()//初始化函数

{

    TMOD = 0x01;

    TH0 = (65535-50000)/256;

    TL0 = (65535-50000)%256;


    EA = 1;

    ET0 = 1;

    

    EX0 = 1;//打开外部中断0

//    IT0 = 0;//电平触发方式

    

    EX1 = 1;//打开外部中断1 

//    IT1 = 0;

    TR0 = 1;



}


void delayms(uint x)//延时函数

{

    uint i,j;

    for(i = x;i>0;i--)

        for(j=110;j>0;j--);

}


void display(uchar gw,uchar sw)//显示函数

{

    dula = 1;

    P0 = table[sw];

    dula = 0;


    P0 = 0xff;

    wela = 1;

    P0 = 0xfe;

    wela = 0;

    delayms(5);


    P0 = 0x0;//消影

    dula = 1;

    P0 = table[gw];

    dula = 0;


    P0 = 0xff;

    wela = 1;

    P0 = 0xfd;

    wela = 0;

    delayms(5);


}


void main()

{

    init();

    while(1)

    {

        

        display(gw,sw);

    }

}


void timer0()interrupt 1

{

    TH0 = (65536-50000)/256;

    TL0 = (65536-50000)%256;

    aa ++;

    if(aa ==20)

        {

            aa =0;

            num++;

            if(num == 99)

                num =0;

            gw = num%10;

            sw = num/10;

            if(num == 6)

                {

                

                    ET0 = 0;//关闭定时器

                    PCON = 0x01;//单片机进入空闲模式

                }

        }


}


void ex_int0()interrupt 0

{

//    PCON = 0;//可要可不要

    ET0 =1;

}


void ex_int1()interrupt 2

{

//    PCON = 0;//可要可不要

    ET0 = 1;

}

正确代码:

#include

#define uint unsigned int

#define uchar unsigned char 


sbit dula = P2^6;

sbit wela = P2^7;

uchar num ,gw,sw,aa;

uchar code table[]={0x3f,0x06,0x5b,0x4f,

                    0x66,0x6d,0x7d,0x07,

                    0x7f,0x6f,0x77,0x7c,

                    0x39,0x5e,0x79,0x71};


void init()//初始化函数

{

    TMOD = 0x01;

    TH0 = (65535-50000)/256;

    TL0 = (65535-50000)%256;


    EA = 1;

    ET0 = 1;

    

    EX0 = 1;//打开外部中断0

//    IT0 = 0;//电平触发方式

    

    EX1 = 1;//打开外部中断1 

//    IT1 = 0;

    TR0 = 1;



}


void delayms(uint x)//延时函数

{

    uint i,j;

    for(i = x;i>0;i--)

        for(j=110;j>0;j--);

}


void display(uchar gw,uchar sw)//显示函数

{

    dula = 1;

    P0 = table[sw];

    dula = 0;


    P0 = 0xff;

    wela = 1;

    P0 = 0xfe;

    wela = 0;

    delayms(5);


    P0 = 0x0;//消影

    dula = 1;

    P0 = table[gw];

    dula = 0;


    P0 = 0xff;

    wela = 1;

    P0 = 0xfd;

    wela = 0;

    delayms(5);


}


void main()

{

    init();

    while(1)

    {

        if(aa ==20)

        {

            aa =0;

            num++;

            if(num == 99)

                num =0;

            gw = num%10;

            sw = num/10;

            if(num == 6)

                {

                

                    ET0 = 0;//关闭定时器

                    PCON = 0x01;//单片机进入空闲模式

                }

        }

        display(gw,sw);

    }

}


void timer0()interrupt 1

{

    TH0 = (65536-50000)/256;

    TL0 = (65536-50000)%256;

    aa ++;


}


void ex_int0()interrupt 0

{

//    PCON = 0;//可要可不要

    ET0 =1;

}


void ex_int1()interrupt 2

{

//    PCON = 0;//可要可不要

    ET0 = 1;

}

错误代码中,把

if(aa ==20)

        {

            aa =0;

            num++;

            if(num == 99)

                num =0;

            gw = num%10;

            sw = num/10;

            if(num == 6)

                {

                

                    ET0 = 0;//关闭定时器

                    PCON = 0x01;//单片机进入空闲模式

                }

        }


这部分代码放在了定时器0的中断函数中,没有放在主函数中,导致外部中断无法响应,单片机无法从掉电模式或者是休眠模式中醒来

实验现象:数码管从00计数到05,之后进入休眠,数码管显示5,之后来一个外部中断,从5继续计数


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章