zigbee笔记:七、zigbee系统电源管理与睡眠唤醒

        zigbee的低功耗、近距离无线传输的特点使得其在一众近距离无线传输方案中备受青睐。而zigbee低功耗优势是通过根据不同工况选择运行在不同的运行模式(供电模式)实现的,因此,掌握zigbee的系统电源管理与睡眠唤醒的相关知识,是对zigbee进行优势开发的重中之重。本文将根据开发经验和网络相关资料进行详解解读,也欢迎指正。(声明:本文为总结性文章,内容有大量引用其他博主的内容,末尾有参考链接声明)

一、zigbee的电源管理模式

        zigbee cc2530是一种集成了Zigbee通信协议的芯片,通过不同的运行模式(电源模式)可以实现低功耗的操作。运行模式有主动模式、空闲模式和供电模式 1、2 和 3(PM1-PM3),各自特点如下图:

        (1)主动模式:即完全功能的运行模式,也是复位设备默认运行模式,数字稳压器为开启状态,CPU、外设和 RF 收发器都是活动的,高 频 晶 振 ( 16M 或 者 32M ) 和 低 频 晶 振 ( 32.768KRCOSC/XOSC )全部工作, 数字处理模块正常工作。在该模式下cc2530可以充当Zigbee网络中的协调器(Coordinator)、路由器(Router)或终端设备(End Device)。

        (2)空闲模式:除了 CPU 内核停止运行(即空闲),其他和主动模式一样。在主动模式(SLEEPCMD.MODE = 0x00)通过使能 PCON.IDLE 位,CPU 内核就停止运行,进入空闲模式。所有其他外设将正常工作,且 CPU 内核将被任何使能的中断唤醒(从空闲模式转换到主动模式)。

        (3)PM1模式:低功耗模式1(Power Mode 1)。在PM1模式下,稳压器的数字部分开启。32 MHz XOSC 和 16 MHz RCOSC 都不运行。32 kHz RCOSC 或 32 kHz XOSC运行。复位、外部中断或睡眠定时器过期时系统将转到主动模式。该模式下cc2530的主要功能是接收和处理数据,但其无线电部分处于关闭状态,以降低功耗。这种模式适用于需要在较短时间内接收数据的应用场景。

        (4)PM2模式:低功耗模式2(Power Mode 2)。在PM2模式下,稳压器的数字内核关闭。32 MHz XOSC 和 16 MHz RCOSC 都不运行。32kHz RCOSC 或 32 kHz XOSC运行。复位、外部中断或睡眠定时器过期时系统将转到主动模式。该模式下cc2530,I/O 引脚保留在进入PM2 之前设置的I/O 模式和输出值,无线电部分处于关闭状态,同时大部分的功能也被禁用,以进一步减少功耗。这种模式适用于需要长时间处于待机状态,但偶尔需要唤醒进行一些处理的应用场景。

        (5)PM3模式:休眠模式(Power Mode 3)。在PM3模式下,获得最运行低功耗,稳压器的数字内核关闭,所有的振荡器都不运行,复位或外部中断时系统将转到主动模式。该模式下cc2530,I/O 引脚保留进入PM3 之前设置的I/O 模式和输出值,其他所有功能都被禁用,包括无线电部分。在这种模式下,cc2530需要外部触发来唤醒并重新启动其功能。这种模式适用于需要极低功耗且只偶尔需要进行通信的应用场景。

二、如何切换电源管理

        上一节,我们已经了解zigbee cc2530具有五中工作模式,各自拥有不同的特点,根据运行工况进行选择切换,实现低功耗方案设计。那么如何进行电源模式的切换管理,供电模式通过使用 SLEEPCMD 控制寄存器的 MODE 位和 PCON寄存器的IDLE 位来选择。

1、控制寄存器

首先,我们认识系统电源管理的两个寄存器:

2、切换电源模式与唤醒

        进行电源模式的切换管理很简单,分两步走:

        (1)首先,通过使用SLEEPCMD 控制寄存器的MODE 位选择系统电源模式;

        (2)使能SFR 寄存器的PCON.IDLE 位(设置为1),进入SLEEPCMD.MODE 所选的模式。

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

