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