打印
[Zigbee]

CC2530系统睡眠唤醒—中断唤醒

[复制链接]
1254|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gwsan|  楼主 | 2019-8-1 13:54 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
1 理论分析
1.1 CC2530 睡眠定时器简介
睡眠定时器用于设置系统进入和退出低功耗睡眠模式之间的周期。睡眠定时器还用于当进入低功耗睡眠模式时,维持定时器 2 的定时。

睡眠定时器的主要功能如下:

        24 位的定时器正计数器,运行在 32kHz 的时钟频率
        24 位的比较器,具有中断和 DMA 触发功能
        24 位捕获


使用特权

评论回复
评论
dirtwillfly 2019-8-3 20:46 回复TA
感谢分享 

相关帖子

沙发
gwsan|  楼主 | 2019-8-1 13:54 | 只看该作者
1、概述
睡眠定时器是一个 24 位的定时器,运行在一个 32kHz 的时钟频率(可以是 RCOSC 或 XOSC)上。定时器在复位之后立即启动,如果没有中断就继续运行。定时器的当前值可以从 SFR 寄存器 ST2:ST1:ST0 中读取。

2、定时器比较
当定时器的值等于 24 位比较器的值,就发生一次定时器比较。通过写入寄存器 ST2:ST1:ST0 来设置比较值。当 STLOAD.LDRDY 是 1 写入 ST0 发起加载新的比较值,即写入 ST2、ST1 和 ST0 寄存器的最新的值。

加载期间 STLOAD.LDRDY 是 0,软件不能开始一个新的加载,直到 STLOAD.LDRDY 回到 1。读 ST0 将捕获 24 位计数器的当前值。因此,ST0 寄存器必须在 ST1和 ST2 之前读,以捕获一个正确的睡眠定时器计数值。当发生一个定时器比较,中断标志 STIF 被设置。每次系统时钟,当前定时器值就被更新。因此,当从 PM1/2/3(这期间系统时钟关闭)返回,如果尚未在 32kHz 时钟上检测到一个正时钟边沿,ST2:ST1:ST0 中的睡眠定时器值不更新, 要保证读出一个最新的值, 必须在读睡眠定时器值之前,在 32kHz 时钟上通过轮询 SLEEPSTA.CLK32K 位,等待一个正的变换。

ST 中断的中断使能位是 IEN0.STIE,中断标志是 IRCON.STIF。
当运行在所有供电模式,除了 PM3 时,睡眠定时器将开始运行。因此,睡眠定时器的值在 PM3 下不保存。在 P1 和 PM2 下睡眠定时器比较事件用于唤醒设备,返回主动模式的主动操作。复位之后的比较值的默认值是 0xFFFFFF。
睡眠定时器比较还可以用作一个 DMA 触发。

注意:如果电压降到 2V 以下同时处于 PM2,睡眠间隔将会受到影响。

使用特权

评论回复
板凳
gwsan|  楼主 | 2019-8-1 13:55 | 只看该作者
3、定时器捕获
当设置了已选 I/O 引脚的中断标志,且 32 kHz 时钟检测到这一事件时,发生定时器捕获。睡眠定时器通过设置将要用作触发捕获的 I/O 引脚的 STCC.PORT[1:0]和 STCC.PIN[2:0]使能。当 STCS.VALID 变为高电平,即可读 STCV2:STCV1:STCV0 的捕获值。捕获值多于在 I/O 引脚上的事件瞬间的值,因此如果时序需要,软件必须从捕获的值中间抽取一个。要使能一个新的捕获,遵循以下步骤:

(1) 清除 STCS.VALID。
(2) 等待直到 SLEEPSTA.CLK32K 变为低电平。
(3) 等待直到 SLEEPSTA.CLK32K 变为高电平。
(4) 清除 P0IFG/P1IFG/P2IFG 寄存器中的引脚中断标志。

这一顺序使用 P0.0 上的上升沿为例,见图1。


图 1 睡眠定时器捕获(使用 P0_0 的上升沿为例)
当捕获使能,不能切换输入捕获引脚。在选择一个新的输入捕获引脚之前,捕获必须禁用。要禁用捕获,遵循以下步骤(如果禁用了中断,使用一个高达 32 kHz 周期(~15.26 us)的一半即可) :
(1) 禁用中断
(2) 等待直到 SLEEPSTA.CLK32K 变为高电平。
(3) 设置 STCC.PORT[1:0]为 3。这将禁用捕获。


使用特权