示例函数:

void SysPowerMode(char mode) 
 { 
     if((mode > 0)&&(mode < 4)) 
    {  
         SLEEPCMD |= mode;    //设置系统睡眠模式 
         PCON = 0x01;         //进入睡眠模式 ,通过中断唤醒
     } 
     else 
         PCON = 0x00;         //通过中断唤醒系统 
 }

三、案例讲解

1、中断唤醒

        初始设置系统为PM3电源模式,然后通过外部中断的方式,使得电源模式恢复(唤醒)主动模式。实验现象:LED1闪烁3次后进入睡眠状态,通过按下按键S1产生外部中断进行唤醒,重新进入主动模式,LED1闪烁3次后又进入睡眠状态。

//该代码基于作者的zigbee设备编写
//移植使用注意修改LED和按键的对应节点

#include <iocc2530.h>


#define LED1 P1_0

//  初始化LED1对应P1_0
void initLED1_P1_0()
{
    P1SEL &= ~0x01;
    P1DIR |= 0x01;
    P1_0 = 1;
}

//初始化一个按键KEY1中断
void initInterrupt()
{
    P0SEL &= 0xfd;  //中断口是P0_0
    P0DIR &= 0xfd;
    P0INP &=  0xfd;
    P2INP &=  0xdf;
    EA = 1;
    P0IE = 1;
    P0IEN |= 0x02;
    PICTL |= 0x01;
}

//延时函数
void delayms( unsigned int a )  //@16MHz
{
    unsigned char i, j;
    for( int s = 0; s < a; s++ )
    {
        i = 3;
        j = 148;
        do
        {
            while( --j );
        }
        while( --i );
    }
}
//  设置系统工作模式函数
void SysPowerMode( char mode )
{
    if( ( mode > 0 ) && ( mode < 4 ) )
    {
        SLEEPCMD |= mode;    //设置系统睡眠模式
        PCON = 0x01;         //进入睡眠模式 ,通过中断唤醒
    }
    else
    {
        PCON = 0x00;    //通过中断唤醒系统
    }
}

#pragma vector=P0INT_VECTOR
__interrupt void P0_INT( void )
{
    if( P0IFG & 0x02 )
    {
        SysPowerMode( 4 );
    }
    P0IFG = 0;
    P0IF = 0;
}

void main()
{
    char count = 0;
    initInterrupt();     //初始化一个按键中断
    initLED1_P1_0(); //  初始化一个LED
    while( 1 )
    {
       if( count > 10 )  {
         count = 0;
        }
        LED1 = ~LED1;
        if( ++count >= 6 )
        {
            count = 0;
            SysPowerMode( 3 ); //3次闪烁后进入睡眠状态PM3,等待按键S1中断唤醒
        }
        delayms( 800 );
    }
}


2、睡眠定时中断唤醒

        电源模式恢复(唤醒)为主动模式的另一种方法是定时中断唤醒,需要使用到睡眠定时器。我们先来了解睡眠定时器。这里简单只讲解睡眠定时器的比较模式用法,更详细讲解阅读参考链接(3)。

        2.1 睡眠定时器

         睡眠定时器用于设置系统进入和退出低功耗睡眠模式之间的周期。还用于当系统进入低功耗模式后,维持 MAC 定时器(T2)的定时。其特性如下:

        (1)长达 24 位定时计数器,运行在 32.768KHZ 的工作频率;

        (2)24 位的比较器具有中断和 DMA 触发功能在 PM2 低功耗模式下运行(PM3模式下振荡器全部被关闭,无法使用睡眠定时器唤醒)

        (3)定时器的当前值可以从 SFR 寄存器 ST2:ST1:ST0 中读取

        2.2  睡眠定时器寄存器

           睡眠定时器(T2)工作模式仍然有捕获和比较两种。通过如下寄存器控制。

        2.3 睡眠定时器比较模式

        睡眠定时器在复位之后立即启动,如果没有中断就继续运行。当定时器的值等于 24 位比较器的值,就发生一次定时器比较。通过写入寄存器 ST2:ST1:ST0 来设置比较值。

        寄存器 ST0、ST1、ST2分别对应着定时器的值等于 24 位比较器的低、中、高位,如何写值?定义一个32位的变量,通过移位的方式进行,如下:

