ホームに戻る
 PIC16F88 で MIDIデータを出力する

0、はじめに

MIDI は音そのものを含まない音楽の演奏情報の統一規格です。
例えば、ドの音を出すとかドの音を止めるとか。
MIDI の規格についての説明はここではしません。
今回は PIC16F88 を使って MIDI 信号を MIDI 対応の楽器に転送します。
MIDI の情報交換のやり方は非常にシンプルで逆に不安になるほどですが、
思ったよりも正確に情報のやり取りができます。

2、必要なもの

PIC16F88 と MIDI楽器 と MIDIケーブルが必要です。
他に、5V電源、220Ωの抵抗が2本、配線が必要です。
抵抗は220Ωに近いもので代用できると思います。

3、PIC と MIDIケーブルの配線について

MIDIケーブルの左から4番目が4番ピン。
MIDIケーブルの左から2番目が5番ピン。
逆にしても大きな問題は起きないので、
動作しなかったら入れ替えれば良いと思います。
MIDIケーブルの4番ピンを抵抗をはさんで5Vへ。
MIDIケーブルの5番ピンを抵抗をはさんで、
PIC の任意の出力ポートにつなぎます。

5V  -----抵抗(220Ω)-----MIDIケーブル(4番ピン)
PIC -----抵抗(220Ω)-----MIDIケーブル(5番ピン)

4、MIDI信号の詳細

MIDIデータの出力が無いときは常に HIGH になっています。
最初に LOW になったときがスタートビットです。
続いて8ビットが転送ビットになります。
このとき下位ビットから上位ビットに向かって転送します。
最後に HIGH にするのがエンドビットになります。

例えば、0x90 を転送したい場合には、

H の状態から LLLLLHLLHH の10ビットを転送します。

続けて、0x90 0x3C を転送したい場合には、

H の状態から LLLLLHLLHHLLLHHHHLLH の20ビットを転送します。

1ビットを維持する時間はおよそ 32 マイクロ秒です。
1つの MIDIデータを送るのにおよそ 320 マイクロ秒かかります。

5、サンプルコード

; PIC16F88 で内部クロック 4MHz を使用します。
; MIDI出力は PORTB の0番ピンを使用しています。

 LIST P=16F88
 INCLUDE P16F88.INC

 __CONFIG  _CONFIG1, _WDT_OFF & _PWRTE_ON & _INTRC_IO & _LVP_OFF & _MCLR_OFF
 __CONFIG  _CONFIG2, _IESO_OFF & _FCMEN_OFF

  T0        EQU  20H
  T1        EQU  21H
  MIDI_DATA EQU  22H
  COUNT1    EQU  23H
  BITCOUNT  EQU  24H

  PORT_OUT  EQU  0 ; 使用するポートBの番号

  BSF   STATUS,RP0 ; Bank 1
  MOVLW 064h
  MOVWF OSCCON     ; 内部クロック 4MHz
  MOVLW 000h
  MOVWF TRISB      ; すべて出力に
  CLRF  ANSEL      ; アナログ入出力を使用しない
  BCF   STATUS,RP0 ; Bank 0

  BSF   PORTB,PORT_OUT

MAIN

  CALL  WAIT_250MS
  CALL  WAIT_250MS

  MOVLW 0x90
  MOVWF MIDI_DATA
  CALL  MIDI_OUT
  MOVLW 0x3C
  MOVWF MIDI_DATA
  CALL  MIDI_OUT
  MOVLW 0x7F
  MOVWF MIDI_DATA
  CALL  MIDI_OUT

  CALL  WAIT_250MS
  CALL  WAIT_250MS

  MOVLW 0x80
  MOVWF MIDI_DATA
  CALL  MIDI_OUT
  MOVLW 0x3C
  MOVWF MIDI_DATA
  CALL  MIDI_OUT
  MOVLW 0x00
  MOVWF MIDI_DATA
  CALL  MIDI_OUT

  GOTO  MAIN

MIDI_OUT
  BCF   PORTB,PORT_OUT
  NOP
  MOVLW  D'8'
  MOVWF  COUNT1
START_BIT_WAIT
  DECFSZ COUNT1,F
  GOTO   START_BIT_WAIT
  MOVLW  D'8'
  MOVWF  BITCOUNT
SET_BIT
  BTFSC  MIDI_DATA,0
  GOTO   BIT_1
BIT_0
  NOP
  BCF    PORTB,PORT_OUT
  GOTO   SET_BIT2
BIT_1
  BSF    PORTB,PORT_OUT
  GOTO   SET_BIT2
SET_BIT2
  RRF    MIDI_DATA,F
  MOVLW  D'7'
  MOVWF  COUNT1
SET_BIT_WAIT
  DECFSZ COUNT1,F
  GOTO   SET_BIT_WAIT
  DECFSZ BITCOUNT
  GOTO   SET_BIT
STOP_BIT
  NOP
  NOP
  NOP
  NOP
  BSF    PORTB,PORT_OUT
  MOVLW  D'8'
  MOVWF  COUNT1
STOP_BIT_WAIT
  DECFSZ COUNT1,F
  GOTO   STOP_BIT_WAIT
  NOP
  RETURN

; 1ms
WAIT_01MS
  MOVLW D'250'
  MOVWF T0
TIMELOOP
  NOP
  DECFSZ T0, F
  GOTO  TIMELOOP
  RETURN

; 250ms
WAIT_250MS
 MOVLW D'250'
 MOVWF T1
TIMELOOP2
 CALL WAIT_01MS
 DECFSZ T1, F
 GOTO  TIMELOOP2
 RETURN

  END

inserted by FC2 system