下面是是我学习CC2530(webee套件)-----睡眠定时器中断的两段程序:
/*****************************************
//初始化 Sleep Timer (设定后经过指定时间自行唤醒)
*****************************************/
void Init_SLEEP_TIMER(void)
{
ST2 = 0X00;
ST1 = 0X0f;
ST0 = 0X0f; //设置计数值
EA = 1; //开中断
STIE = 1; //SleepTimerinterrupt enable 使能睡眠定时器
STIF = 0; //SleepTimerinterrupt flag 清除睡眠定时器标志位
}
/*********************************************************************
//设置睡眠时间
//说明:读取睡眠定时器的当前计数值,顺序必须遵循:读ST0 →读ST1 →读ST2
写入睡眠定时器的比较值, 顺序必须遵循:写ST2 →写ST1 →写ST0
当定时器的计数值=比较值时,产生中断
*********************************************************************/
void Set_ST_Period(uint sec)
{
UINT32 sleepTimer = 0;
//把ST2:ST1:ST0赋值给sleeptimer
sleepTimer |= ST0;
sleepTimer |= (UINT32)ST1 << 8;
sleepTimer |= (UINT32)ST2 << 16;
sleepTimer += ((UINT32)sec * (UINT32)32768); //低速频率为32.768KHZ,故每秒定时器计数32768次
//把加N秒的计数值赋给ST2:ST1:ST0
ST2 = (UINT8)(sleepTimer >> 16);
ST1 = (UINT8)(sleepTimer >> 8);
ST0 = (UINT8) sleepTimer;
}
主函数直接调用 :Set_ST_Period(10); //10S之后重新进入睡眠
SysPowerMode(2); //进入PM2低频晶振模式,睡眠定时器中断唤醒
CC2530的睡眠定时器(SLEEP TIMER)是一个24位的计数器(最大0xffffff),可以用来作为唤醒中断(仅PM0-2)下面有效,ST的计数时钟是32.768K,向上计数,可以和一个24数比较以产生中断,在PM2仍然工作,可以产生中断.
实现定时唤醒就要利用ST的数差,相差32768,就表示1秒唤醒一次,相差n*32768表示n秒唤醒一次,这里的n可以是小数。
所以,既然是两次ST(ST0,ST1,ST2)的差值,为何还要在void Init_SLEEP_TIMER(void) 函数中写ST2 = 0X00; ST1 = 0X0f; ST0 = 0X0f; 我也看了无线龙的基础实验,是寄存器全部给0的,ST2 = 0X00; ST1 = 0X00; ST0 = 0X00;
ST是24位计数器0xFFFFFF,转成十进制是16777215,除以32768,等于511.99997秒,等于8分32秒。也就是在ST0=ST1 = ST2=0X00;前提下,最大定时时间是8分32秒。
按网蜂ST2 = 0X00; ST1 = 0X0f; ST0 = 0X0f; 0xffffff减去0xf0f,等于0xfff0f0,转成十进制16773360,在除以32768,等于511.88232秒,也近似约等于8分32秒。
所示,实在搞不清楚,void Init_SLEEP_TIMER(void) 函数里的为何要这么设置?ST2 = 0X00; ST1 = 0X0f; ST0 = 0X0f;
懂得给说下喽~~谢谢 |
|