目次>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 ; =========================== ここまで ===============================