应广单片机休眠和按键唤醒

       对应电池供电的产品,在不使用的时候,单片机和外设都应该进入休眠状态,用于减少对电池电量消耗.在使用的时候又能够通过按键,或是其他信号唤醒系统,然后进入正常工作状态.在电压V3.3V的情况下,应广单片机的休眠电流几乎在2uA以下,经常测到都是一点几uA.非常不错|那么应广单片机的低功耗和按键唤醒是怎么实现的呢?不多说上代码.除了外部唤醒,还有一种机制是内部定时器定时唤醒,请听下回分解!

#include    "extern.h"

#define     HIGH    1
#define  LOW    0

#define DISABLE 0
#define ENABLE 1

#define EMPTY 0
#define FULL 1

#define ON 1
#define OFF 0


#define LOW_POW_TIMING_TMR  5000

/*灯*/
BIT     LED_R           :        PA.0;

/*按键*/
BIT     KEY_POW           :        PA.3;


#define KEY_DEBOUNCE_CNT  20
#define KEY_LONG_PRESS_TIMER 1200

#define LED_R_ON   LED_R=1
#define LED_R_OFF  LED_R=0


/*定时时间是否到了cinit*/
bit     FLAG_NMS;
/*计数值cinit*/
byte    count;
/*定时器初始化cinit*/
word    T16COUNTER;


Eword ueLowPowAltTm;

byte ucKeyPowHigtCnt;
byte ucKeyPowLowCnt;
byte ucKeyPowSt;
byte ucKeyPowBak;
word usKeyPowLoPreCnt;
//word usKeyPowLoPreCntSet;
bit ucKeyPowPreSt;

void UpDateLedSt(void);
/***************************************/
void    TIME16_Init(void)
{
    /*计数值清零*/
    T16COUNTER    =488;
    /*ms标记reset*/
    FLAG_NMS    =0;
    
    /*使能定时器*/
    $    INTEN    T16;
    /*关中断*/
    INTRQ        =    0;
    
    /*停止定时器*/
       T16M.5        =0;               

    STT16 T16COUNTER;
    
    /*计算方法16M/*/
    $    T16M    IHRC,/1,BIT11;     
    

}

//byte ucPadierBak;
/*低功耗*/
void LowPow(void)
{
    /*退出功能则进入低功耗*/
   if((!ueLowPowAltTm) )
   {    
         /*关灯*/
         LED_R_OFF;
         
        .delay 1000;
        /*清看门狗*/
        wdreset;
        /*IHRC ->ILRC,关看门狗*/
        CLKMD=0xf4;
        /*禁用IHRC*/
        CLKMD.4=0;
        
        while(1)
        {
             /*低功耗*/
             STOPSYS;
           
             if(KEY_POW==0)
             { 
                   break;   
             }
         
           
        }
        /*ILRC->IHRC ,
         b7:5@001=IHRC/8,
         b4@1=IHRC
         
         b3@1=模式1
         b2@ 1=ILRC启动
         b1@ 1=看门狗开启
         b0@ 0=Pa5;
         
         模式口1;开看门狗*/
        CLKMD=0b001_1_1110;

        ueLowPowAltTm=LOW_POW_TIMING_TMR;

        //$ padier 0b111_1_1001;
        
    }
    
}

/*10ms任务函数*/
void UpDateKeyTmr(void)
{
     
    if(KEY_POW)
    {
        ucKeyPowHigtCnt=KEY_DEBOUNCE_CNT;
    }
    /*当前状态为0*/
    else
    {
        ucKeyPowLowCnt=KEY_DEBOUNCE_CNT;
    }


     /*KeyPow高电平计数值*/
     if(ucKeyPowHigtCnt)
     {
         ucKeyPowHigtCnt--;
        if(!ucKeyPowHigtCnt)
        {
            /*高电平倒计时完成说明当前为低*/
            ucKeyPowSt=LOW;
        }
     }
    
     /*KeyPow低电平计数值*/
     if(ucKeyPowLowCnt)
     {
         ucKeyPowLowCnt--;
        if(!ucKeyPowLowCnt)
        {
            /*低电平倒计时完成,说明当前为高*/
            ucKeyPowSt=HIGH;
        }
     }

}


/*状态切换*/
void GetKeySt(void)
{
       
      /*状态有变化*/
   if(ucKeyPowSt!=ucKeyPowBak)
   {  
        ucKeyPowBak=ucKeyPowSt;
        
        /*按键按下动作*/
        if(!ucKeyPowSt)
        {
                ueLowPowAltTm=LOW_POW_TIMING_TMR;
                /*点灯*/
                LED_R_ON;
           }
    }

}

/*端口状态初始化*/
void KeyAppInit(void)
{
    
    if(KEY_POW)
    {
        ucKeyPowSt=HIGH;
        ucKeyPowBak=HIGH;
    }
    else
    {
        ucKeyPowSt=LOW;
        ucKeyPowBak=LOW;
    }

    ucKeyPowHigtCnt=KEY_DEBOUNCE_CNT;
    ucKeyPowLowCnt=KEY_DEBOUNCE_CNT;
    usKeyPowLoPreCnt=0;
    ucKeyPowPreSt=0;

  
}


void    FPPA0 (void)
{
    .ADJUST_IC    SYSCLK=IHRC/8, IHRC=16MHz, VDD=3.0V;
    $ CLKMD IHRC/8,En_IHRC,En_ILRC,En_WatchDog;
    
    .delay 40000;
      
    $  KEY_POW     IN,PULL; 

    $  LED_R     OUT,LOW;

    TIME16_Init();
    
    KeyAppInit();

    ueLowPowAltTm=1;
    
    engint;
    
    while (1)
    {

            wdreset;


         /*1ms定时时间到*/
         if ( FLAG_NMS )
         {
             /*清除标记*/
            FLAG_NMS=0;


            UpDateKeyTmr();


            /*低功耗定时器*/
            if(ueLowPowAltTm)
            {
                ueLowPowAltTm--;
            }
            LowPow();

           
        }
        
        /*取得按键状态*/
        GetKeySt();

        
    }
}

void    Interrupt ( void )
{
    pushaf;

    if ( Intrq.T16 )  
    {

        Intrq.T16    =    0;
        
        STT16 T16COUNTER;

        
        if ( count>0 )
        {
            count--;
        }
        else
        {
            count   =   9;
            /*1ms*/
            FLAG_NMS=   1;      
        }

    }

    popaf;
}
 

 

 

  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值