[ZigBee] 11、ZigBee之睡眠定時器二


 

1、前言

  上一節講了Zigbee的睡眠定時器利用外部按鍵使系統從休眠態喚醒到工作態,其核心在於:

   61 void SysPowerMode(uchar mode) 
   62 { 
   63     if(mode > 0 && mode < 4) 
   64     {  
   65         SLEEPCMD |= mode;    //設置系統睡眠模式 
   66         PCON = 0x01;         //進入睡眠模式 ,通過中斷喚醒
   67     } 
   68     else 
   69         PCON = 0x00;         //主動/空閑模   通過中斷喚醒系統 
   70 }

  其中參數mode表示電源管理系統中的PM1、PM2、PM3、全功能模式,上節只對這幾種模式做簡單的介紹,本節將詳細介紹電源管理部分,而后分析基於Zigbee休眠定時器實現的周期性休眠喚醒工程。

 

2、低功耗電源管理概述

  一個具有低功耗運行的系統,其實現往往是利用在不同情況下切換為不同電源模式來實現的。各種運行模式指的是主動模式、空閑模式和供電模式1、2 和3(PM1-PM3)。而超低功耗一般通過關閉對模塊的供電來減少靜態功耗,以及使用門控時鍾和關閉振盪器來降低動態功耗。

 

3、電源管理系統介紹

  不同的操作模式或者供電模式使系統低功耗運行成為了可能,如果想追求超低功耗,可以通過關閉對模塊的供電來減小靜態功耗,或者使用時鍾門控,以及關閉晶振來減少動態功耗。

  active mode\idle mode\PM1\PM2\PM3被稱為operating模式(power模式)。Active mode是正常運行模式,PM3模式擁有最低的功耗,他們的區別見下表:

 

 

  Active mode: 全功能模式,穩壓器的數字內核開啟,要么16MHz的RC振盪器要開啟、要么32MHz的晶體振盪器要開啟、要么兩者都開啟;要么32kHz的RCOSC開啟、要么32kHz的XOSC要開啟。

  Idle mode: 空閑模式-除了CPU內核停止運行之外,其他和active mode一樣

  PM1: The voltage regulator to the digital part is on. Neither the 32 MHz XOSC nor the 16 MHz RCOSC is running. Either the 32 kHz RCOSC or the 32 kHz XOSC is running. The system goes to active mode on reset, an external interrupt, or when the Sleep Timer expires.(處於PM1模式系統重新變為active mode要么reset,要么外部中斷觸發,要么Sleep timer溢出)

  PM2: The voltage regulator to the digital core is turned off. Neither the 32 MHz XOSC nor the 16 MHz RCOSC is running. Either the 32 kHz RCOSC or the 32 kHz XOSC is running. The system goes to active mode on reset, an external interrupt, or when the Sleep Timer expires.

  PM3: The voltage regulator to the digital core is turned off. None of the oscillators is running. The system goes to active mode on reset or an external interrupt.

 

  POR在PM2/PM3模式下是Active的,但是BOD卻是Power Down的,這給電源管理造成了限制。如果在PM2或者PM3模式下供電電壓小於1.4V,溫度高於70℃,並且然后重新進入主動模式之前,回到合適的運行電壓,寄存器和RAM在PM2/PM3 下保存的內容可能會改變。Hence, care should be taken in the design of the system power supply to ensure that this does not occur. 因為如果電壓低於大約1.7V 就觸發一個BOD 復位,所以電壓可以通過進入主動模式進行精確的定期監控。

 

3.1、主動和空閑模式

  Active mode is the fully functional mode of operation where the CPU, peripherals, and RF transceiver are active. The digital voltage regulator(數字穩壓器) is turned on.

  Active mode is used for normal operation.在active模式通過使能PCON.IDLE位 (SLEEPCMD.MODE = 0x00), CPU內核停止運行進入空閑模式. All other peripherals function normally, and any enabled interrupt wakes up the CPU core (to transition back from idle mode to active mode).

 

3.2、PM1模式

  In PM1, the high-frequency oscillators are powered down (32 MHz XOSC and 16 MHz RCOSC). The voltage regulator and the enabled 32 kHz oscillator are on. When PM1 is entered, a power-down sequence is run.

  當等待喚醒事件的預期時間相對較短(小於3ms),就要選用PM1模式,因為 PM1 uses a fast power-down/up sequence.

 

3.3、PM2模式

  PM2 具有較低的功耗。在PM2 下的上電復位時刻,外部中斷、所選的32 kHz 振盪器和睡眠定時器外設是活動的。I/O 引腳保留在進入PM2 之前設置的I/O 模式和輸出值。所有其它內部電路是掉電的。穩壓器也是關閉的。當進入PM2 模式,就運行一個掉電序列。

  當使用睡眠定時器作為喚醒事件,並結合外部中斷時,一般就會進入PM2 模式。相比較PM1,當睡眠時間超過3ms 時,一般選擇PM2。比起使用PM1,使用較少的睡眠時間不會降低系統功耗。

 

