PIC16F18346の基本動作から応用プログラムまでを学びます。

ホーム
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
    
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
省電力動作
2020-06-19

省電力モードの目的は、消費電力を削減することで、このモードには、Dozeモードと Sleepモードと Idleモードがあります。

Dozeイネーブル(DOZEN)ビットがセットされている場合(DOZEN = 1)、CPUは、DOZE モードになります。
CPUDOZEレジスタのアイドルイネーブル(IDLEN)ビットがクリア(IDLEN = 0)状態で、SLEEP命令を実行すると SLEEP モードになります。IDLENビットがセット(IDLEN = 1)状態で、SLEEP命令が実行されると、CPUは IDLE モードになります。

8.1 Doze (ドーズ) モード

Dozeモードでは、周辺機器の動作に影響を与えることなく、CPU動作とプログラムメモリアクセスを削減することにより、電力を節約できます。Dozeモードは SLEEP モードとは異なり、システムオシレータは引き続き動作しますが、CPUとプログラムメモリのみが影響を受けます。命令実行の削減により、CPUとメモリ内の不要な動作が排除され、電力が節約されます。

Dozeイネーブル(DOZEN)ビットがセットされている場合(DOZEN = 1)、CPUは、CPUDOZEレジスタのDOZE <2:0>ビットで定義されているNサイクルごとに1命令サイクルのみ実行します。たとえば、DOZE <2:0> = 100の場合、命令サイクル比は1:32です。CPUとメモリは1命令サイクル実行すると、その後の31命令サイクルはアイドル状態になります。アイドルサイクル中でも、ペリフェラルはシステムクロック速度で動作し続けます。

8.1.2 Doze中の割り込み

割り込みが発生し、割り込み時にRecover-on-Interrupt(ROI)ビットがクリアされている(ROI = 0)場合、割り込みサービスルーチン(ISR)はDOZE <2:0>で選択されたレートで実行を継続します。 割り込みレイテンシ(遅延)は、DOZE <2:0>比率で延長となります。

割り込みが発生し、割り込み時にROIビットがセットされている場合(ROI = 1)、DOZENビットはクリアされ、CPUはフルスピードで実行されます。プリフェッチされた命令が実行された後、割り込みベクタシーケンスが実行されます。図8-1では、Doze期間の2番目の命令サイクル中に割り込みが発生し、すぐにCPUがDozeから抜け出します。Doze-on-Exit(DOE)ビットがセットされている(DOE = 1)場合、RETFIE動作の実行時にDOZENがセットされ、CPUはDOZE <2:0>比率に基づいて低減されたレートに戻り実行します。

8.2 SLEEP モード

CPUDOZEレジスタのアイドルイネーブル(IDLEN)ビットがクリア(IDLEN = 0)状態で、SLEEP命令を実行すると SLEEP モードになります。IDLENビットがセット(IDLEN = 1)状態で、SLEEP命令が実行されると、CPUは IDLE モードになります。

SLEEP モードでは、次の状態になります。

  1. WDTはクリアされますが、スリープ中の動作が有効になっている場合は実行し続けます
  2. STATUSレジスタのPDビットがクリアされる
  3. STATUSレジスタのTOビットがセットされる
  4. CPUクロックが無効になる
  5. 31 kHz LFINTOSC、HFINTOSCおよびSOSCは影響を受けず、これらを使用する周辺機器はスリープ状態でも動作を継続できる
  6. 選択したTimer1クロックソースが次の場合、Timer1およびそれを使用する周辺機器はスリープ状態で動作し続ける
  7. 専用ADCRC発振器が選択されている場合、ADCは影響を受けない
  8. I/Oポートは、SLEEP前の状態を維持する(高、低、または高インピーダンス駆動)
  9. WDT以外のリセットは SLEEP モードの影響を受けない

スリープ中の周辺機器動作の詳細については、個々の章を参照してください。

電流消費を最小限に抑えるには、次の項目を検討する必要があります。

ハイインピーダンス入力であるI/Oピンは、フローティング入力によって引き起こされるスイッチング電流を回避するために、外部でVDDまたはVSSに固定する必要があります。

電流が流れだす可能性のある内部回路には、DACやFVRモジュールなどが含まれます。これらのモジュールの詳細は、各セクションを参照してください。

8.2.1 スリープからのウェイクアップ

デバイスは、次のいずれかのイベントによってスリープからウェイクアップできます。

  1. MCLRピンの外部リセット入力(有効な場合)
  2. BORリセット(有効な場合)
  3. PORリセット
  4. ウォッチドッグタイマー(有効な場合)
  5. 外部割り込み
  6. スリープ中に実行可能なペリフェラルによる割り込み