//在给STx赋值是都是需要最后给ST0赋值,在读取STx值时都是要最先读取ST0的值

void Set_ST_Period(uint sec) 
{ 
   UINT32 sleepTimer = 0; //定义一个32位的变量
//注意:读取ST2:ST1:ST0的值,建议读取顺序ST0、ST1、ST2
   sleepTimer |= ST0;  //读取ST0的值,写入sleepTimer的[0:7]位
   sleepTimer |= (UINT32)ST1 <<  8; //读取ST1的值,写入sleepTimer的[8:15]位
   sleepTimer |= (UINT32)ST2 << 16; //读取ST2的值,写入sleepTimer的[16:24]位

   sleepTimer += ((UINT32)sec * (UINT32)32768); 
//当 STLOAD.LDRDY 是 1 写入 ST0 后,会发起加载最新的比较值,ST2、ST1 和 ST0 寄存器的最新的值。
//注意:写入ST2:ST1:ST0的值,写入顺序必须为ST2、ST1、ST0
   ST2 = (UINT8)(sleepTimer >> 16); //将sleepTimer的[16:24]位的值,写入ST2
   ST1 = (UINT8)(sleepTimer >> 8); //将sleepTimer的[8:15]位的值,写入ST1
   ST0 = (UINT8) sleepTimer; //将sleepTimer的[0:7]位的值,写入ST0
}

        2.4睡眠定时器唤醒

        通过设置定时器在特定时间内进行唤醒,重新进入工作模式,每次唤醒LED2闪烁3下。


 
#include <ioCC2530.h>
 
#define uint unsigned int
#define uchar unsigned char
 
#define UINT8 unsigned char
#define UINT16 unsigned int
#define UINT32 unsigned long
 
//定义控制LED灯的端口
 
#define LED1 P1_0             //定义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--);
}
/****************************
//初始化LED1对应P1_0
*****************************/
  
void initLED1_P1_0()
{
    P1SEL &= ~0x01;
    P1DIR |= 0x01;
    P1_0 = 1;
}
 
/**************************************************************** 
系统工作模式选择函数            
* 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 = 0X00; 
  ST0 = 0X00; 
  EA = 1;  //总开中断 
  STIE = 1; //睡眠定时器中断使能
  STIF = 0; //睡眠定时器中断标志清零
}
 
/********************************************************************* 
//设置睡眠时间 
*********************************************************************/ 
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;        
  initLED1_P1_0();        //调用初始化LED1函数    
  Init_SLEEP_TIMER();    //初始化SLEEPTIMER
  while(1)
  {
  
      for(i=0;i<6;i++) //闪烁3下
      {
        LED1=~LED1;
        Delayms(200);
      }
      Set_ST_Period(3); //重新进入睡眠模式
      SysPowerMode(2);   //进入PM2低频晶振模式
  
  }
}
//中断唤醒
#pragma vector = ST_VECTOR 
 __interrupt void ST_ISR(void) 
 { 
   STIF = 0;          //清标志位
   SysPowerMode(4);   //进入正常工作模式
 }

        main函数开始初始化LED和睡眠定时器,然后在while大循环里面先LED闪烁3次,然后调用睡眠周期设置设置3s,此时睡眠定时器开始计时,而main函数由于执行到设置系统进入PM2模式而休眠,当5s后触发休眠定时器中断,在中断中设置系统进入active模式。

参考链接:

(1)lesson4(Zigbee补充2)CC2530睡眠唤醒(详解)_cc2530休眠与唤醒-CSDN博客

(2)ZigBee基础实验(九)--定时器二_zigbee看门狗的唤醒定时器唤醒定时器彭20控制-CSDN博客

(3)ZigBee基础实验(八)--定时器一_zigbee定时器实验代码-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/792038.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

