dsPIC33AKシリーズ⑪WDTモジュールの使い方

dsPIC33Aシリーズ

概要

今回は、WDTモジュールの使い方をご紹介します。
WDTとはWatchDog Timerの略でソフトウェアがWDTを定期的にクリアしないと、デバイスがリセットされます。これにより、システムソフトウェアが正常に動作していない場合に、それを検出することができます。

dsPIC33AKシリーズには似た機能として「DMTモジュール」が搭載されていますが、その機能については次回の記事で説明いたします。

WDTモジュールの特徴

・独立した動作モードとスリープモード用のカウンター
・動作モードカウンターに別のクロック源とポストスケーラを使用可能
・最大32種類の設定可能なタイムアウト期間
・動作モードとスリープモードカウンターに独立した5ビットポストスケーラ
・ハードウェアおよびソフトウェアで有効化可能
・窓付きWDTオプション – ソフトウェア設定ビットで制御する4つのウィンドウサイズ

今回は基本的な使い方から実践的な使い方まで紹介します。

関連記事

記事リンク
第1回dsPIC33AKシリーズについてdsPIC33Aシリーズに関して – ぴくおの電子工作的な何かWP (electricpico.com)
第2回開発ボード、コンフィグレーション設定、クロック設定についてdsPIC33AKシリーズ②開発ボード,コンフィグレーション設定,クロック設定について – ぴくおの電子工作的な何かWP (electricpico.com)
第3回CPU性能についてdsPIC33AKシリーズ③CPU性能について – ぴくおの電子工作的な何かWP (electricpico.com)
第4回FPU性能についてdsPIC33AKシリーズ④FPU性能について – ぴくおの電子工作的な何かWP (electricpico.com)
第5回DSPについてdsPIC33AKシリーズ⑤DSPについて – ぴくおの電子工作的な何かWP (electricpico.com)
第6回タイマー1割り込みの使い方dsPIC33AKシリーズ⑥Timer1割り込みの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第7回PMUの使い方dsPIC33AKシリーズ⑦PMUの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第8回高速ADCの使い方dsPIC33AKシリーズ⑧高速ADCの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第9回高速OPAMPの使い方dsPIC33AKシリーズ⑨高速OPAMPの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第10回DMAモジュールの使い方dsPIC33AKシリーズ⑩DMAモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第11回(本記事)WDTモジュールの使い方
第12回DMTモジュールの使い方
(fig.1-1)各関連記事リンク

開発環境

開発環境を以下に示します。
今回はどちらのCPUボードでも動作いたします。

項目リンク
ベースボードdsPIC33A CURIOSITY PLATFORM
DEVELOPMENT BOARD
dsPIC33A Curiosity Platform Development Board User’s Guide (microchip.com)
CPUボード(EV68M17A)EV68M17A – dsPIC33AK128MC106 Motor Control DIMdsPIC33AK128MC106 Motor Control Dual In-Line Module (DIM) Information Sheet (microchip.com)
CPUボード(EV02G02A)dsPIC33AK128MC106 General Purpose Dual In-Line Module (DIM)dsPIC33AK128MC106 General Purpose Dual In-Line Module (DIM) | Microchip Technology
統合開発環境MPLAB X IDE v6.20MPLAB® X IDE | Microchip Technology
コンパイラMPLAB XC DSC v3.10MPLAB® XC DSC Compiler | Microchip Technology
(fig.2-1)本記事の動作確認環境
(fig.2-2)動作環境

WDTブロック図

以下にWDTのブロック図を示します。基本的には従来のdsPIC33CKシリーズと大きな変化点はありません。

WDTを有効化すると入力クロックのカウントアップを開始し、カウンタにリセットがかからないままカウントの最大値に到達すると、デバイスがリセットされます。

(fig.3-1)WDTブロック図

WDTレジスタとコンフィグフューズ

以下にWDTレジスタとその説明を示します。

レジスタ名ビット名説明
WDTCONONWDTモジュールの有効化/無効化
WINSIZEウィンドウサイズ
RMPSRUNモード時のクロックプリスケーラ
RMCLKRUNモード時のクロック選択
SMPSスリープモード時のクロックプリスケーラ
WINDISウィンドウモードの有効化/無効化
(fig.4-1)WDTレジスタ

なおWDTはコンフィグでも設定が可能です。基本的な動作はレジスタで設定する場合と同一ですが、起動時から動作を開始するため、ペリフェラルなど初期化中にもリセットを行う必要が有ります。
コンフィグで設定された値はソフトウェアによって上書きすることが可能です。