最初の3つのイベントにより、デバイスはリセットされます。後の3つのイベントは、プログラム実行の継続と見なされます。デバイスのリセットまたはウェイクアップイベントが発生したかどうかを確認するには、セクション5.11「リセットの原因の特定」を参照してください。

SLEEP命令の実行中、次の命令(PC + 1)がプリフェッチされます。デバイスが割り込みイベントによってウェイクアップするには、対応する割り込みイネーブルビットを有効にする必要があります。ウェイクアップは、GIEビットの状態に関係なく発生します。
GIEビットが無効(GIE = 0)な場合、デバイスはSLEEP命令の後の命令で実行を継続します。
GIEビットが有効(GIE = 1)な場合、デバイスはSLEEP命令の直後の命令を実行し、デバイスは割り込みサービスルーチンを呼び出します。

重要:SLEEP命令の直後の命令の実行が望ましくない場合、ユーザーはSLEEP命令の直後に NOP を置く必要があります。

ウェイクアップのソースに関係なく、デバイスがスリープからウェイクアップすると、WDTはクリアされます。

8.2.2 割り込みを使用したウェイクアップ

グローバル割り込みが無効(GIE=0)で、クロックソース割り込みを除くすべての割り込みソースで、割り込み有効ビットと割り込みフラグビットの両方がセットされている場合、次のいずれかが発生します。

• SLEEP命令の実行前に割り込みが発生した場合

• SLEEP命令の実行中または実行後に割り込みが発生した場合

SLEEP命令を実行する前にフラグビットがチェックされた場合でも、SLEEP命令が完了する前にフラグビットがセットされる可能性があります。SLEEP命令が実行されたかどうかを判断するには、PDビットをテストします。PDビットがセットされている場合、SLEEP命令はNOPとして実行されました。

8.2.3 低電力 SLEEP モード

PIC16F18326/18346デバイスには内部低ドロップアウト(LDO)電圧レギュレータが含まれているため、デバイスのI/Oピンを最大5.5Vの電圧で動作させながら、内部デバイスロジックをより低い電圧で動作させることができます。LDOとそれに関連するリファレンス回路は、デバイスが SLEEP モードのときもアクティブのままである必要があります。

PIC16F18326/18346を使用すると、アプリケーションの要件に応じて、スリープ時の動作電流を最適化できます。

低電力 SLEEP モードは、VREGCONレジスタのVREGPMビットをセットすることで選択できます。これらのビットの構成に応じて、デバイスがスリープ状態のとき、LDOとリファレンス回路は低電力状態になります。

8.2.3.1 スリープ電流とウェイクアップ時間

デフォルトの動作モードでは、LDOとリファレンス回路は、スリープ中も通常の構成のままです。すべての回路がアクティブなままであるため、デバイスは SLEEP モードをすばやく終了できます。低電力 SLEEP モードでは、スリープからウェイクアップするときに、これらの回路が通常の構成に戻って安定するまでに追加の遅延時間が必要です。

低電力 SLEEP モードは、長期間 SLEEP モードに留まるアプリケーションに役立ちます。ノーマルモードは、スリープからすばやく頻繁にウェイクアップする必要があるアプリケーションに役立ちます。

8.2.3.2 スリープ中の周辺機器の使用

SLEEP モードで動作できる周辺機器の中には、低電力 SLEEP モードが選択されていると正しく動作しないものがあります。低電力 SLEEP モードは、次の周辺機器での使用を目的としています。

VREGPMの設定は、スリープ状態での動作を保証しアプリケーションで許容できるかを考慮し、エンドユーザーの責任で実施してください。

8.2.4 IDLE モード

アイドルイネーブル(IDLEN)ビットがクリアされている場合(IDLEN = 0)、SLEEP命令はデバイスをフル SLEEP モードにします(セクション8.2「SLEEP モード」を参照)。IDLENがセットされている場合(IDLEN = 1)、SLEEP命令はデバイスを IDLE モードにします。 IDLE モードでは、CPUとメモリの動作は停止しますが、周辺クロックは動作し続けます。このモードはDozeモードに似ていますが、IDLEではCPUとプログラムメモリの両方が遮断される点が異なります。

注意:FOSCを使用するペリフェラルは、アイドル状態(スリープ状態ではない)でも動作し続けます。

注意:CLKOUTが有効(CLKOUT = 0、Configuration Word 1)の場合、クロックはアイドル中も出力し続けます。

8.2.4.1 アイドルと割り込み

割り込みが発生すると(GIE =​​ 0であっても)、 Idle モードは終了しますが、IDLENは変更されません。デバイスは、SLEEP命令を実行することでIDLEに再び入ることができます。

