/* * Source : FMR12Main.c * Date : 2012/09/17 * Update : * Auther : Pharaoh */ #include #include "pic16f88.h" #include "stdio.h" // Data Sheet P132 (CONFIG1) __CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_OFF & MCLRE_ON & BOREN_OFF & CPD_OFF & WRT_OFF & DEBUG_ON & CP_OFF & LVP_OFF); __CONFIG(IESO_OFF & FCMEN_OFF); // スイッチ入力 #define INP_POWEREN RB4 #define INP_SEEKUP RB5 #define INP_SEEKDOWN RB6 // 割り込みによって実行する処理 #define INT_CMD_POWEREN 1 #define INT_CMD_SEEKUP 2 #define INT_CMD_SEEKDOWN 3 #define INT_CMD_NO 0 // コントロール出力 #define OUT_POWER_FM RA4 // RDA7088 PDN #define OUT_SEEKUP RA2 // RDA7088 SEEK+ #define OUT_SEEKDOWN RA3 // RDA7088 SEEK- #define OUT_POWER_AMP RA1 // HT82V739 CE #define OUT_POWER_LED RA0 // 電源オン−オフ状態 #define POWER_ON 1 #define POWER_OFF 0 // 電源オンオフ間遷移状態 #define PTRANS_OFF_ON 1 // オフ→オンの遷移 #define PTRANS_ON_OFF 2 // オン→オフの遷移 #define PTRANS_OUT 0 // 遷移状態ではない void WaitChattering(); void WaitSwitchOn(); void Sleep(); static int Int_Cmd; static int PowerOnTransition; /* * 割り込みハンドラ */ void interrupt Interrupt(){ if (RBIF == 1){ if (INP_POWEREN == 0){ Int_Cmd = INT_CMD_POWEREN; } else if (INP_SEEKUP == 0){ Int_Cmd = INT_CMD_SEEKUP; } else if (INP_SEEKDOWN == 0){ Int_Cmd = INT_CMD_SEEKDOWN; } RBIF = 0; } } void main(){ int power_state = POWER_OFF; int trans_cnt = 0; int a6 = 0; ANSEL = 0; // set AN pins to Digital IO pin TRISA0 = 0; // RA0 -> output TRISA1 = 0; // RA1 -> output TRISA2 = 0; // RA2 -> output TRISA3 = 0; // RA3 -> output TRISA4 = 0; // RA4 -> output TRISB4 = 1; // RB4 -> input TRISB5 = 1; // RB5 -> input TRISB6 = 1; // RB6 -> input OSCCONbits.IRCF = 0; // 31.25kHz nRBPU = 0; // weak internal pull-ups on RBIE = 1; // RB port change interrupt ON GIE = 1; // Global Interrupt Enable ON OUT_POWER_LED = 0; OUT_POWER_FM = 0; OUT_SEEKUP = 0; OUT_SEEKDOWN = 0; OUT_POWER_AMP = power_state; while (1){ /*** for TEST // about 5s for (long i=0; i<1000; i++){ asm("NOP"); } // toggle a6 = 1 - a6; OUT_POWER_LED = a6; ***/ if (Int_Cmd != INT_CMD_NO){ if (Int_Cmd == INT_CMD_POWEREN){ // RDA7088 OUT_POWER_FM = 1; WaitSwitchOn(); OUT_POWER_FM = 0; if (PowerOnTransition == PTRANS_OUT){ if (power_state == POWER_OFF){ //アンプのオフ→オンはすぐに power_state = POWER_ON; OUT_POWER_AMP = power_state; PowerOnTransition = PTRANS_OFF_ON; OUT_POWER_LED = 1; } else { //アンプのオン→オフは時間を置いてから。 //その間にRDA7088が切れていることを耳で確認する。 PowerOnTransition = PTRANS_ON_OFF; } trans_cnt = 0; } else { trans_cnt = 0; } } else if (Int_Cmd == INT_CMD_SEEKUP){ OUT_SEEKUP = 1; WaitSwitchOn(); OUT_SEEKUP = 0; Sleep(); } else if (Int_Cmd == INT_CMD_SEEKDOWN){ OUT_SEEKDOWN = 1; WaitSwitchOn(); OUT_SEEKDOWN = 0; Sleep(); } WaitChattering(); Int_Cmd = INT_CMD_NO; } if (PowerOnTransition != PTRANS_OUT){ trans_cnt++; if (trans_cnt == 1000){ // トランジション状態の持続時間 // トランジション状態の終わりにアンプをオフに if (PowerOnTransition == PTRANS_ON_OFF){ power_state = POWER_OFF; OUT_POWER_AMP = power_state; OUT_POWER_LED = 0; } PowerOnTransition = PTRANS_OUT; Sleep(); } } } } /* * ボタン押下後のチャッタリングをやり過ごす */ void WaitChattering(){ int cnt = 0; while (1){ if (INP_POWEREN == 1 && INP_SEEKUP == 1 && INP_SEEKDOWN == 1){ cnt++; if (cnt == 10){ // どのボタンも押されていない状態が充分な期間続くこと break; } } else { cnt = 0; } // 20*(5/1000) = 0.1s for (int i=0; i<20; i++){ asm("NOP"); } } } /* * スイッチがONとなる時間間隔 */ void WaitSwitchOn(){ for (int i=0; i<10; i++){ asm("NOP"); } } /* * SLEEPモードに */ void Sleep(){ asm("SLEEP"); }