目次>5章 第2ステップ(色々な実験)>スピーカを使って音を出す(追加実験)>ソース
スピーカを使って音を出す(ドレミ)
更新日2006.2.28
以下のソースを取り込んで、アセンブル→PIC書き込み→実行して下さい。
; ========================== ここから ============================== ; スピーカを鳴らす(ドレミファソラシドを演奏) ; ; PIC16F84A ; CLOCK : 20MHz ; PORTA 0 : OUT スピーカ(LM386で増幅) ; PORTA 2 : OUT LED(0.5秒間隔で点滅) ; ; プリスケーラ : なし ; TMR0初期値 : 128(設定値は138) ; TMR0割込み周期 : 25.6uS ; LIST P=PIC16F84A INCLUDE P16F84A.INC __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF timer EQU 011h save_st EQU 012h ;STATUSのセーブ save_w EQU 013h ;W-regのセーブ cnt5m EQU 014h ;5mSカウンタ(195) 0.0256mS*195=4.992mS cnt500m EQU 015h ;500mSカウンタ(100) cnt1Hz EQU 016h ;周波数(波長)値(tmr0割込み回数) cnt1Hzi EQU 017h ;周波数(波長)値(tmr0割込み回数)の初期値 cnt1mus EQU 018h ;音階(ドレミファソラシド)の指定 ; timer のビット位置 T25uS EQU 0 ;0.0256mSフラグ T500mS EQU 3 ;500mSフラグ counti EQU d'75' ;周波数カウントの初期値 ORG 0 GOTO init ; ●===== 割り込み処理 (タイマ)===== ORG 4 ;割込みの入口 intr BCF INTCON,T0IF ;割込みフラグクリア MOVWF save_w ;W-regセーブ SWAPF STATUS,W MOVWF save_st ;STATUSレジスタセーブ MOVLW d'138' MOVWF TMR0 BSF timer,T25uS ;0.0256mSフラグセット DECFSZ cnt5m,F GOTO intr90 MOVLW d'195' MOVWF cnt5m ;5mSカウンタ初期化 DECFSZ cnt500m,F GOTO intr90 BSF timer,T500mS ;500mSフラグセット MOVLW d'100' MOVWF cnt500m ;500mSカウンタ初期化 intr90 SWAPF save_st,W MOVWF STATUS ;STATUSレジスタロード SWAPF save_w,F SWAPF save_w,W ;W-regロード RETFIE ;割込み許可リターン ; ●===== 初期処理 ===== init CLRF timer ;タイマフラグクリア CLRF cnt1mus ;音階クリア MOVLW d'195' MOVWF cnt5m ;5mSカウンタ初期化 MOVLW d'100' MOVWF cnt500m ;500mSカウンタ初期化 MOVLW counti MOVWF cnt1Hz MOVWF cnt1Hzi BSF STATUS,RP0 ;■バンク1に切替え MOVLW 0FAh MOVWF TRISA ;RA0,2は出力 MOVLW 08h ;プリスケーラ:使用しない(WDTに割り当て) MOVWF OPTION_REG BCF STATUS,RP0 ;■バンク0に切替え CLRF PORTA ;PORTAをクリア MOVLW d'138' MOVWF TMR0 ;TMR0セット MOVLW 0A0h ;TMR0割り込みを使用する MOVWF INTCON ; ===== メイン処理 ===== BSF PORTA,2 main BTFSC timer,T25uS ;0.0256mSフラグON? CALL s25u ;YES BTFSC timer,T500mS ;500mSフラグON? CALL s500m ;YES GOTO main ; ===== 0.0256mSサブルーチン ; 一定周期のパルスを発生させる。 ; ・周期は"cnt1Hzi"で指定する ; ・パルスの出力はRA0 s25u BCF timer,T25uS ;0.0256mSフラグをクリア DECFSZ cnt1Hz,F ;1/2サイクル経過? GOTO s25u90 ; NO MOVF cnt1Hzi,W MOVWF cnt1Hz MOVLW 01h XORWF PORTA,F ;RA0を反転させる s25u90 RETURN ; ===== 500mSサブルーチン ; 音階設定 と ; RA2のLEDを0.5秒毎にON/OFFさせる(タイマ動作の確認用) s500m BCF timer,T500mS ;500mSフラグをクリア ; 音階設定 INCF cnt1mus,F ;音階カウントアップ BTFSC cnt1mus,3 ;1オクターブ終了? CLRF cnt1mus ; Yes MOVF cnt1mus,W CALL doremi MOVWF cnt1Hzi ; パイロットランプ(RA2)点滅 MOVLW 04h XORWF PORTA,F ;RA2を反転させる s500m90 RETURN ; ===== ドレミファソラシド ===== doremi ADDWF PCL,f RETLW d'75' ;ド RETLW d'67' ;レ RETLW d'59' ;ミ RETLW d'56' ;ファ RETLW d'50' ;ソ RETLW d'44' ;ラ RETLW d'40' ;シ RETLW d'37' ;ド END ; =========================== ここまで ===============================