Recover-on-Interruptが有効になっている場合(ROI = 1)、DOZEも有効になっている場合、デバイスをアイドル状態から戻す割り込みにより、CPUのフルスピード実行が復元されます。

8.2.4.2 アイドルとWDT

アイドル状態のとき、WDTリセットはブロックされ、代わりにデバイスをウェイクアップします。WDTウェイクアップは割り込みではないため、ROIは適用されません。

注意:WDTは、デバイスをスリープから復帰させるのと同じ方法で、デバイスをアイドルから復帰させることができます。DOZENビットは影響を受けません。

関連レジスター

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
VREGCON - - - - - - VREGPM Reserved
CPUDOZE IDLEN DOZEN ROI DOE - DOZE<2:0>
レジスタ BIT 説明 1 0
VREGCON 1 VREGPM 低電力 SLEEP モード ON/OFF 低電力 通常
0 Reserved 未使用 常にセットすること 1 -
CPUDOZE 7 IDLEN Idle / Sleep 選択 IDLE SLEEP
6 DOZEN Dozeモード選択 Doze 通常
5 ROI Interrupt(ISR)でのDoze動作 Doze 通常
4 DOE 復帰時のDozs Doze 変更なし
2 DOZE2 Doze動作時の間引き比率
111 = 1:256110 = 1:128101 = 1:64100 = 1:32
011 = 1:16010 = 1:8001 = 1:4000 = 1:2
1 IDLEN1
0 IDLEN0

SLEEPのプログラム例

<回路図>

SLEEP状態をTimer1またはPushSWでウェイクアップするプログラムです。

Timer1は LFINTOSC 31KHz を入力し4秒後にカウントアップします。カウントアップでSLEEPからウェイクアップし、LED4を短く点滅し再びSLEEPに入ります。
SWを押すとその立ち下がり信号で、SLEEPからウェイクアップし、LED7を短く点滅し、SWが話されるのを待て再びSLEEPに入ります。

<プログラム>

/*************************************
 * File: main.c
 *  SLEEP状態から、Timer1またはPushSW
 *  からの信号でウェイクアップする
 *     1MHz (内部クロック)
 *     RA4 LED4
 *     RC5 LED7
 *     RC4 PushSW
 * PIC16F18346 MPLAB XC8 v2.10
 * Created on June 22, 2020, 2:37 PM
 **************************************/

#include 
#define _XTAL_FREQ 1000000      // delay_ms(x) のための定義
#define LED4 LATA5
#define LED7 LATC5
#define SW RC4

#pragma config FEXTOSC = OFF,RSTOSC = HFINT1  // HFINTOSC (1MHz)
#pragma config CLKOUTEN = OFF,CSWEN = OFF,FCMEN = OFF
#pragma config MCLRE = ON,PWRTE = OFF,WDTE = OFF,LPBOREN = OFF
#pragma config BOREN = OFF,BORV = LOW,PPS1WAY = OFF,STVREN = ON
#pragma config DEBUG = OFF
#pragma config WRT = OFF,LVP = ON,CP = OFF,CPD = OFF


// ********************************************************
void main() {
    TRISA5 = 0;             // LED4 出力
    TRISC5 = 0;             // LED7 出力
    TRISC4 = 1;             // SW(RC4)   入力
    ANSC4  = 0;             // SW(RC4)   デジタル
    INTPPS = 0x14;          // SW(RC4)   interrupu pinに指定
    T1CON  = 0b11010101;    // LFINTosc Sync PreS 1/2 4sec
    T1GCON = 0;             // ゲート機能は使用せず
    TMR1 = 0;               // Timerクリア
    TMR1IF=0;               // Timer1割込みフラッグクリア
    INTEDG = 0;             // 立ち下がりで割込み
    INTF = 0;               // Pin割込みフラッグクリア
    INTE = 1;               // Pin割込み許可
    TMR1IE = 1;             // Timer1割込み許可
    PEIE = 1;               // ペリフェラル割込み許可
		
    while(1){
      // ----- SLEEP状態にする ------------------
      SLEEP();
      NOP();
      // ----- ウェイクアップ --------------------
      if(TMR1IF){       // Timer1カウントアップなら
        TMR1IF=0;       // Timer1割込みフラッグクリア
        LED4 = 1;       // LED4を短く点滅
        __delay_ms(20);
        LED4 = 0;
      }
      if(INTF){         // SWが押されたなら
        LED7 = 1;       // LED7を短く点滅
        __delay_ms(20);
        LED7 = 0;
        while(!SW);     // SWが離れるのを待つ
        __delay_ms(10); // チャタリング防止
        INTF = 0;       // Pin割込みフラグクリア
      }
    }
}