ウォッチ ドッグ タイマ(Watch Dog Timer)はハードウェアに近い場所に実装された独立したタイマで、プログラムのバグで無限ループに陥ったり、外乱ノイズ等の影響でプログラムが暴走してしまった場合などの異常を検知して、PIC に自動的にリセットをかけたりするのに使われます。今回、このウォッチドッグタイマを利用して LED を点滅させてみようという試み。
ウォッチドッグタイマは、CPU とは独立した内蔵クロックで駆動されていて、タイムアウトすると以下の動作を行います。
通常は、1. の使途で利用し、ソフトウェアのバグなどで無限ループに陥ってしまった時などに、ソフトウェアをリセットするために用いるのですが、今回は 2. の特性を利用し、SLEEP でプログラム実行を止め、ウォッチドッグタイマのタイムアウトにより SLEEP を抜けるようにしてみます。
#include <htc.h>
__CONFIG (
FOSC_INTOSCIO // 内蔵オシレータ
& WDTE_ON // WDT 【有効】
& PWRTE_OFF // PWRT 無効
& MCLRE_OFF // MCLR 使用しない
& BOREN_OFF // BOD 無効
& LVP_OFF // Low-Voltage Programming 使用しない
& CPD_OFF // Data memory code protection 無効
& DEBUG_OFF // In-Circuit Debugger 使用しない
& CP_OFF // Program Memory code protection 無効
);
// メインルーチン
void main ()
{
// ポートBをデジタル出力に設定
TRISB = 0b00000000;
OPTION_REGbits.PSA = 0b1;
OPTION_REGbits.PS = 0b110; // 1:64
// ポート初期化
PORTB = 0b10101010;
// メインループ
while (1)
{
CLRWDT(); // ウォッチドッグタイマをクリア
SLEEP(); // SLEEP から復帰すると次の1命令は実行される
NOP(); // スリープから復帰
PORTB = ~PORTB; // ポートの出力状態を反転
}
}
OPTION_REGbits.PSAOPTION_REGbits.PSネット上で PIC の情報を集めると、ウォッチドッグタイマは無効にしているサンプル ソースが相当多くて、ウォッチドッグタイマのタイムアウトを使って何かやっている例というのがあまり見つけられませんでした。まぁ、普通にプログラムを動かしていても、タイムアウトすると勝手にソフトウェア リセットがかかってしまうため、PIC の勉強をする上ではむしろ邪魔になりますからね。
ウォッチドッグタイマを駆動している内蔵クロックの周波数が 31.25kHz であることから、タイムアウトする時間を求められそうですが、これがよくわからない。最終的に、データシートに書いてあるタイムアウト時間(16ミリ秒)にプリスケール値を乗じてタイムアウト時間を求めることになりました。例えば、プリスケール値が 1:64 の時のタイムアウト時間は約 1 秒なので、精度を求めない場合などには使えるかもしれません...