发挥储能系统领域优势,海博思创坚定不移推动能源消费革命

随着新发展理念的深入贯彻&#xff0c;我国正全面落实“双碳”目标任务&#xff0c;通过积极转变能源消费方式&#xff0c;大幅提升能源利用效率&#xff0c;实现了以年均约3.3%的能源消费增长支撑了年均超过6%的国民经济增长。这一成就的背后&#xff0c;是我国能源结构的持续…

c#调用c++ dll库报错System.BadImageFormatException

System.BadImageFormatException:“试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)” 1. dll需要选择release模式进行编译 2.选择相同位数&#xff0c;比如x64平台&#xff0c;c#也需要x64 3.不要设置c#不支持的函数供调用 比如&#xff1a; c可以输出到控制台…

昇思学习打卡-16-热门LLM及其他AI应用/K近邻算法实现红酒聚类

文章目录 算法原理距离定义模型构建 算法原理 K近邻算法可以用在分类问题和回归问题上&#xff0c;它的原理如下&#xff1a;要确定一个样本的类别&#xff0c;可以计算它与所有训练样本的距离&#xff0c;然后找出和该样本最接近的k个样本&#xff0c;统计出这些样本的类别并…

中职综合布线实训室

一、中职综合布线实训室建设背景 在数字化转型的大潮中&#xff0c;计算机网络技术作为支撑数字中国建设的基石&#xff0c;其重要性不言而喻。面对汹涌而来的数字时代&#xff0c;中等职业学校&#xff08;简称中职&#xff09;作为技术技能型人才培养的重要基地&#xff0c;…

如何使用Vger对已经过身份验证的Jupyter实例进行安全检测

关于Vger Vger是一款功能强大的交互式命令行应用程序&#xff0c;广大研究人员可以利用Vger与已经过身验证的Jupyter实例进行交互&#xff0c;并对其执行人工智能或机器学习方面的安全检测操作。 使用场景 1、作为红队研究人员&#xff0c;当我们寻找到了Jupyter凭证之后&…

单例模式的简单理解

单例模式 前言一、单例模式是什么二、单例模式的使用饿汉模式单线程下的懒汉模式多线程下的懒汉模式&#xff08;优化懒汉模式&#xff09;加锁 三、总结 前言 设计模式是将一些经典的问题场景进行整合归纳&#xff0c;并提供一些解决方案&#xff0c;相当于一种“套路”。 熟…

政企单位光纤资源高效管理与优化策略

引言 随着信息技术的飞速发展&#xff0c;政企单位对于通信基础设施的管理要求日益提高。然而&#xff0c;传统的管理模式&#xff0c;如Excel表格记录和纸质审批流程&#xff0c;已难以满足当前复杂多变的业务需求。在此背景下&#xff0c;我们实施了光纤管理的数字化转型项目…

LLMs的基本组成:向量、Tokens和嵌入

编者按&#xff1a;随着人工智能技术的不断发展&#xff0c;大模型&#xff08;语言、视觉&#xff0c;或多模态模型&#xff09;已成为当今AI应用的核心组成部分。这些模型具有处理和理解自然语言等模态输入的能力&#xff0c;推动了诸如聊天机器人、智能助手、自动文本生成等…

防火墙安全策略练习

实验拓扑 实验要求 1.DMZ区内的服务器&#xff0c;办公区仅能在办公时间内&#xff08;9&#xff1a;00 — 18&#xff1a;00&#xff09;可以访问&#xff0c;生产区的设备全天可以访问 2.生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网 3.办公区设备10.…

C++初学者指南-5.标准库(第一部分)--顺序视图

C初学者指南-5.标准库(第一部分)–顺序视图 文章目录 C初学者指南-5.标准库(第一部分)--顺序视图std::string_view (C17)避免不必要的内存分配类似字符串的函数参数创建string_viewsstring_view接口 std::span &#xff08;C20&#xff09;作为参数&#xff08;主要用例&#x…

笔记本硬盘数据恢复的6种方法!简单易懂

