目次>5章 第2ステップ(色々な実験)>スピーカを使って音を出す>ソース
スピーカを使って音を出す(ソース)
更新日2006.1.29
以下のソースを取り込んで、アセンブル→PIC書き込み→実行して下さい。
; ========================== ここから ==============================
; スピーカを鳴らす
; 50Hzから10,000Hzまで序所に変化させる
;
; PIC16F84A
; CLOCK : 20MHz
; PORTA 0 : OUT スピーカ
; PORTA 2 : OUT LED(0.5秒間隔で点滅)
;
; プリスケーラ : なし
; TMR0 : 0
; TMR0割込み周期 : 0.0512mS
;
LIST P=PIC16F84A ; LIST宣言で使用するPICを16F84Aと定義する。
INCLUDE P16F84A.INC ; 設定ファイルp16f84a.incを読み込む。
__CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
onoff EQU 010h
timer EQU 011h
save_st EQU 012h ;STATUSのセーブ
save_w EQU 013h ;W-regのセーブ
cntHz EQU 014h ;周波数(波長)値(tmr0割込み回数)
cntHzi EQU 015h ;周波数(波長)値(tmr0割込み回数)の初期値
cnt10m EQU 016h ;10mSカウンタ(195) 0.0512mS*195=9.984mS
cnt100m EQU 017h ;100mSカウンタ(10)
cnt500m EQU 018h ;500mSカウンタ(50)
; timer のビット位置
T005mS EQU 0 ;0.05mSフラグ
T10mS EQU 1 ;10mSフラグ
T100mS EQU 2 ;100mSフラグ
T500mS EQU 3 ;500mSフラグ
counti EQU d'195' ;周波数カウントの初期値
ORG 0
GOTO init
; ●===== 割り込み処理 (タイマ)=====
ORG 4 ;割込みの入口
intr
BCF INTCON,T0IF ;割込みフラグクリア
MOVWF save_w ;W-regセーブ
BSF timer,T005mS ;0.05mSフラグセット
DECFSZ cnt10m,F
GOTO intr90
BSF timer,T10mS ;10mSフラグセット
MOVLW d'195'
MOVWF cnt10m ;10mSカウンタ初期化
DECFSZ cnt100m,F
GOTO intr50
BSF timer,T100mS ;100mSフラグセット
MOVLW d'10'
MOVWF cnt100m ;100mSカウンタ初期化
intr50
DECFSZ cnt500m,F
GOTO intr90
BSF timer,T500mS ;500mSフラグセット
MOVLW d'50'
MOVWF cnt500m ;500mSカウンタ初期化
intr90
SWAPF save_w,f
SWAPF save_w,w ;W-regロード
RETFIE ;割込み許可リターン
; ●===== 初期処理 =====
init
CLRF timer
CLRF onoff
MOVLW d'195'
MOVWF cnt10m ;10mSカウンタ初期化
MOVLW counti
MOVWF cntHz
MOVWF cntHzi
MOVLW d'10'
MOVWF cnt100m ;100mSカウンタ初期化
MOVLW d'50'
MOVWF cnt500m ;500mSカウンタ初期化
BSF STATUS,RP0 ;■バンク1に切替え
MOVLW 0FAh
MOVWF TRISA ;RA0,2は出力
MOVLW 08h ;プリスケーラ:使用しない(WDTに割り当て)
MOVWF OPTION_REG
BCF STATUS,RP0 ;■バンク0に切替え
CLRF PORTA ;PORTAをクリア
CLRF TMR0 ;TMR0セット
MOVLW 0A0h ;TMR0割り込みを使用する
MOVWF INTCON
; ===== メイン処理 =====
BSF PORTA,2
main
BTFSC timer,T005mS ;0.05mSフラグON?
CALL s005m ;YES
BTFSC timer,T10mS ;10mSフラグON?
CALL s10m ;YES
BTFSC timer,T100mS ;100mSフラグON?
CALL s100m ;YES
BTFSC timer,T500mS ;500mSフラグON?
CALL s500m ;YES
GOTO main
; ===== 0.05mSサブルーチン
; 一定周期のパルスを発生させる。
; ・周期は"cntHzi"で指定する
; ・パルスの出力はRA0
s005m
BCF timer,T005mS ;0.05mSフラグをクリア
DECFSZ cntHz,F ;1/2サイクル経過?
GOTO s005m90 ; NO
MOVF cntHzi,W
MOVWF cntHz
BTFSS onoff,0 ;前回の1/2サイクルはON?
GOTO s005m50 ;NO
;YES
BCF PORTA,0 ;今回の1/2サイクルをOFF
BCF onoff,0 ;前回の1/2サイクル表示をOFF
GOTO s005m90
s005m50
BSF PORTA,0 ;今回の1/2サイクルをON
BSF onoff,0 ;前回の1/2サイクル表示をON
s005m90
RETURN
; ===== 10mSサブルーチン
; 10m秒毎に周波数(波長)を変える
s10m
BCF timer,T10mS ;10mSフラグをクリア
; DECFSZ cntHzi,F
; GOTO s10m90
; MOVLW counti
; MOVWF cntHzi
s10m90
RETURN
; ===== 100mSサブルーチン
; 100m秒毎に周波数(波長)を変える
s100m
BCF timer,T100mS ;100mSフラグをクリア
DECFSZ cntHzi,F
GOTO s100m90
MOVLW counti
MOVWF cntHzi
s100m90
RETURN
; ===== 500mSサブルーチン
; RA2のLEDを0.5秒毎にON/OFFさせる(タイマ動作の確認用)
s500m
BCF timer,T500mS ;500mSフラグをクリア
BTFSS PORTA,2 ;RA2がONなら
GOTO s500m10
BCF PORTA,2 ; OFFにする
GOTO s500m90
s500m10
BSF PORTA,2 ; OFFならONにする
s500m90
RETURN
END
; =========================== ここまで ===============================