#include #include #include //クロックは内部RC4MHz #define _XTAL_FREQ 4000000 //内部クロックを使う #pragma config OSC = IntRC //PIC自体のWDTは使用しない #pragma config WDT = OFF //MCLRピンはI/O #pragma config MCLRE = OFF //コードプロテクトしない #pragma config CP = OFF //各ピンの名称 #define RESETPIN GPIObits.GP0 #define CHKLED GPIObits.GP4 #define WDDATA GPIObits.GP1 #define WDCTL GPIObits.GP2 //ループカウンタ unsigned char lcnt; //ハートビートの前回の値 unsigned char last_wdata; void main() { lcnt = 0; //WPUありクロック外部出力なし OPTION = 0b10000000; //強制リセットを不用意に実施しないため初期化前にHiに //これ以前は外部プルアップが効いている //注意:RPiのリセットはLo側でアクティブ RESETPIN = 1; //GPIOは0と4がOUT,それ以外はINに設定 TRISGPIO = 0b00101110; //WDが作動した場合の繰り返しループはここから while(1){ //初期ウエイト __delay_ms(100); //リセットピンをHiに RESETPIN = 1; //確認LEDを消灯 CHKLED = 0; //起動時のフェイルセーフ //GP1とGP2がLoになるまでスタートしない while(1) { if(WDDATA==1) continue; if(WDCTL==1) continue; break; } //GP1とGP2が一旦Hiになるのを待つ while(1) { if(WDDATA==0) continue; if(WDCTL==0) continue; break; } //GP1とGP2がLoになったらスタート while(1) { if(WDDATA==1) continue; if(WDCTL==1) continue; break; } //レディ確認表示 CHKLED = 1; while( 1 ) { //ループ回数をかぞえるためカウンタを減ずる lcnt--; //WDCTLがHiならアームドモード if(WDCTL == 1){ //アームド状態でループカウンタが1周したらWD動作 //期待されるWDの時間は100ms×256=25.6秒 if(lcnt==0) break; } else { //アームドでなければカウンタをリセット lcnt = 0; } //ループサイクルは100mS __delay_ms(100); //WDDATAの前回の値と異なるか? if(last_wdata != WDDATA){ if(WDDATA==1){ //値が変化しLo->Hiならばカウンタをリセット lcnt=0; if(WDCTL == 1){ //アームド状態の場合確認LEDをハートビートサイクルで点滅 CHKLED = ~CHKLED; } else { //アームドでない場合にはLEDを消灯のまま CHKLED = 0; } } } //現在のハートビート状態を保存 last_wdata = WDDATA; } //ウォッチドック作動RPiを強制リセット RESETPIN = 0; __delay_ms(3000); //リセット動作のため3秒間Loにホールド RESETPIN = 1; //Hiに戻す } }