對應電池供電的産品,在不使用的時候,單片機和外設都應該進入休眠狀态,用于減少對電池電量消耗.在使用的時候又能夠通過按鍵,或是其他信号喚醒系統,然後進入正常工作狀态.在電壓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;
}