评论回复
地板
gwsan|  楼主 | 2019-8-1 13:55 | 只看该作者
1.2 CC2530 工作模式介绍
1、概述
Zigbee 的特点就是远距离低功耗的无线传输设备,节点模块闲时可以进入睡眠模式,在需要传输数据时候进行唤醒,能进一步节省电量。
CC2530 有五种不同的运行模式(供电模式) ,叫做主动模式、空闲模式、PM1、PM2 和 PM3。主动模式是一般模式,而 PM3 具有最低的功耗。不同的供电模式对系统运行的影响见表,并给出了稳压器和振荡器选择。

表 1 不同的供电模式对系统运行的影响


==主动模式:==完全功能模式。稳压器的数字内核开启,16 MHz RC 振荡器或 32 MHz 晶体振荡器运行,或者两者都运行。32 kHz RCOSC 振荡器或 32kHz XOSC 运行。

==空闲模式:==除了 CPU 内核停止运行(即空闲) ,其他和主动模式一样。
PM1:稳压器的数字部分开启。32 MHz XOSC 和 16 MHz RCOSC 都不运行。32kHz RCOSC 或 32 kHz XOSC 运行。复位、外部中断或睡眠定时器过期时系统将转到主动模式。

==PM2:==稳压器的数字内核关闭。32 MHz XOSC 和 16 MHz RCOSC 都不运行。32kHz RCOSC 或 32 kHz XOSC 运行。复位、外部中断或睡眠定时器过期时系统将转到主动模式。

==PM3:==稳压器的数字内核关闭。所有的振荡器都不运行。复位或外部中断时系统将转到主动模式。

2、管理控制
所需的供电模式通过使用 SLEEPCMD 控制寄存器的 MODE 位和 PCON.IDLE 位来选择。设置 SFR 寄存器的 PCON.IDLE 位,进入 SLEEPCMD.MODE 所选的模式。来自端口引脚或睡眠定时器的使能的中断,或上电复位将从其他供电模式唤醒设备,使它回到主动模式。

当进入 PM1、PM2 或 PM3,就运行一个掉电序列。当设备从 PM1、PM2 或 PM3中出来,它在 16 MHz 开始,如果当进入供电模式(设置 PCON.IDLE)且 CLKCONCMD.OSC = 0 时,自动变为 32 MHz。如果当进入供电模式设置了 PCON.IDLE 且 CLKCONCMD.OSC = 1,它继续运行在 16 MHz。


使用特权

评论回复
5
gwsan|  楼主 | 2019-8-1 13:56 | 只看该作者
2 实验详解
2.1.实验目的
掌握几种系统电源模式的基本设置及切换;
将睡眠模式下的CC2530 通过定时器唤醒,观察LED 闪烁现象
2.2.实验设备
硬件:PC 机一台ZB2530(底板、核心板、仿真器、USB 线) 一套
软件:win7 系统,IAR 8.20 集成开发环境

使用特权

评论回复
6
gwsan|  楼主 | 2019-8-1 13:56 | 只看该作者

2.3.实验相关电路图

图2 LED电路图

图3 按键电路图

使用特权

评论回复
7
gwsan|  楼主 | 2019-8-1 13:57 | 只看该作者
2.4.实验分析及相关寄存器

相关寄存器PCON,SLEEPCMD, ST0,ST1,ST2,如下表所示:

表2 供电模式控制


使用特权

评论回复
8
gwsan|  楼主 | 2019-8-1 13:57 | 只看该作者
表3 睡眠模式控制


使用特权

评论回复
9
gwsan|  楼主 | 2019-8-1 13:58 | 只看该作者
表4 休眠定时器0


使用特权

评论回复
10
gwsan|  楼主 | 2019-8-1 13:58 | 只看该作者
表5 休眠定时器1


使用特权

评论回复
11
gwsan|  楼主 | 2019-8-1 13:58 | 只看该作者
表6 休眠定时器2


使用特权

评论回复
12
gwsan|  楼主 | 2019-8-1 13:59 | 只看该作者
睡眠定时器用于设置系统进入和退出低功耗睡眠模式之间的周期。还用于当系统进入低功耗模式后,维持MAC 定时器(T2)的定时。

其特性如下: 长达24 位定时计数器,运行在32.768KHZ的工作频率。24 位的比较器具有中断和DMA 触发功能在PM2 低功耗模式下运行.按照表格寄存器的内容,相关寄存器配置如下:

