(一)中斷喚醒
一、實驗內容
通過中斷喚醒在睡眠模式下的CC2540
二、實驗原理
1、系統電源管理(工作方式)
(1)全功能模式:
高頻晶振(16M或者32M)和低頻晶振(32.768K RCOSC/XOSC)全部工作,數字梳理模塊正常工作
(2)PM1:
高頻晶振(16或者32M)關閉,低頻晶振(32.768K RCOSC/XOSC)工作,數字核心模塊正常工作。
(3)PM2:
低頻晶振(32.768K RCOSC/XOSC)工作,數字核心模塊關閉,系統通過RESET,外部中斷或者睡眠計時器溢出喚醒
(3)PM3:
晶振全部關閉,數字處理核心模塊關閉,系統只能通過RESET或外部中斷喚醒。此模式的功耗最低。
2、LED硬件原理圖
3、寄存器配置
| PCON(0X87) 系統電源模式控制寄存器 |
BIT0 置1將強制系統進入SLEEPCMD所指定的電源模式,所有中斷信號都可以清除此置位 |
| SLEEPCMD(0XBE) 系統電源模式設定 |
BIT1:BIT0 00:全功能模式 01:PM1模式 10:PM2模式 11:PM3模式 |
三、實驗代碼
#include<ioCC2540.h> //宏定義聲明 #define uint unsigned int #define uchar unsigned char #define LED2 P1_1 #define KEY1 P0_0 //函數聲明 void Delayms(uint); //延時函數 void InitLed(void); //初始化P1 void SysPowerMode(uchar); //系統工作模式選擇 //延時 void Delayms(uint t) { uint i,j; for(i=t;i>0;i--) { for(j=587;j>0;j--) { } } } //初始化 void InitLed(void) { P1DIR |= 0x02; //P1_1 ,LED2 定義為輸出 LED2=0; //LED2熄滅 P0INP &= ~0x01; //設置P0口輸入電路模式為上下拉 P0IEN |= 0X01; //P0_0設置為中斷方式 PICTL |= 0x01; //下降沿觸發 } //系統工作模式選擇 void SysPowerMode(uchar mode) { uchar i,j; i=mode; if(mode<4) { SLEEPCMD |= i; //設置系統睡眠模式 for(j=0;j<4;j++) { PCON=0x01; //進入睡眠模式,通過中斷關閉 } } else { PCON=0x00; //喚醒系統 } } //主函數 void main(void) { uchar count=0; InitLed(); IEN1 |= 0X20; //開PO口總中斷 P0IFG |= 0x00; //清中斷標志 EA=1; while(1) { LED2=~LED2; if(++count>=10) { count=0; SysPowerMode(3); //5次閃爍后進入睡眠狀態PM3,等待按鍵S1中斷喚醒 } Delayms(500); } } #pragma vector = P0INT_VECTOR __interrupt void func(void) { if(P0IFG>0) { P0IFG=9; } P0IF=0; SysPowerMode(4); }
定時器喚醒睡眠模式
可以做到一段時間工作,一段時間休眠的效果,也就是說定時器會先使得系統在睡眠模式下也會有一個定時器進行計時,在計時到一段時間后進入中斷,改變工作模式,即可做到喚醒睡眠模式,或者在不同的模式下進行切換。
下面是代碼
#include<ioCC2540.h> #define uint unsigned int #define uchar unsigned char #define UINT8 unsigned char #define UINT16 unsigned int #define UINT32 unsigned long //定義控制LED燈的端口 #define LED2 P1_1 //定義LED2為P1.1口控制 //函數聲明 void Delayms(uint); //延時函數 void InitLed(void); //初始化P1口 void SysPowerMode(uchar sel); //系統工作模式 /**************************** //延時函數 *****************************/ void Delayms(uint xms) //i=xms 即延時i毫秒 { uint i,j; for(i=xms;i>0;i--) for(j=587;j>0;j--); } /**************************** //初始化程序 *****************************/ void InitLed(void) { P1DIR |= 0x02; //P1_0、P1_1定義為輸出 LED2 = 0; //LED2燈熄滅 } /**************************************************************** 系統工作模式選擇函數 * para1 0 1 2 3 * mode PM0 PM1 PM2 PM3 ****************************************************************/ void SysPowerMode(uchar mode) { uchar i,j; i = mode; if(mode<4) { SLEEPCMD |= i; // 設置系統睡眠模式 for(j=0;j<4;j++); PCON = 0x01; // 進入睡眠模式 ,通過中斷打斷 } else { PCON = 0x00; // 系統喚醒 ,通過中斷打斷 } } /***************************************** //初始化 Sleep Timer (設定后經過指定時間自行喚醒) *****************************************/ void Init_SLEEP_TIMER(void) { ST2 = 0X00; ST1 = 0X0F; ST0 = 0X0F; EA = 1; //開中斷 STIE = 1; //SleepTimerinterrupt enable STIF = 0; //SleepTimerinterrupt flag 還沒處理的 } /********************************************************************* //設置睡眠時間 *********************************************************************/ void Set_ST_Period(uint sec) { UINT32 sleepTimer = 0; sleepTimer |= ST0; sleepTimer |= (UINT32)ST1 << 8; sleepTimer |= (UINT32)ST2 << 16; sleepTimer += ((UINT32)sec * (UINT32)32768); ST2 = (UINT8)(sleepTimer >> 16); ST1 = (UINT8)(sleepTimer >> 8); ST0 = (UINT8) sleepTimer; } /*************************** //主函數 ***************************/ void main(void) { uchar i; InitLed(); //調用初始化函數 Init_SLEEP_TIMER(); //初始化SLEEPTIMER while(1) { for(i=0;i<6;i++) //閃爍3下 { LED2=~LED2; Delayms(200); } Set_ST_Period(3); //重新進入睡眠模式 SysPowerMode(2); //進入PM2低頻晶振模式 } } //中斷喚醒 #pragma vector = ST_VECTOR __interrupt void ST_ISR(void) { STIF = 0; //清標志位 SysPowerMode(4); //進入正常工作模式 }