3.4、PM3模式

  PM3 用於獲得最低功耗的運行模式。在PM3 模式下,穩壓器供電的所有內部電路都關閉(基本上是所有的數字模塊,除了中斷探測和POR 電平傳感)。內部穩壓器和所有振盪器也都關閉。

  復位(POR 或外部)和外部I/O 端口中斷是該模式下僅有的運行的功能。I/O 引腳保留進入PM3 之前設置的I/O 模式和輸出值。復位條件或使能的外部IO 中斷事件將喚醒設備,使它進入主動模式(外部中斷從它進入PM3 的地方開始,而復位返回到程序執行的開始)。RAM 和寄存器的內容在這個模式下可以部分保留。PM3 使用和PM2 相同的上電/掉電序列。

  當等待外部事件時,使用PM3 獲得超低功耗。當睡眠時間超過3ms 時應該使用該模式。

 

4、電源管理控制

  所需的供電模式通過使用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。

  為了正確運行,設置PCON.IDLE 位的指令必須遵循某種方式。這一指令后面跟的第一條匯編指令的第一個字節不能放在4 字節邊界。而且,緩存不能禁用(見FCTL 寄存器描述的CM)。不遵守這一要求可能導致較高的電流消耗。只要遵守了這一要求,設置了PCON.IDLE 位的指令后面的第一條匯編指令在導致系統醒來的中斷的ISR 之前、但是系統醒來之后執行。如果這個指令是一個全局中斷禁用,后面可以跟醒來之后、但是在ISR 運行之前執行的代碼。

 

5、工程