可以从笔记本电脑硬盘恢复已删除的数据吗&#xff1f; “我不小心删除了笔记本电脑硬盘上的重要数据。请问我可以在笔记本电脑硬盘上恢复已删除的数据吗&#xff1f;如果可以&#xff0c;我应该怎么做才能恢复数据呢&#xff1f;” 很多笔记本电脑用户可能会不小心地从电脑中…

翻译|解开LLMs的神秘面纱:他们怎么能做没有受过训练的事情?

大语言模型&#xff08;LLMs&#xff09;通过将深度学习技术与强大的计算资源结合起来&#xff0c;正在彻底改变我们与软件互动的方式。 虽然这项技术令人兴奋&#xff0c;但许多人也担忧LLMs可能生成虚假的、过时的或有问题的信息&#xff0c;他们有时甚至会产生令人信服的幻…

顶顶通呼叫中心中间件-打电话没声音检查步骤(mod_cti基于FreeSWITCH)

顶顶通呼叫中心中间件-电话没声音检查步骤(mod_cti基于FreeSWITH) 检查步骤 1、检查配置文件 检查配置文件&#xff1a;打开ccadmin -> 配置文件 -> vars -> external_ip$${local_ip_v4}看一下这个有没有配置正确的外网IP&#xff0c;如果没有配置正确就需要配置正…

方格验证码输入框实现方式

引言 在实际开发过程中验证码输入框是一个很常见UI界面。通常来讲有简单的输入框&#xff0c;也有方格的输入框&#xff0c;其中相对较为棘手就是这种方格输入框里面还需要显示光标的情况。本篇博客我们就来主要讨论一下方格带光标的验证码输入框样式。 实现方案 在着手实现…

顺序结构 ( 六 ) —— 顺序结构实例 【互三互三】

&#x1f680;欢迎互三&#x1f449;&#xff1a;程序猿方梓燚 &#x1f48e;&#x1f48e;&#x1f680;所属专栏&#xff1a;C教程&#x1f48e; &#x1f680;关注博主&#xff0c;后期持续更新系列文章 &#x1f680;如果有错误感谢请大家批评指出&#xff0c;及时修改 &am…

什么是RLHF(基于人类反馈的强化学习)?

什么是RLHF&#xff08;基于人类反馈的强化学习&#xff09;&#xff1f; 基于人类反馈的强化学习&#xff08;Reinforcement Learning from Human Feedback, RLHF&#xff09;是一种结合强化学习和人类反馈的技术&#xff0c;用于训练智能体&#xff0c;使其行为更符合人类期…

农牧行业CRM洞察:打造营、销、服一体化数字营销平台

01、行业应用背景 保持企业活力&#xff0c;支撑业务单元协调发展&#xff0c;稳定核心产品竞争力&#xff0c;将成为农牧行业企业数字化、数智化建设的指导方向。 积极发挥数据在生产、流通、消费各个环节的决策支撑&#xff0c;为农牧企业特别是多业态集团型企业&#xff0…

1.浅谈蓝牙BLE的总体框架

这里只展开BLE这一部分&#xff0c; 框图如下所示 蓝牙也是使用分层的结构组织代码。 Application&#xff1a;是自己的业务逻辑实现的地方。当然应用程序需要根据BLE的规定&#xff0c;实现配置文件&#xff08;profile&#xff09;、服务&#xff08;service&#xff09;和…

【话题】开源项目:从边缘到主流的转变之旅

目录 开源项目有哪些机遇与挑战&#xff1f; 前言 宏观视角&#xff1a;开源项目的发展趋势 开源运动&#xff0c;作为一股不可忽视的创新力量&#xff0c;正在重塑全球科技版图。其核心价值在于打破知识的壁垒&#xff0c;推动技术的民主化&#xff0c;让信息与技术不再为少…

C++ :内联函数inline|nullptr

欢迎来到HarperLee的学习笔记&#xff01; 博主主页传送门&#xff1a;HarperLee博客主页&#xff01; 欢迎交流学习&#xff01; 一、inline关键字 1.1 什么是内联函数&#xff1f; 内联函数&#xff1a;用** inline 修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用…