概要
バッテリを用いるアプリケーションで、非稼働時にCPUのモードを変更して消費電力を低減する事が可能です。dsPIC33Cの場合は「Dozeモード」「Idleモード」「Sleepモード」の3つのモードがあり(fig.1)のような動作の違いがあります。
| モード | 消費電流 | クロック | CPU | 復帰 |
| DOZE | 中 | システムクロック = 動作 LPRCクロック = 動作 | 速度低下 | DOZENビットクリア 割り込み発生時 (ROIビットセット時) |
| IDLE | 小 | システムクロック = 動作 LPRCクロック = 動作 | 停止 | WDT デバイスリセット 有効な割り込み |
| SLEEP | 最小 | システムクロック = 停止 LPRCクロック = 動作 (WDTが有効な場合) | 停止 | WDT デバイスリセット 有効な割り込み |
また他に消費電力を低減させる方法として使わない周辺機能(ペリフェラル)をPMD(Peripheral module Disable)レジスタでOFFにする方法があります。
PMDとはPeripheral module Disableの略でペリフェラル毎に細かく電源ON/OFFをする機能
ハードウェア構成と制御ブロック
◆Idleモード、Sleepモードの場合
SW1を押すとパワーセーブモードに入ります。今回パワーセーブモードを解除するためにCLCモジュールとUARTモジュールを用います。パワーセーブ時にパソコンから適当に文字を送信するとRP58ピンのレベルが変化しますので、これをCLC1モジュールに入力するとパワーセーブが解除できます。
◆Dozeモードの場合
SW1を押すたびにDozeモードとActiveモードが切り替わります。

ソースコード
下記のマクロの値を「PS_ACTIVE」「PS_SLEEP」「PS_IDLE」「PS_DOZE」のいづれかに書き換えると各パワーセーブモードの動作を検証できます
#define PS_MODE
コンフィグレーション設定についてはコンフィグレーション設定に記載しております。
コピーして下記のソースコードの「 //ここにコンフィグレーション設定を挿入する// 」の位置に挿入してください。
クロック設定用関数 vds_Main_Init_Clock_Register(); のソースコードはクロック設定のページに記載しております。
コピーして下記のソースコードの「 //ここにクロック設定ソースをコピペする// 」の位置に挿入してください。
/*--------------------------------------------------------------------------------*/
/* @file CHAPTER_2_9_2_SLLEP_WAKE */
/* @brief パワーセーブモード */
/*--------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------*/
/* コンフィグレーション設定*/
/*--------------------------------------------------------------------------------*/
//ここにコンフィグレーション設定を挿入する//
/*--------------------------------------------------------------------------------*/
/* インクルードファイル*/
/*--------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
/*--------------------------------------------------------------------------------*/
/* 定数定義*/
/*--------------------------------------------------------------------------------*/
#define BRINK_PERIOD 2000000
#define PS_ACTIVE 0x0000 //110mA
#define PS_SLEEP 0x0001 //60mA
#define PS_IDLE 0x0002 //85mA
#define PS_DOZE 0x0003 //80mA
#define PS_MODE PS_SLEEP
/*--------------------------------------------------------------------------------*/
/* クロック設定 */
/*--------------------------------------------------------------------------------*/
//ここにクロック設定ソースを挿入する//
/*--------------------------------------------------------------------------------*/
/* Main関数 */
/*--------------------------------------------------------------------------------*/
int main(int argc, char** argv)
{
unsigned long u4_Count = BRINK_PERIOD;
/*----------------------------------------------------------------------------*/
/* クロック初期化*/
/*----------------------------------------------------------------------------*/
vds_Main_Init_Clock_Register(); /* クロック初期化 */
/*----------------------------------------------------------------------------*/
/* GPIO初期化*/
/*----------------------------------------------------------------------------*/
TRISA = 0xFFFF;
TRISB = 0xFFFF;
TRISC = 0xFFFF;
TRISD = 0xFFFF;
TRISE = 0xFFFF;
TRISEbits.TRISE0 = 0u; /* LED1ピンはデジタル出力ピン */
TRISEbits.TRISE7 = 1u; /* SLEEPピン */
RPOR13bits.RP59R = 1u; /* RP59ピン出力機能選択ビット */
RPINR45bits.CLCINAR = 58u; /* CLC1 */
RPOR17bits.RP67R = 40; /* RD3 = CLC1out */
/*---------------------------------------------------------------------------*/
/* CLC1*/
/*---------------------------------------------------------------------------*/
CLC1SEL = 0x0100u;
CLC1SELbits.DS1 = 0u; /* CLCINA */
CLC1CONH = 0x0000u;
CLC1CONHbits.G2POL = 1u;
CLC1GLSL = 0x0002u;
CLC1GLSLbits.G1D1T = 1u;
CLC1GLSH = 0x0000u;
CLC1CONL = 0x0000u;
CLC1CONLbits.MODE = 0u; /*AND or*/
CLC1CONLbits.LCOE = 1u; /* 出力有効化 */
CLC1CONLbits.INTP = 1u; /* 立ち上がり割り込み許可 */
CLC1CONLbits.INTN = 1u; /* 立ち上がり割り込み許可 */
CLC1CONLbits.LCEN = 1u; /* モジュール有効化 */
INTCON2bits.GIE = 0;
/*----------------------------------------------------------------------------*/
/* メインルーチン*/
/*----------------------------------------------------------------------------*/
while(1)
{
if (u4_Count >(BRINK_PERIOD >> 1))
{
LATEbits.LATE0 = 1;
u4_Count --;
}
else if (u4_Count > 0)
{
LATEbits.LATE0 = 0;
u4_Count --;
}
else
{
u4_Count = BRINK_PERIOD;
}
#if (PS_MODE == PS_ACTIVE)
#elif (PS_MODE == PS_SLEEP)
if (PORTEbits.RE7 == 0)
{
IFS7bits.CLC1PIF = 0;
IEC7bits.CLC1PIE = 1;
LATEbits.LATE0 = 0;
Sleep();
IEC7bits.CLC1PIE = 0;
IEC11bits.CLC1NIE = 0;
}
#elif (PS_MODE == PS_IDLE)
if (PORTEbits.RE7 == 0)
{
IFS7bits.CLC1PIF = 0;
IEC7bits.CLC1PIE = 1;
LATEbits.LATE0 = 0;
Idle();
IEC7bits.CLC1PIE = 0;
IEC11bits.CLC1NIE = 0;
}
#elif (PS_MODE == PS_DOZE)
if (PORTEbits.RE7 == 0)
{
while(PORTEbits.RE7 == 0){;}
if (CLKDIVbits.DOZEN == 0)
{
CLKDIVbits.DOZE = 7;
CLKDIVbits.DOZEN = 1;
}
else
{
CLKDIVbits.DOZE = 0;
CLKDIVbits.DOZEN = 0;
}
}
#endif
}
}
結果
以下に各モードの消費電流を示します。ただメインマイコンのdsPIC33CHだけで無くオンボードデバッガ用のマイコンやLED等の消費電流も含みますので、参考程度に捉えて下さい。
| 条件 | 消費電流(mA) |
| Active | 110 |
| Sleep | 70 |
| Idle | 90 |
| Doze | 90 |
| 条件 | 消費電流(mA) |
| PMD All On | 105 |
| PMD All Off | 115 |


コメント