这个实验利用睡眠定时器工作在多个电源模式下这一特性来实现定时唤醒,最长的唤醒时隔为8 分32 秒,而最短的时隔可达 30余微秒。实验中在设定好唤醒时间后让 CC2430进入PM2 模式,在达到指定时间后小灯闪烁,之后再次是设定唤醒时间,进入PM2 ,唤醒的循环。
void Init_SLEEP_TIMER(void) ;
函数原型:
1 void Init_SLEEP_TIMER(void) 2 { 3 EA = 1; // 开中断 4 STIE = 1; 5 STIF = 0; 6 }
函数功能: 打开睡眠定时器(ST)的中断,并且将ST的中断标志位清零。在使用ST时必须于addToSleepTimer() 前调用本函数。
void addToSleepTimer(UINT16 sec) ;
函数原型:
1 void addToSleepTimer(UINT16 sec) 2 { 3 UINT32 sleepTimer = 0; 4 5 sleepTimer |= ST0; 6 sleepTimer |= (UINT32)ST1 << 8; 7 sleepTimer |= (UINT32)ST2 << 16; 8 9 sleepTimer += ((UINT32)sec * (UINT32)32768); 10 11 ST2 = (UINT8)(sleepTimer >> 16); 12 ST1 = (UINT8)(sleepTimer >> 8); 13 ST0 = (UINT8) sleepTimer; 14 }
函数功能:设置睡眠时间,在sec 秒以后由 ST唤醒CC2430,在调用这个函数之前必须先调用Init_SLEEP_TIMER (),否则不能唤醒CC2430。通常在这个函数以后会出现SET_POWER_MODE(2)语句。
1 /***************************************** 2 // For: 3 // emot.h 4 *****************************************/ 5 #ifndef EMOT_H 6 #define EMOT_H 7 8 #include <ioCC2430.h> 9 10 /***************************************** 11 //定义类型 12 *****************************************/ 13 #define uchar unsigned char 14 #define uint unsigned int 15 #define UINT8 uchar 16 #define UINT16 unsigned int 17 #define UINT32 unsigned long 18 19 /***************************************** 20 //定义常量 21 *****************************************/ 22 #ifndef FALSE 23 #define FALSE 0 24 #endif 25 26 #ifndef TRUE 27 #define TRUE 1 28 #endif 29 30 #ifndef NULL 31 #define NULL 0 32 #endif 33 34 #ifndef HIGH 35 #define HIGH 1 36 #endif 37 38 #ifndef LOW 39 #define LOW 0 40 #endif 41 42 /***************************************** 43 //LED 使能控制 44 *****************************************/ 45 #define LED_ENABLE(val) \ 46 do{ \ 47 if(val==1) \ 48 { \ 49 P1SEL &= ~0X03; \ 50 P1DIR |= 0X03; \ 51 RLED = 1; \ 52 GLED = 1; \ 53 } \ 54 else \ 55 { \ 56 P1DIR &= ~0X03; \ 57 } \ 58 }while(0) 59 60 #define RLED P1_0 61 #define GLED P1_1 62 63 /***************************************** 64 //选择主时钟,关闭不用的时钟 65 *****************************************/ 66 #define SET_MAIN_CLOCK_SOURCE(source) \ 67 do { \ 68 if(source) { \ 69 CLKCON |= 0x40; /*RC*/ \ 70 while(!(SLEEP&0X20)); /*待稳*/ \ 71 SLEEP |= 0x04; /*关掉不用的*/ \ 72 } \ 73 else { \ 74 SLEEP &= ~0x04; /*全开*/ \ 75 while(!(SLEEP&0X40));/*待稳*/ \ 76 asm("NOP"); \ 77 CLKCON &= ~0x47; /*晶振*/ \ 78 SLEEP |= 0x04; /*关掉不用的*/ \ 79 } \ 80 }while (0) 81 82 #define CRYSTAL 0 83 #define RC 1 84 85 /***************************************** 86 //选择低速时钟 87 *****************************************/ 88 #define SET_LOW_CLOCK(source) \ 89 do{ \ 90 (source==RC)?(CLKCON |= 0X80):(CLKCON &= ~0X80); \ 91 }while(0) 92 93 94 95 //Macro for setting the clock tick for timer3 or 4 96 #define TIMER3_START(val) \ 97 (T##timer##CTL = (val) ? T##timer##CTL | 0X10 : T##timer##CTL&~0X10) 98 99 #define TIMER3_SET_CLOCK_DIVIDE(timer,val) \ 100 do{ \ 101 T##timer##CTL &= ~0XE0; \ 102 (val==2) ? (T##timer##CTL|=0X20): \ 103 (val==4) ? (T##timer##CTL|=0x40): \ 104 (val==8) ? (T##timer##CTL|=0X60): \ 105 (val==16)? (T##timer##CTL|=0x80): \ 106 (val==32)? (T##timer##CTL|=0xa0): \ 107 (val==64) ? (T##timer##CTL|=0xc0): \ 108 (val==128) ? (T##timer##CTL|=0XE0): \ 109 (T##timer##CTL|=0X00); /* 1 */ \ 110 }while(0) 111 112 //Macro for setting the mode of timer3 or 4 113 #define TIMER3_SET_MODE(timer,val) \ 114 do{ \ 115 T##timer##CTL &= ~0X03; \ 116 (val==1)?(T##timer##CTL|=0X01): /*DOWN */ \ 117 (val==2)?(T##timer##CTL|=0X02): /*Modulo */ \ 118 (val==3)?(T##timer##CTL|=0X03): /*UP / DOWN */ \ 119 (T##timer##CTL|=0X00); /*free runing */ \ 120 }while(0) 121 122 123 #define SET_POWER_MODE(mode) \ 124 do { \ 125 if(mode == 0) { SLEEP &= ~0x03; } \ 126 else if (mode == 3) { SLEEP |= 0x03; } \ 127 else { SLEEP &= ~0x03; SLEEP |= mode; } \ 128 PCON |= 0x01; \ 129 asm("NOP"); \ 130 }while (0) 131 132 /***************************************** 133 //开启电池板上的按键 134 *****************************************/ 135 #define USE_Key_ON_BT() \ 136 #define USE_Key_ON_BT() \ 137 do{ \ 138 //P1DIR &= ~0X0C; /*按键在P12 P13*/ 139 //P1INP &= ~0x0c; //上、下拉 140 141 P0DIR&=~0X60; /*按键在P05 P06*/ \ 142 P0INP|=0X60; \ 143 P2INP |= 0x40; \ 144 145 }while(0) 146 147 #endif //EMOT_H
1 //main.c 2 3 #include <emot.h> 4 5 /***************************************** 6 //初始化Sleep Timer 7 *****************************************/ 8 void Init_SLEEP_TIMER(void) 9 { 10 EA = 1; //开中断 11 STIE = 1; 12 STIF = 0; 13 } 14 15 /***************************************** 16 //设置Sleep Timer唤醒时间 17 //sec :间隔时间,单位为秒 18 //无返回 19 *****************************************/ 20 void addToSleepTimer(UINT16 sec) 21 { 22 UINT32 sleepTimer = 0; 23 24 sleepTimer |= ST0; 25 sleepTimer |= (UINT32)ST1 << 8; 26 sleepTimer |= (UINT32)ST2 << 16; 27 28 sleepTimer += ((UINT32)sec * (UINT32)32768); 29 30 ST2 = (UINT8)(sleepTimer >> 16); 31 ST1 = (UINT8)(sleepTimer >> 8); 32 ST0 = (UINT8) sleepTimer; 33 } 34 35 /***************************************** 36 //延时函数 37 *****************************************/ 38 void Delay(uint n) 39 { 40 uint jj; 41 for(jj=0;jj<n;jj++); 42 for(jj=0;jj<n;jj++); 43 for(jj=0;jj<n;jj++); 44 for(jj=0;jj<n;jj++); 45 for(jj=0;jj<n;jj++); 46 } 47 48 /***************************************** 49 //LED闪烁函数 50 *****************************************/ 51 void LedGlint(void) 52 { 53 uchar jj=10; 54 while(jj--) 55 { 56 RLED = !RLED; 57 Delay(10000); 58 } 59 } 60 61 /********************************************************************* 62 //主函数 63 *********************************************************************/ 64 void main(void) 65 { 66 SET_MAIN_CLOCK_SOURCE(CRYSTAL); 67 SET_LOW_CLOCK(CRYSTAL); 68 LED_ENABLE(1); 69 RLED = 1; 70 GLED = 0; 71 72 Init_SLEEP_TIMER(); 73 while(1) 74 { 75 addToSleepTimer(10); 76 SET_POWER_MODE(2); 77 LedGlint(); 78 GLED = ~GLED; 79 } 80 } 81 82 #pragma vector = ST_VECTOR 83 __interrupt void ST_ISR(void) 84 { 85 STIF = 0; 86 }