SLEEPCMD |= mode; //设置系统睡眠模式mode 取值为0、1、2、3
PCON = 0x01; //进入睡眠模式,通过中断唤醒
PCON = 0x00; //通过中断唤醒系统


使用特权

评论回复
13
gwsan|  楼主 | 2019-8-1 14:00 | 只看该作者
2.5 参考代码
/**Includes*********************************************************************/
#include <ioCC2530.h>

/**宏定义***********************************************************************/
//定义数据类型
typedef unsigned char uchar;
typedef unsigned int  uint;

//定义IO口
#define LED1 P1_0            //P1.0口控制LED1
#define KEY2 P2_0            //P2.0口控制KEY2

/**函数声明*********************************************************************/
void DelayMS(uint msec);
void InitLed(void);
void InitKey();
void SysPowerMode(uchar mode) ;

/**
  * @brief     主函数
  * @param     None
  * @retval    None
  */
void main(void)
{   
    uchar i=0;  
      
    InitLed();                     //设置LED灯相应的IO口     
    InitKey();               //设置KEY相应的IO口
   
    while(1)
    {
        for (i=0; i<6; i++)  //LED闪烁3次提醒用户将进入睡眠模式
        {
            LED1 = ~LED1;
            DelayMS(500);
        }

        SysPowerMode(3);     //进入睡眠模式PM3,按下按键K1中断唤醒系统
    }
}

使用特权

评论回复
14
gwsan|  楼主 | 2019-8-1 14:00 | 只看该作者
/**
  * @brief     延时函数,大约1毫秒
  * @param     msec 延时大小
  * @retval    None
  */
void DelayMS(uint msec)
{
    uint i,j;
   
    for (i=0; i<msec; i++)
        for (j=0; j<535; j++);
}

/**
  * @brief     LED控制IO口初始化函数
  * @param     None
  * @retval    None
  */
void InitLed(void)
{
    P1DIR |= 0x01;           //P1.0定义为输出口
    LED1 = 1;                //LED灯上电默认为熄灭
}

/**
  * @brief     按键控制IO口初始化函数
  * @param     None
  * @retval    None
  */
void InitKey()
{
    P2IEN |= 0x1;    // P2.0 设置为中断方式 1:中断使能
    PICTL |= 0x8;    //下降沿触发   
    IEN2 |= 0x2;     //允许P2口中断;
    P2IFG = 0x00;    //初始化中断标志位
    EA = 1;          //打开总中断
}

使用特权

评论回复
15
gwsan|  楼主 | 2019-8-1 14:00 | 只看该作者
/**
  * @brief     系统工作模式选择函数
  * @param     None
  * @retval    None
  * @attention
  *            para1  0         1        2        3                                                                       
  *            mode         PM0        PM1        PM2        PM3                                                                                                       
  */
void SysPowerMode(uchar mode)
{
    if(mode > 0 && mode < 4)
    {  
        SLEEPCMD |= mode;    //设置系统睡眠模式
        PCON = 0x01;         //进入睡眠模式 ,通过中断唤醒
    }
    else
        PCON = 0x00;         //主动/空闲模   通过中断唤醒系统
}

/**
  * @brief     中断处理函数-系统唤醒
  * @param     None
  * @retval    None
  */
#pragma vector = P2INT_VECTOR   
__interrupt void P2_ISR(void)
{
    if(P2IFG > 0)
    {
        P2IFG = 0;           //清标志位
    }
   
    P2IF = 0;
    SysPowerMode(4);         //正常工作模式
}

使用特权

评论回复
16
gwsan|  楼主 | 2019-8-1 14:01 | 只看该作者
2.6.实验现象
在工作情况下,LED1 闪烁三次后,系统进入睡眠,按下KEY2后唤醒中断。

附:管理睡眠定时器的寄存器类型
●ST2 –睡眠定时器 2
●ST2 –睡眠定时器 2
●ST1 –睡眠定时器 1
●ST0 –睡眠定时器 0
●STLOAD –睡眠定时器加载状态
●STCC –睡眠定时器捕获控制
●STCS –睡眠定时器捕获状态
●STCV0 –睡眠定时器捕获值字节 0
●STCV1 –睡眠定时器捕获值字节 1
●STCV2 –睡眠定时器捕获值字节 2

使用特权

评论回复
17
parameters| | 2019-8-6 14:45 | 只看该作者
感谢楼主分享!学习一下

使用特权

评论回复
18
gwsan|  楼主 | 2019-9-9 14:46 | 只看该作者
希望能帮到你

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

69

主题

3434

帖子

1

粉丝