(一)中断唤醒
一、实验内容
通过中断唤醒在睡眠模式下的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); //进入正常工作模式 }