PIC de MIDI
1999年2月 長嶋洋一
PIC de MIDI 99/02/20 23:54
やっと資料がまとまりました_o_
PIC16F84を使ったMIDI小物、その1をお贈りします。
DTM仕様の音源モジュールやキーボード(R社SK-50,Y社CBX-K1XG)をリアル
タイム演奏に使おうとすると音色切替が面倒です。
そこで、ワンタッチで音色番号を選択するために作りました。
1) 数字キー(1-9,0)を押すと、あらかじめ記憶されたProgram#を出力。
2) E を押しながら数字キーを押すと、現在のProgram#がその番号に記憶。
(EEPROMに記憶されるため、電源を切っても消えません。)
3) C を押すと、Program#=0を出力。
4) ^ を押すと、現在のProgram#に8を加えたProgram#を出力。
5) v を押すと、現在のProgram#から8を引いたProgram#を出力。
6) > を押すと、現在のProgram#に1を加えたProgram#を出力。
7) < を押すと、現在のProgram#から1を引いたProgram#を出力。
(Channel#は1に固定です。)
ではまずハード篇から:
キー・スイッチはジャンク屋で電話用のものを買ってきて、キー・トップを
適当に並べ変えました。
スイッチ・マトリクスを組む場合、同時に押されるスイッチの個数が2個ま
でならばダイオードは不要です。
この回路ではRB0-3を出力、RA1-4を入力にします。
抵抗アレーRA1でプルアップし、ロー・アクティブで動かします。
R1,R2 = 47k
RA1 = 8*47k(抵抗アレー)
C1,C2 = 22pF
Xtal = 2MHz
MIDI OUT は規格に準拠すればオープン・コレクタのインバータを使って、
次のような回路になります。(Pwr = +5V)
RB5ではなくオープン・ドレイン出力のRA4を使えば良かったのですが、配線の
楽な方を選んでしまいました。(^_^;)
...ま、ここまでは許してぇ...
さて、電源まで省いて相手の MIDI OUT から電流をもらおうという暴挙も公開
してしまいましょう。(だって、電池もACアダプターも面倒なんだもん。)
短距離で1対1で使う分には一応動きますが、相応のリスクはあるでしょう。
ここで使う三端子レギュレータはMOS型の低ドロップ電圧、超低消費電力のもの
です。(例)リコー RE5RL33A(3.3V)
MIDI端子の4番は、他に電流を横取りしなければフォトカプラーのLED点灯時
でも4V、1mA取られても3.8Vありますから3.3Vに落として使えば安心?です。
などというワガママな製品もあり、要注意です。
ソフト篇に続く...
RE:PIC de MIDI 99/02/21 00:30
PIC小物その1、ソフト篇をお贈りします。
いきなりオープン・ソースにて失礼します。
;Program Memory 1
LIST P=PIC16F84
include "p16f84.inc"
LIST R=DECIMAL
__config _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC
tx_reg equ 0x10
tx_lcnt equ 0x11
tx_wcnt equ 0x12
out_b equ 0x13
wcnt1 equ 0x14
wcnt2 equ 0x15
key1_old equ 0x16
key1_new equ 0x17
key2_old equ 0x18
key2_new equ 0x19
key3_old equ 0x1A
key3_new equ 0x1B
key4_old equ 0x1C
key4_new equ 0x1D
key_ent equ 0x1E
key_tmp equ 0x1F
pgm_num equ 0x20
mem_num equ 0x21
lp_cnt equ 0x22
org 0
goto start
retfie
retfie
retfie
retfie
start
bcf STATUS,RP0
movlw 0xFF
movwf out_b
movwf PORTB
bsf STATUS,RP0
movlw 0xD0
movwf TRISB
movlw 0x7F
movwf OPTION_REG
bcf STATUS,RP0
clrf pgm_num
key_on_loop
call key_chk
bz key_on_loop
call chat_wait
call key_chk
bz key_on_loop
key_updn
btfsc key3_new,1
call pgm_up8
btfsc key3_new,2
call pgm_up1
btfsc key4_new,1
call pgm_dn8
btfsc key4_new,2
call pgm_dn1
btfsc key4_new,3
call pgm_clr
key_mem
rlf key2_new,w
movwf key_tmp
rlf key_tmp
rlf key_tmp,w
andlw 0xF0
movwf key_tmp
rrf key1_new,w
andlw 0x0F
iorwf key_tmp
clrf mem_num
movlw 8
movwf lp_cnt
key_mem_loop
rrf key_tmp
skpnc
call pgm_mem
incf mem_num
decfsz lp_cnt
goto key_mem_loop
key_mem9
btfsc key3_new,3
call pgm_mem
incf mem_num
btfsc key3_new,4
call pgm_mem
key_off_loop
call key_chk
bnz key_off_loop
call chat_wait
call key_chk
bnz key_off_loop
goto key_on_loop
key_chk
key1
movlw 0xFE
movwf out_b
movwf PORTB
movfw key1_new
movwf key1_old
comf PORTA,w
andlw 0x1E
movwf key1_new
key2
movlw 0xFD
movwf out_b
movwf PORTB
movfw key2_new
movwf key2_old
comf PORTA,w
andlw 0x1E
movwf key2_new
key3
movlw 0xFB
movwf out_b
movwf PORTB
movfw key3_new
movwf key3_old
comf PORTA,w
andlw 0x1E
movwf key3_new
key4
movlw 0xF7
movwf out_b
movwf PORTB
movfw key4_new
movwf key4_old
comf PORTA,w
movwf key_ent
andlw 0x0E
movwf key4_new
key0
movlw 0xFF
movwf out_b
movwf PORTB
movfw key1_new
iorwff key3_new,w
iorwf key4_new,w
return
pgm_up1
incf pgm_num,w
andlw 0x7F
movwf pgm_num
goto pgm_chng
pgm_up8
movfw pgm_num
addlw 8
andlw 0x7F
movwf pgm_num
goto pgm_chng
pgm_dn1
decf pgm_num,w
andlw 0x7F
movwf pgm_num
goto pgm_chng
pgm_dn8
movfw pgm_num
addlw -8
andlw 0x7F
movwf pgm_num
goto pgm_chng
pgm_clr
clrf pgm_num
goto pgm_chng
pgm_mem
movfw mem_num
movwf EEADR
btfsc key_ent,4
goto pgm_mem_wr
bsf STATUS,RP0
bsf EECON1,RD
bcf STATUS,RP0
movfw EEDATA
movwf pgm_num
goto pgm_chng
pgm_mem_wr
movfw pgm_num
movwf EEDATA
bsf STATUS,RP0
bsf EECON1,WREN
movlw 0x55
movwf EECON2
movlw 0xAA
movwf EECON2
bsf EECON1,WR
bcf EECON1,WREN
bcf STATUS,RP0
return
pgm_chng
movlw 0xC0
call Midi_Out
movfw pgm_num
call Midi_Out
return
Midi_Out
movwf tx_reg
bcf out_b,5 ;start bit
movfw out_b
movwf PORTB
call midi_wait
nop
nop
movlw 8
movwf tx_lcnt
midi_loop
btfsc tx_reg,0
bsf out_b,5
btfss tx_reg,0
bcf out_b,5
movfw out_b
movwf PORTB
call midi_wait
rrf tx_reg
decfsz tx_lcnt
goto midi_loop
midi_stop_bit
nop
nop
nop
nop
bsf out_b,5 ;stop bit
movfw out_b
movwf PORTB
call midi_wait
nop
return
midi_wait
nop ;Xtal=2MHz
nop
return
chat_wait
movlw 8
movwf wcnt1
wlp1
clrf wcnt2
wlp2
nop
nop
nop
decfsz wcnt2
goto wlp2
decfsz wcnt1
goto wlp1
return
;EEPROM
org 0x2100
de 00
de 16
de 32
de 48
de 56
de 64
de 80
de 96
de 112
de 0
END
その1、終わり。
RE:PIC de MIDI 99/02/21 00:31
やっと資料がまとまりました。
PIC16F84を使ったMIDI小物(今度は大物?)、その2をお贈りします。
さてお待ちかねの光ハープです。
要はキー・スイッチのマトリクスと同じで、スイッチの接点部分をLEDと
フォト・トランジスタに置き換えたものです。
光の絃とNote#との対応はDataEEPROMにテーブルとして持ちます。
ハード篇その1:CPUボード
この回路ではRB0-3を出力、RA0-4を入力にします。
抵抗アレーRA3でプルアップし、ロー・アクティブで動かします。
明るさによるフォト・トランジスタの電流変化をPICのRA0-3に入力するため、
シュミット入力タイプのバス・バッファ HC244を通します。
RB0-3の出力は、どれか1本だけがローになるようにスキャンし、LEDを点灯
させると同時に対応するHC244の出力をアクティブにします。
CN1,2の奇数番ピンはすべてGndに接続。
SW1はプッシュ・オン型。動作テスト、光部の調整に使います。
Pwr= +5V
u1 = 74HC244
u2 = 74HC244
u3 = PIC16F84-10
R1 = 10k
R2 = 10k
RA1= 8*2k2 (2.2k) Pull Up R-Array
RA2= 8*2k2 (2.2k) Pull Up R-Array
RA3= 8*10k Pull Up R-Array
C1 = 22p
C2 = 22p
Xtal=10MHz
ハード篇その2:光部分
LEDは超高輝度(2000-3000mcd/20mA)で指向角の小さいもの(10度以下)を
使います。2個ずつ直列にすることによって、電流を有効に使います。
フォト・トランジスタは飽和電流2mAのものを使い、プルアップ抵抗RA1,2
(2.2k)による電流ループを作ります。
隣接するLEDからの光の漏れはダイナミック・スキャンによってソフト的に
排除できますが、外部からの光がフォト・トランジスタに当たると誤動作
します_o_
面倒なのは、筐体の木工とLED,PhotoTrの取り付け、光軸合わせです。
光軸合わせは、テスト・モードでLEDを1系統ずつ点灯させ、PhotoTrの
コレクタ側の電圧を測りながら行います。
部品の選別:
LEDもPhotoTrもバラツキがありますから、選別する必要があります。
LEDは樹脂成型なのですがチップの取り付け位置が微妙にズレていて、
光の像はそれぞれ異なります。チップが光軸にぴったり合っている方が、
かえってボンディング点が陰となってしまい、リング状の光が出てしま
います。
PhotoTrは感度(飽和電流)がそれぞれ異なります。
A-A,B-B,...,H-H をそれぞれ接続。
LED GL5UR3K (Sharp)
PhotoTr TPS607A (Toshiba)
R0 = 82[ohm]
ソフト篇に続く...
RE:PIC de MIDI 99/02/21 00:32
光ハープ ソフト篇
;Photo Harp part1
;PentaTonic
;with TestMode
LIST P=PIC16F84
include "p16f84.inc"
LIST R=DECIMAL
__config _CP_OFF&_PWRTE_ON&_WDT_OFF&_HS_OSC
note_vel equ 0x10
tx_reg equ 0x11
tx_lcnt equ 0x12
tx_wcnt equ 0x13
out_b equ 0x14
wcnt1 equ 0x15
wcnt2 equ 0x16
wcnt3 equ 0x17
key1_old equ 0x18
key1_new equ 0x19
key2_old equ 0x1A
key2_new equ 0x1B
key3_old equ 0x1C
key3_new equ 0x1D
key4_old equ 0x1E
key4_new equ 0x1F
key_sw equ 0x20
key_num equ 0x21
key_cnt equ 0x22
org 0
goto start
retfie
retfie
retfie
retfie
start
bcf STATUS,RP0
movlw 0xFF
movwf out_b
movwf PORTB
bsf STATUS,RP0
movlw 0xC1
movwf TRISB
bcf STATUS,RP0
btfss PORTA,4
goto test_loop
clrf key1_old
clrf key1_new
clrf key2_old
clrf key2_new
clrf key3_old
clrf key3_new
clrf key4_old
movlw 0x01
movwf key4_new
loop1
clrf key_num
key1
movlw 0xEF
movwf out_b
movwf PORTB
call wait_on
movfw key1_new
movwf key1_old
movfw PORTA
movwf key1_new
movlw 0xFF
movwf out_b
movwf PORTB
key1_on
comf key1_old,w
andwf key1_new,w
movwf key_sw
movlw 64
movwf note_vel
call key_event
movlw 4
subwf key_num
key1_off
comf key1_new,w
andwf key1_old,w
movwf key_sw
movlw 0
movwf note_vel
call key_event
key2
movlw 0xF7
movwf out_b
movwf PORTB
call wait_on
movfw key2_new
movwf key2_old
movfw PORTA
movwf key2_new
movlw 0xFF
movwf out_b
movwf PORTB
key2_on
comf key2_old,w
andwf key2_new,w
movwf key_sw
movlw 64
movwf note_vel
call key_event
movlw 4
subwf key_num
key2_off
comf key2_new,w
andwf key2_old,w
movwf key_sw
movlw 0
movwf note_vel
call key_event
key3
movlw 0xFB
movwf out_b
movwf PORTB
call wait_on
movfw key3_new
movwf key3_old
movfw PORTA
movwf key3_new
movlw 0xFF
movwf out_b
movwf PORTB
key3_on
comf key3_old,w
andwf key3_new,w
movwf key_sw
movlw 64
movwf note_vel
call key_event
movlw 4
subwf key_num
key3_off
comf key3_new,w
andwf key3_old,w
movwf key_sw
movlw 0
movwf note_vel
call key_event
key4
movlw 0xFD
movwf out_b
movwf PORTB
call wait_on
movfw key4_new
movwf key4_old
movfw PORTA
movwf key4_new
movlw 0xFF
movwf out_b
movwf PORTB
key4_on
comf key4_old,w
andwf key4_new,w
movwf key_sw
movlw 64
movwf note_vel
call key_event
movlw 4
subwf key_num
key4_off
comf key4_new,w
andwf key4_old,w
movwf key_sw
movlw 0
movwf note_vel
call key_event
goto loop1
key_event
movlw 4
movwf key_cnt
key_loop
btfsc key_sw,3
call note_event
rlf key_sw
incf key_num
decfsz key_cnt
goto key_loop
return
note_event
movlw 0x90
call Midi_Out
movfw key_num
movwf EEADR
bsf STATUS,RP0
bsf EECON1,RD
bcf STATUS,RP0
movfw EEDATA
call Midi_Out
movfw note_vel
call Midi_Out
return
Midi_Out
movwf tx_reg
bcf out_b,5 ;start bit
movfw out_b
movwf PORTB
call midi_wait
nop
nop
movlw 8
movwf tx_lcnt
midi_loop
btfsc tx_reg,0
bsf out_b,5
btfss tx_reg,0
bcf out_b,5
movfw out_b
movwf PORTB
call midi_wait
rrf tx_reg
decfsz tx_lcnt
goto midi_loop
midi_stop_bit
nop
nop
nop
nop
bsf out_b,5 ;stop bit
movfw out_b
movwf PORTB
call midi_wait
nop
return
midi_wait ;Xtal=10MHz
nop
nop
movlw 21
movwf tx_wcnt
midi_wait_loop
decfsz tx_wcnt
goto midi_wait_loop
return
wait_on
movlw 10
movwf wcnt1
wlp1
clrf wcnt2
wlp2
nop
nop
decfsz wcnt2
goto wlp2
decfsz wcnt1
goto wlp1
return
;Photo Harp part2
;test mode
test_loop
movlw 0xEF
movwf PORTB
call kwait
movlw 0xF7
movwf PORTB
call kwait
movlw 0xFB
movwf PORTB
call kwait
movlw 0xFD
movwf PORTB
call kwait
goto test_loop
kwait
kwait_hi
btfss PORTA,4
goto kwait_hi
kwait_lo
btfsc PORTA,4
goto kwait_lo
movlw 100
movwf wcnt1
kwlp1
clrf wcnt2
kwlp2
nop
nop
decfsz wcnt2
goto kwlp2
decfsz wcnt1
goto kwlp1
btfsc PORTA,4
goto kwait_lo
return
org 0x2100
;EEPROM Note# PhotoTr
de 50 ; 1
de 60 ; 5
de 69 ; 9
de 79 ;13
de 52 ; 2
de 62 ; 6
de 71 ;10
de 81 ;14
de 55 ; 3
de 64 ; 7
de 74 ;11
de 83 ;15
de 57 ; 4
de 67 ; 8
de 76 ;12
de 85 ;16
END
|