code:

  1 /****************************************************************************
  2 * 文 件 名: main.c
  3 * 描    述: 設置定時器讓系統在設定的時間被喚醒,每次喚醒LED1閃爍3下提示用戶
  4 ****************************************************************************/
  5 #include <ioCC2530.h>
  6 
  7 typedef unsigned char uchar;
  8 typedef unsigned int  uint;
  9 typedef unsigned long ulong;
 10 
 11 #define LED1 P1_0            //P1.0口控制LED1
 12 
 13 
 14 /****************************************************************************
 15 * 名    稱: DelayMS()
 16 * 功    能: 以毫秒為單位延時 16M時約為535,系統時鍾不修改默認為16M
 17 * 入口參數: msec 延時參數,值越大,延時越久
 18 * 出口參數: 無
 19 ****************************************************************************/
 20 void DelayMS(uint msec)
 21 { 
 22     uint i,j;
 23     
 24     for (i=0; i<msec; i++)
 25         for (j=0; j<535; j++);
 26 }
 27 
 28 /****************************************************************************
 29 * 名    稱: InitLed()
 30 * 功    能: 設置LED燈相應的IO口
 31 * 入口參數: 無
 32 * 出口參數: 無
 33 ****************************************************************************/
 34 void InitLed(void)
 35 {
 36     P1DIR |= 0x01;           //P1.0定義為輸出口
 37     LED1 = 1;                //LED1燈上電默認為熄滅 
 38 }
 39 
 40 /****************************************************************************
 41 * 名    稱: SysPowerMode()
 42 * 功    能: 設置系統工作模式
 43 * 入口參數: mode等於0為PM0 1為PM1 2為PM2 3為PM3             
 44 * 出口參數: 無
 45 ****************************************************************************/
 46 void SysPowerMode(uchar mode) 
 47 { 
 48     if(mode < 4) 
 49     {  
 50         SLEEPCMD |= mode;    //設置系統睡眠模式 
 51         PCON = 0x01;         //進入睡眠模式 ,通過中斷喚醒
 52     } 
 53     else 
 54         PCON = 0x00;         //通過中斷喚醒系統 
 55 }
 56 
 57 /****************************************************************************
 58 * 名    稱: ST_ISR(void) 中斷處理函數 
 59 * 描    述: #pragma vector = 中斷向量,緊接着是中斷處理程序
 60 ****************************************************************************/
 61 #pragma vector = ST_VECTOR  62 __interrupt void ST_ISR(void)  63 {  64 STIF = 0; //清標志位  65 SysPowerMode(4); //進入正常工作模式  66 }  67 
 68 /****************************************************************************
 69 * 名    稱: SysPowerMode()
 70 * 功    能: 初始化休眠定時器,設定后經過指定時間自行喚醒
 71 * 入口參數:             
 72 * 出口參數: 無
 73 ****************************************************************************/
 74 void InitSleepTimer(void)  75 {  76 ST2 = 0x00;  77 ST1 = 0x00;  78 ST0 = 0x00;  79 EA = 1; //開中斷   80 STIE = 1; //睡眠定時器中斷使能 0: 中斷禁止 1: 中斷使能  81 STIF = 0; //睡眠定時器中斷標志 0: 無中斷未決 1: 中斷未決  82 }  83 
 84 /****************************************************************************
 85 * 名    稱: Set_ST_Period()
 86 * 功    能: 設置睡眠時間 
 87 * 入口參數: sec 睡眠時間             
 88 * 出口參數: 無
 89 ****************************************************************************/
 90 void Set_ST_Period(uint sec)  91 {  92 ulong sleepTimer = 0;  93  94 sleepTimer |= ST0;  95 sleepTimer |= (ulong)ST1 << 8;  96 sleepTimer |= (ulong)ST2 << 16;  97 sleepTimer += ((ulong)sec * (ulong)32768);  98 ST2 = (uchar)(sleepTimer >> 16);  99 ST1 = (uchar)(sleepTimer >> 8); 100 ST0 = (uchar) sleepTimer; 101 } 102 
103 
104 /****************************************************************************
105 * 程序入口函數
106 ****************************************************************************/
107 void main(void)
108 {   
109     uchar i=0;  
110       
111     InitLed();                 //設置LED燈相應的IO口     
112     InitSleepTimer();        //初始化休眠定時器
113     
114     while(1)
115     {
116         for (i=0; i<6; i++)  //LED1閃爍3次提醒用戶將進入睡眠模式
117         {
118             LED1 = ~LED1;
119             DelayMS(500);
120         }
121 
122         Set_ST_Period(5);   //設置睡眠時間,睡眠5秒后喚醒系統
123         SysPowerMode(2);    //重新進入睡眠模式PM2
124     }
125 }

其中SysPowerMode在上一節[ZigBee] 10、ZigBee之睡眠定時器講了SysPowerMode(uchar mode) 用於設置系統進入幾種模式,本節不額外說明。重點看SleepTimer的用法。

 

先看SleepTimer的初始化函數:在上一節中介紹一次定時器比較發生在定時器的值等於24位比較器的值,寄存器ST2:ST1:ST0可以用來設置比較器的值。 當STLOAD.LDRDY=1寫入ST0發起加載新的比較值。當STLOAD.LDRDY=0軟件不能開始一個新的加載,直到它為1。因此這里的76\77\78行用來設置比較器的值,然后開總中斷,開SleepTimer中斷,最后將睡眠中斷標志位清0。

 74 void InitSleepTimer(void) 75 { 76 ST2 = 0x00; 77 ST1 = 0x00; 78 ST0 = 0x00; 79 EA = 1; //開中斷 80 STIE = 1; //睡眠定時器中斷使能 0: 中斷禁止 1: 中斷使能 81 STIF = 0; //睡眠定時器中斷標志 0: 無中斷未決 1: 中斷未決 82 }

 

而Set_ST_Period比較簡單,就是將待設置的時間賦值給ST2、ST1和ST0,注意無論是初始化還是這里,在給STx賦值是都是需要最后給ST0賦值,在讀取STx值時都是要最先讀取ST0的值(這個為什么在上一節中有詳細介紹)

 90 void Set_ST_Period(uint sec) 91 { 92 ulong sleepTimer = 0; 93 94 sleepTimer |= ST0; 95 sleepTimer |= (ulong)ST1 << 8; 96 sleepTimer |= (ulong)ST2 << 16; 97 sleepTimer += ((ulong)sec * (ulong)32768); 98 ST2 = (uchar)(sleepTimer >> 16); 99 ST1 = (uchar)(sleepTimer >> 8); 100 ST0 = (uchar) sleepTimer; 101 }

 

這樣整個工程就比較容易理解了:main函數開始初始化LED和睡眠定時器,然后在while大循環里面先LED閃爍3次,然后調用睡眠周期設置設置5s,此時睡眠定時器開始計時,而main函數由於執行到設置系統進入PM2模式而休眠,當5s后觸發休眠定時器中斷,在中斷中設置系統進入active模式。

 

 

Zigbee系列文章:

[ZigBee] 1、 ZigBee簡介

[ZigBee] 2、 ZigBee開發環境搭建

[ZigBee] 3、ZigBee基礎實驗——GPIO輸出控制實驗-控制Led亮滅

[ZigBee] 4、ZigBee基礎實驗——中斷

[ZigBee] 5、ZigBee基礎實驗——圖文與代碼詳解定時器1(16位定時器)(長文)

[ZigBee] 6、ZigBee基礎實驗——定時器3和定時器4(8 位定時器)

[ZigBee] 7、ZigBee之UART剖析(ONLY串口發送)

[ZigBee] 8、ZigBee之UART剖析·二(串口收發)

[ZigBee] 9、ZigBee之AD剖析——AD采集CC2530溫度串口顯示

[ZigBee] 10、ZigBee之睡眠定時器

 

 

PS:如果您覺得還不錯,點個贊,讓更多人受益~

@beautifulzzzz 2016-07-18 continue~  
e-mail:beautifulzzzz@qq.com 
sina:http://weibo.com/beautifulzzzz?is_all=1

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM