单片机的电源选项

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

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

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

空闲模式:

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

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

 

掉电模式:

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

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

错误代码:

#include<reg52.h>
#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;
}
View Code


正确代码:

#include<reg52.h>
#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;
}
View Code

错误代码中,把

if(aa ==20)
        {
            aa =0;
            num++;
            if(num == 99)
                num =0;
            gw = num%10;
            sw = num/10;
            if(num == 6)
                {
                
                    ET0 = 0;//关闭定时器
                    PCON = 0x01;//单片机进入空闲模式
                }
        }
View Code

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

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

 

版权所有,转载请注明链接地址:http://www.cnblogs.com/fengdashen/p/3358735.html

 

### 单片机电源模块的设计与应用 #### 一、设计工具的选择单片机控制系统中,选择合适的开发工具对于项目的成功至关重要。针对PCB电路板布线工作,常用的是Protel 99SE这一款功能强大的电子线路辅助设计软件[^1]。它能够帮助工程师完成从原理图绘制到最终生产文件生成的一系列操作。 而对于程序编写和调试,则依赖于像Keil uVision2这样的集成开发环境(IDE)。该平台支持多种微控制器架构下的嵌入式应用程序开发,并提供了丰富的编译器选项以及高效的仿真测试手段。 #### 二、输入保护措施 考虑到实际应用场景中的复杂性和不确定性,在构建基于单片机系统的硬件部分时还需要特别注意一些细节处理。例如,当涉及到外部供电接口时,应当采取有效的防护策略以保障整个装置的安全稳定运行。具体来说,为了应对可能发生的瞬态过压情况,可以在输入端加入电容器C1作为缓冲元件,以此来抑制任何可能出现的大规模电压突变现象[^2]。 此外,选用具备宽泛适应范围特性的降压转换芯片也是十分必要的。比如MP2359就拥有着良好的兼容性能——其允许的工作电压区间可以从最低+4.5伏特一直到最高可达+24伏特之间变化而不受影响。 ```c // 示例代码展示如何初始化ADC并读取模拟信号值(假设使用STM8S单片机) #include "stm8s.h" void ADC_Init(void){ // 配置PA0为模拟输入模式 GPIO_DeInit(GPIOA); GPIO_Init(GPIOA, GPIO_PIN_0, GPIO_MODE_IN_FL_NO_IT); // 开启ADC外设时钟 CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, ENABLE); // 设置通道数等参数... } uint16_t Read_Voltage(){ uint16_t result; // 启动一次转换 ADC_StartConversion(); while(!ADC_GetFlagStatus(ADC_FLAG_EOC)); // 获取转换后的数值 result = ADC_GetConversionValue(); return result; } ``` 此段伪代码展示了在一个典型的应用场景下,通过配置特定引脚状态及开启相应外设资源的方式实现对某一物理量(此处指代电压水平)的有效监测过程。当然这只是一个非常基础的例子,真实项目里往往还会涉及更多复杂的逻辑判断环节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值