設定項目コメント
FWDT_WINDISONウォッチドッグタイマウィンドウ有効ビット(ウォッチドッグタイマは非ウィンドウモードで動作します)
FWDT_SWDTMPSPS2147483648スリープモードウォッチドッグタイマポストスケーラ選択ビット(1:2147483648)
FWDT_RCLKSELBPRC256ウォッチドッグタイマクロック選択ビット(WDT実行モードはBFRC:256を使用)
FWDT_RWDTPSPS2147483648実行モードウォッチドッグタイマポストスケーラ選択ビット(1:2147483648)
FWDT_WDTWINWIN25ウォッチドッグタイマウィンドウサイズ選択ビット(WDTウィンドウはWDT期間の25%)
FWDT_WDTENHWウォッチドッグタイマ有効ビット(WDTはハードウェアで有効)
FWDT_WDTRSTENONウォッチドッグタイマリセット有効ビット(WDTイベントはリセットを生成します)
(fig.4-2)WDTコンフィグ

WDTウィンドウ動作

Watchdog Timerにはオプションのウィンドウモードがあり、WINDIS = 0ビット(WDTCON[0])で有効にできます。このモードでは、WINSIZE[1:0]ビットで指定されたウィンドウ時間内でのみクリアされる必要があります。

動作確認①(Windowモード 無し)

ソースコード

インクルードファイル

コンフィグレーションファイル、クロック設定ファイルは以下のファイルをインクルードしてください。

■コンフィグレーションファイル (config.h)

■クロック設定ソースファイル(Clock_Driver.c)

■クロックヘッダーファイル(clock_driver.h)

ソースコード全体

以下のコードを実行すると、起動後8秒後にCPUリセットが発生します。
//ClrWdt(); のコメントを削除するとWDTのクリアが行われ、CPUリセットは発生しません。

#include <stdio.h>
#include <stdlib.h>
#include <dsp.h>
#include <xc.h>
#include "config.h"
#include "clock_driver.h"

int main() 
{
    /*-----------------------------------------------------------------------*/
    /*初期化*/
    /*-----------------------------------------------------------------------*/
        vdg_Clock_Set_Register();
		
	WDTCONbits.RMCLK = 3u;	//LPRC 32kHz
	WDTCONbits.RMPS = 12u;  //8.192s
	WDTCONbits.WINDIS = 1u; //Window 無効化	
	WDTCONbits.ON = 1u;
	Nop();

    /*----------------------------------------------------------------------------*/
    /*メインルーチン*/
    /*----------------------------------------------------------------------------*/
        while(1)
        {
	  //ClrWdt();
	}	
}

動作確認①(Windowモード 有り)

ソースコード

ソースコード全体

このコードを実行するとWDTが有効化され、約500ミリ秒後にClrWdt();が実行されます。しかし、このタイミングがウィンドウの外にあるため、タイマーはリセットされません。その結果、起動後1秒後にCPUがリセットされます。

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include "peripheral_init.h"
#include "BoardSupportPackage.h"
#include <dsp.h>

uint32_t Timer;

int main() 
{
    /*-----------------------------------------------------------------------*/
    /*初期化*/
    /*-----------------------------------------------------------------------*/
        vdg_Clock_Set_Register();
		
		
	PR1 = 100000;
	T1CONbits.ON = 1;
	T1CONbits.TCKPS = 0;
	IFS1bits.T1IF = 0;
	IEC1bits.T1IE = 1;
	IPC6bits.T1IP = 3;
		
	WDTCONbits.RMCLK = 3u;	  //LPRC
	WDTCONbits.RMPS = 10u;    //1.024sec以内
	WDTCONbits.WINDIS = 0u;   //ウィンドウ有効化
	WDTCONbits.WINSIZE = 3u; //75%
		
	WDTCONbits.ON = 1u;
	INTCON1bits.GIE = 1;
	Nop();

    /*----------------------------------------------------------------------------*/
    /*メインルーチン*/
    /*----------------------------------------------------------------------------*/
        while(1)
        {
		Timer = 500;
		while(Timer > 0) {;}
		ClrWdt();
	}	
}


void __attribute__((interrupt, no_auto_psv)) _T1Interrupt(void)
{
	if (Timer > 0 ){Timer --;}
	IFS1bits.T1IF = 0u;
}

Timer の値を以下のように変更すると、ウィンドウ内でWDTのクリアが行われるため、CPUリセットは発生しなくなります。

Timer = 800;

記事についての注意点

本記事は慎重に内容を検討し正確さに努めておりますが、内容に誤りがあったとしても、この記事を参考にして生じた損害等については一切の責任を負いません。

コメント

タイトルとURLをコピーしました