MIDIコントローラ
;;MIDI シリアルドライバ ;;MIDIのnoteONコマンドを送る ;;タイマー割込みを利用する ;;MIDI出力端子 RB1 LIST P=16F648A, ST=OFF, R=DEC, F=INHX8M INCLUDE P16F648A.INC ; __CONFIG _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON ;;; 定数 ;WAIT_CNT equ 0x20 ; 100usのwaitカウント bitDelay equ 0x20 ; 31.25Kbit/s タイマーWait値(bit間隔 32us) ;FileRegi msg_len equ 0x22 bit_cnt equ 0x23 ;割込み処理するビット数 wsave equ 0x24 stsave equ 0x25 CNT1 equ 0x26 CNT2 equ 0x27 CNT3 equ 0x28 sendByte equ 0x29 midi_cmd equ 0x30 ; MIDIコマンド midi_note equ 0x31 midi_vel equ 0x32 org 0 goto main org 4 goto intproc main movlw 0x6 ;初期設定 movwf PORTB bsf STATUS,RP0 ;bank1 movlw 0xF0 movwf TRISB bcf OPTION_REG,T0CS ;内部クロックを利用 bsf OPTION_REG,T0SE ;タイマオーバーフロー割込み設定 bsf OPTION_REG,PSA ;プリスケーラを利用しない movlw 0x80 movf bit_cnt,F bcf STATUS,RP0 ;bank0 bsf INTCON,T0IE ;タイマ0割り込み許可、 ;bsf PORTB,1 ;MIDI出力H ;bsf PORTB,2 ;BSF INTCON,GIE loop call note_on bcf PORTB,2 ;Check LED call TIM100 bsf PORTB,2 call T1SEC goto loop ;;;;;;;;;;; note_on ;;;;;;;;;;;;; note_on movlw 0x91 movwf midi_cmd movlw 0x3c ;note 3c movwf midi_note movlw 0x64 ;velocity movwf midi_vel movlw 0x3 ;message長 movwf msg_len call send_midi_msg ;midiメッセージ送信 return ;;;;;;;;;;; send_midi_msg ;;;;;;;;;;;;; ;; midi_msgをMIDI OUTに送信する send_midi_msg movlw midi_cmd movwf FSR movlw 0xff - bitDelay movwf TMR0 bsf INTCON,GIE ;割込み可 send_loop movf INDF,W movwf sendByte incf FSR,F movlw 0x9 movwf bit_cnt send_wait btfss bit_cnt,7 ;送信完了を待つ goto send_wait decfsz msg_len,f ;メッセージ長繰り返す goto send_loop bcf INTCON,GIE ;割込み停止 return ;;;;;;;;;;;; 割り込み処理 intproc ;;;;;;;;;;;; intproc ; 割り込み処理(MIDIバイトの送信処理) ;movwf wsave ; Wレジスタ退避 ;swapf STATUS,W ;movwf stsave ; STATUS退避 bcf INTCON,T0IF ;割込み要求クリア movlw 0x9 ;スタートビット subwf bit_cnt,w btfsc STATUS,Z goto send_start movlw 0x0 ;ストップビット subwf bit_cnt,w btfsc STATUS,Z goto send_stop movlw 0x80 ;ストップビット subwf bit_cnt,w btfsc STATUS,Z goto send_stop ;cje bit_cnt,#9,send_strt ;cje bit_cnt,#0,send_stop ;cje bit_cnt,#0ffh,int_end rrf sendByte,f ; データ部(8bit)送信 btfss STATUS,C bcf PORTB,1 btfsc STATUS,C bsf PORTB,1 decf bit_cnt,F goto int_end send_start bcf PORTB,1 ; Start bit decf bit_cnt,F ; bit_cnt = 8 goto int_end send_stop bsf PORTB,1 ; Stop bit movlw 0x80 movwf bit_cnt ;send over int_end ;; ----- 割り込み終了処理 ----- movlw 0xff-bitDelay movwf TMR0 ; tmr0再設定(32us間隔) ;swapf stsave,W ; STATUSを戻す ;movwf STATUS ;swapf wsave,F ; Wを戻す ;swapf wsave,W retfie ; 復帰 ;0.4msec Timer Subroutine TIM10 MOVLW 0F9H ;249回 MOVWF CNT1 ;ここまでで2サイクル TIMLP1 NOP DECFSZ CNT1,F ;このループは4サイクル GOTO TIMLP1 ;2+4*249-1=997 RETURN ;997+1=998*0.4usec=0.4msec ; 100msec Timer Subroutine TIM100 MOVLW 0F9H ;249回 MOVWF CNT2 TIMLP2 CALL TIM10 ;2+(1000+3)*249-1=249748 DECFSZ CNT2,F ;このループは1回1003サイクル GOTO TIMLP2 RETURN ;+1=249749サイクル ; ; 1Sec Timer Subroutine ; T1SEC MOVLW 0AH ;10回 MOVWF CNT3 ;100msec * 10 T1LP CALL TIM100 DECFSZ CNT3,F ;このループは100msec GOTO T1LP RETURN END