list p=16f628A #include errorlevel -302 __CONFIG _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_ON & _PWRTE_ON & _HS_OSC #define GATE1 PORTA,1 #define GATE2 PORTA,0 #define RS_LED PORTB,5 #define GLED1 PORTA,2 #define GLED2 PORTA,3 #define TPAT1 b'11111111' #define TPAT2 b'01010101' #define CYCLCNT 2 #define SEQ_LEN d'96' ; 24x4 = 96 = 1 Length w_temp EQU 0x71 status_temp EQU 0x72 TMP_DATA EQU 0x24 MIDI_CCNT EQU 0x25 RUN_STATE EQU 0x26 ; bit 0 = RUN/STOP, bit 1 = GATE GO TRIG_PAT EQU 0x27 TRIG_CNT EQU 0x28 CNT1 EQU 0x29 CNT2 EQU 0x2a ORG 0x000 goto main ;割り込み処理ルーチン ORG 0x004 movwf w_temp movf STATUS,w movwf status_temp btfss PIR1,RCIF goto ret_main ;シリアル割り込み以外は無視して戻る ;ウォッチドッグクリア clrwdt banksel TMP_DATA movf RCREG,w movwf TMP_DATA movlw 0xf8 ;MIDIクロック subwf TMP_DATA,f btfsc STATUS,Z goto is_clock decf TMP_DATA,f ; 0xf9は無視 decf TMP_DATA,f btfsc STATUS,Z goto is_start ; 0xfa = MIDI Start decf TMP_DATA,f btfsc STATUS,Z goto is_continue ; 0xfb = MIDI Continue decf TMP_DATA,f btfsc STATUS,Z goto is_stop ; 0xfc = MIDI stop goto ret_main ; その他だったら戻るだけ is_continue bsf RUN_STATE,0 ; MIDI CONTINUE時はカウンタをリセットしない goto ret_main is_stop bcf RUN_STATE,0 ; MIDI STOP時は単にSTOP状態に goto ret_main is_start movlw d'1' ; MIDI STARTを受け取ったら次クロックで movwf MIDI_CCNT ;トリガされるように! movlw CYCLCNT ;パターンカウンタをリセット movwf TRIG_CNT call pat_chk ;トリガパターンを初期化 bsf RUN_STATE,0 ; RUN状態に goto ret_main is_clock btfss RUN_STATE,0 goto ret_main ; RUN状態でなければカウントしない decfsz MIDI_CCNT,f ; 1length = 96 tick goto ret_main movlw SEQ_LEN movwf MIDI_CCNT bsf RUN_STATE,1 ; 96tick経過したらゲートON ret_main bcf RCSTA,FERR ;フレーミングエラークリア bcf RCSTA,OERR ;オーバランエラークリア movf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w bsf INTCON,GIE ;割り込み許可 retfie ;割り込み処理ルーチンここまで main ;メインルーチン bcf STATUS,RP0 ;レジスタをバンク0へ明示的に設定 bcf STATUS,RP1 clrf INTCON ;割り込み無効 clrf PORTA ;各ポートを初期化 clrf PORTB movlw 0x07 movwf CMCON ;コンパレータをオフに bsf STATUS,RP0 ;バンクを1に clrf TRISA ;PORTAを出力に movlw b'00001110';PORTB 1,2をシリアルで使用 RB3をスイッチ入力 movwf TRISB movlw d'39' movwf SPBRG ;ボーレートジェネレータに39をセット movlw b'00100100';BRGH=1 で312500bps,TXEN=1 movwf TXSTA ;BRGH=1をセット bcf STATUS,RP0 ;バンク0に戻す ;シリアルポート割り込み関連初期化 bsf INTCON,PEIE;周辺割り込み許可 bsf STATUS,RP0 ;Bank=1 bsf PIE1,RCIE ;受信割り込み有効 bcf STATUS,RP0 ;Bank-0 bsf INTCON,GIE ;割り込み有効 ;MIDIクロックカウンタ設定 movlw SEQ_LEN movwf MIDI_CCNT ;トリガカウンタ設定 movlw CYCLCNT movwf TRIG_CNT ;パターンチェック&設定 call pat_chk ;状態クリア clrf RUN_STATE ;受信OK設定 movlw b'10010000';SPEN=1,SREN=1 movwf RCSTA ;初期化完了後、RUN LED一瞬点灯 bsf RS_LED call dly_ms call dly_ms bcf RS_LED main_loop btfsc RUN_STATE,0 goto RLED_ON goto RLED_OFF RLED_ON bsf RS_LED goto back_loop RLED_OFF bcf RS_LED goto back_loop back_loop btfss RUN_STATE,1 goto main_loop ;ゲート1側 btfss TRIG_PAT,0 goto chk_gat2 bsf GATE1 bsf GLED1 chk_gat2 btfss TRIG_PAT,1 goto do_wait bsf GATE2 bsf GLED2 do_wait call dly_ms call dly_ms call dly_ms bcf GATE1 bcf GLED1 bcf GATE2 bcf GLED2 bcf RUN_STATE,1 ;トリガパターン変更 rrf TRIG_PAT,f decfsz TRIG_CNT,f goto main_loop ;トリガパターン、カウンタ再設定 movlw CYCLCNT movwf TRIG_CNT ;パターンチェック&設定 call pat_chk goto main_loop ;1文字送信ルーチン(w=送信文字) 使ってないけど書いておく send_char movwf TXREG bsf STATUS,RP0 ; Bank=1 send_wait btfss TXSTA,TRMT ;TRMT=1で送信済 goto send_wait bcf STATUS,RP0 ; Bank=0 return pat_chk ;パターンチェック&設定ルーチン btfsc PORTB,3 goto setpat2 setpat1 movlw TPAT1 goto do_setpat setpat2 movlw TPAT2 do_setpat movwf TRIG_PAT return ; ミリ秒遅延(時間はアバウトなので注意) ; Fレジスタ:CNT1,2 dly_ms movlw d'10' movwf CNT1 dly_ms1 movlw d'250' movwf CNT2 dly_ms2 nop nop nop nop decfsz CNT2,f goto dly_ms2 decfsz CNT1,f goto dly_ms1 return ;EEPROM Address ORG 0x2100 END