睡眠及唤醒Word文档下载推荐.docx
《睡眠及唤醒Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《睡眠及唤醒Word文档下载推荐.docx(11页珍藏版)》请在冰点文库上搜索。
→
2s后被睡眠定时器唤醒为PM0
→进入PM3
→等待按键S1按下,触发外部中断,被唤醒为PM0
(2)程序流程图
(注:
上图中的圆角框表示系统的运行状况)
(3)实验源码及剖析(下面的框框是可以点的~)
头文件及宏定义
/*
实验说明:
中断唤醒睡眠实验,分别介绍三种睡眠模式下的唤醒
*/
#include<
ioCC2430.h>
#defineLED_ON0
#defineLED_OFF1
#defineled1P1_0
#defineled2P1_1
#defineled3P1_2
#defineled4P1_3
子函数
/*系统时钟初始化
-------------------------------------------------------*/
voidxtal_init(void)
{
SLEEP&
=~0x04;
//都上电
while(!
(SLEEP&
0x40));
//晶体振荡器开启且稳定
CLKCON&
=~0x47;
//选择32MHz晶体振荡器
SLEEP|=0x04;
}
/*LED初始化
voidled_init(void)
P1SEL=0x00;
//P1为普通I/O口
P1DIR|=0x0F;
//P1.0P1.1P1.2P1.3输出
led1=LED_OFF;
//关闭所有LED
led2=LED_OFF;
led3=LED_OFF;
led4=LED_OFF;
/*外部中断初始化
voidio_init(void)
P0INP&
=~0X02;
//P0.1有上拉、下拉
EA=1;
//总中断允许
IEN1|=0X20;
//P0IE=1,P0中断使能
PICTL|=0X09;
//P0.1允许中断,下降沿触发
P0IFG&
=~0x02;
//P0.1中断标志清0
/*睡眠定时器中断初始化
voidsleepTimer_init(void)
STIF=0;
//睡眠定时器中断标志清0
STIE=1;
//开睡眠定时器中断
EA=1;
//开总中断
/*设置睡眠定时器的定时间隔
voidsetSleepTimer(unsignedintsec)
unsignedlongsleepTimer=0;
sleepTimer|=ST0;
//取得目前的睡眠定时器的计数值
sleepTimer|=(unsignedlong)ST1<
<
8;
sleepTimer|=(unsignedlong)ST2<
16;
sleepTimer+=((unsignedlong)sec*(unsignedlong)32768);
//加上所需要的定时时长
ST2=(unsignedchar)(sleepTimer>
>
16);
//设置睡眠定时器的比较值
ST1=(unsignedchar)(sleepTimer>
8);
ST0=(unsignedchar)sleepTimer;
/*选择电源模式
voidPowerMode(unsignedcharmode)
if(mode<
4)
{
=0xfc;
//将SLEEP.MODE清0
SLEEP|=mode;
//选择电源模式
PCON|=0x01;
//启用此电源模式
}
/*延时函数
voidDelay(unsignedintn)
unsignedinti,j;
for(i=0;
i<
n;
i++)
for(j=0;
j<
1000;
j++);
主函数
/*主函数
voidmain(void)
{
xtal_init();
led_init();
//PM0状态,亮灯并延时
led1=LED_ON;
//亮LED1,表示统在PM0模式工作
Delay(10);
//PM1状态,灭灯
setSleepTimer
(1);
//设置睡眠定时器的定时间隔为1s
sleepTimer_init();
PowerMode
(1);
//设置电源模式为PM1
//1s后,由PM1进入PM0,亮灯并延时
Delay(50);
//PM2,灭灯
setSleepTimer
(2);
//设置睡眠定时器的定时间隔为2s
PowerMode
(2);
//设置电源模式为PM2
//2s后,由PM2进入PM0,亮灯并延时
led1=0;
//PM3,灭灯
io_init();
//初始化外部中断
PowerMode(3);
//设置电源模式为PM3
//当外部中断发生时,由PM3进入PM0,亮灯
while
(1);
中断服务程序
/*外部中断服务程序
#pragmavector=P0INT_VECTOR
__interruptvoidP0_ISR(void)
EA=0;
//关中断
if((P0IFG&
0x02)>
0)//按键中断
P0IF=0;
//P0中断标志清0
//开中断
/*睡眠定时器中断服务程序
#pragmavector=ST_VECTOR
__interruptvoidsleepTimer_IRQ(void)
EA=0;
关于如何使用睡眠定时器来唤醒系统,可以总结为如下流程:
开睡眠定时器中断→设置睡眠定时器的定时间隔→设置电源模式
“设置睡眠定时器的定时间隔”这一步一定要在“设置电源模式”之前,因为进入睡眠后系统就不会继续执行程序了)
接下来,我们重点关注一下设置睡眠定时器定时间隔的子函数:
setSleepTimer
首先对睡眠定时器简单的介绍一下:
它是运行于32.768kHz的24位定时器,当系统运行在除了PM3之外的所有的电源模式下,睡眠定时器都会不间断运行。
睡眠定时器使用的寄存器有:
ST0,ST1,ST2。
下面是摘自CC2430中文手册对其功能的详细介绍:
可以看出,它们的功能包括两方面:
读,写。
读:
用于读取当前定时器的计数值,读的顺序必须遵循:
读ST0→读ST1→读ST2
写:
用于设置定时器的比较值(当定时器的计数值=比较值时,产生中断),写的顺序必须遵循:
写ST2→写ST1→写ST0
OK,接下来我们结合源码来讲解:
(1)首先,定义一个unsignedlong型变量(32位)sleepTimer,用于接收睡眠定时器的当前计数值:
(2)然后加上所需要的定时间隔:
此处需要稍微解释一下:
为什么1s就代表着32768?
因为定时器是工作在32.768kHz之下,所以定时器每加1,需耗时1/32768s;
加32768,就需要1s;
(3)最后将sleepTimer的值作为定时器的比较值:
这样,就可成功设置定时器的定时周期啦~
至于源码的其他部分,相信结合着详细的注释,大家可以轻松看懂,在此不作赘述)
(4)实验结果
运行程序,观察LED1,现象为:
LED1闪烁(即亮->
灭1次),1s后再次闪烁,2s后再次闪烁,然后保持熄灭状态,然后按下S1,LED1亮。
实验现象和预期完全吻合,Over~
三、结语
吁~抽出2天的课余时间,终于搞定了这篇日志。
真的发现写博,特别是写一篇“读者友好”的博文,的确是一项体力活:
严谨性、美观性、逻辑性...都是要考虑的事儿。
每次贴代码都嫌太长,但又不太愿意使用博客园自带的折叠工具。
因此在本篇博文中,笔者试探性的加入了一些JQuery元素,实现了代码的平滑折叠,还是有小小的成就感嘀,呵呵(JQuery菜鸟,高手勿笑~)。
但当局者迷,我并不知这样做是否真正增强了文章的可读性,欢迎读者朋友作出评论:
)
这一个月,笔者真正决定在博客园扎下根来,于是花费了大量的课余时间在博文的写作上。
初次写博,虽然评论很少,但大部分日志都有500以上的点击率,也算是对我的小小的鼓励!
在博客园发表关于单片机的内容,的确需要勇气,不过我会坚持写下去的~
从开始到现在的九篇博文,重点是CC2430芯片上的基本硬件模块的运用。
到此为止,我们基本上把CC2430上的大部分外设都过了一遍,但是还有比如Flash存取、随机数发生器、AES协处理器、射频通信等,还没涉及到。
不过Zigbee之旅并未结束,笔者打算在下一个主题(Z-Stack协议的实现)中,再来有选择性的把这些遗漏之处补齐。