目次>8章.機能が豊富なPICを使う(PIC12F683)>A/D変換を使う>ソース
A/D変換を使う(PIC12F683)(ソース)
更新日2006.10.14
以下のソースを取り込んで、アセンブル→PIC書き込み→実行して下さい。
; ========================== ここから ==============================
;
; PIC12F683
; clock:INTOSCIO 4MHz
;
; A/D変換とPWMの動作確認
; A/D変換結果で音の高さ(PWM周期)を変える
;
; GP2(CCP1:PWM) : スピーカ
; GP4(AN3) : 可変抵抗
; GP5 : LED(0.5秒毎に点滅)
;
; TMR0割込み
; TMR0:0(フリーラン)
; 割込み周期:(1/4MHz)*4*256 = 256uS
;
;
LIST P=12f683
#INCLUDE <p12f683.inc>
__CONFIG _CP_OFF & _CPD_OFF & _WDT_OFF & _BOD_ON & _IESO_OFF& _PWRTE_ON & _INTOSCIO & _MCLRE_OFF
save_st EQU 020h ; STATUSのセーブ領域
save_w EQU 021h ; W-regのセーブ領域
CNT10mS EQU 022h ; TMR0割り込み(256uS)を39回カウントするカウンタ=9.984mS
CNT01S EQU 023h ; 9.984mSを10回カウントするカウンタ=99.84mS
CNT05S EQU 024h ; 99.84mSを5回カウントするカウンタ=499.2mS
acq EQU 025h ; アクィジション時間用カウンタ
AD_save EQU 026h ; A/D変換結果格納領域
timer EQU 027h ; タイマフラグ(0:256uS,1:10mS,2:100mS,3:500mS)
T256uS EQU 00h ; TMR0割込み
T10mS EQU 01h ; 10mS
T100mS EQU 02h ; 100mS
T500mS EQU 03h ; 500mS
ORG 0
GOTO INIT
; ==============================================================
ORG 4
; TMR0割込み
INTR
BCF INTCON,T0IF ;割込みフラグクリア
MOVWF save_w ;W-regセーブ
SWAPF STATUS,W
MOVWF save_st ;STATUSレジスタセーブ
BSF timer,T256uS ;256uSフラグセット
DECFSZ CNT10mS,F
GOTO INTR90
MOVLW d'39'
MOVWF CNT10mS ;10mSカウンタ初期化
BSF timer,T10mS ;10mSフラグセット
DECFSZ CNT01S,F
GOTO INTR90
BSF timer,T100mS ;100mSフラグセット
MOVLW d'10'
MOVWF CNT01S ;100mSカウンタ初期化
DECFSZ CNT05S,F
GOTO INTR90
BSF timer,T500mS ;500mSフラグセット
MOVLW d'5'
MOVWF CNT05S ;500mSカウンタ初期化
INTR90
SWAPF save_st,W
MOVWF STATUS ;STATUSレジスタロード
SWAPF save_w,F
SWAPF save_w,W ;W-regロード
RETFIE ;割込み許可リターン
; ==============================================================
; PICの初期化
INIT
; GPIO(GP2-0)をデジタルI/Oに設定
MOVLW 07h
MOVWF CMCON0 ;GP2-0はデジタルIO
BSF STATUS,RP0 ;■バンク1
; A/D変換の設定
MOVLW 018h
MOVWF ANSEL ;GP4/AN3(3番ピン)のみアナログ入力,8Tosc(2.0uS)
MOVLW 010h
MOVWF TRISIO ;GP0-3,5は出力,GP4(AN3)は入力
BCF STATUS,RP0 ;■バンク0
MOVLW 0Dh
MOVWF ADCON0 ;A/D結果:左詰め,基準電圧:Vdd,チャネル:AN3,A/D有効
; 内部クロックを4MHzに設定
BSF STATUS,RP0 ;■バンク1
MOVLW 060h
MOVWF OSCCON ;CLOCK=4MHz
; PWMの設定
MOVLW D'239'
MOVWF PR2 ;PWM周期
BCF STATUS,RP0 ;■バンク0
MOVLW D'118' ;
MOVWF CCPR1L ;PWMデューティーサイクル
MOVLW 0Ch
MOVWF CCP1CON ;PWMモード
MOVLW 07h
MOVWF T2CON ;Timer2 ON ,プリスケーラ:16
CLRF TMR2
; タイマ用カウンタの設定
MOVLW d'39'
MOVWF CNT10mS ; TMR0割り込み(256uS)を39回カウントするカウンタ=9.984mS
MOVLW d'10'
MOVWF CNT01S ; 9.984mSを10回カウントするカウンタ=99.84mS
MOVLW d'5'
MOVWF CNT05S ; 99.84mSを5回カウントするカウンタ=499.2mS
CLRF timer
; TMR0割込みの設定
BSF STATUS,RP0 ;■バンク1
MOVLW 08h ;プリスケーラ:使用しない(WDTに割り当て)
MOVWF OPTION_REG
BCF STATUS,RP0 ;■バンク0
CLRF TMR0 ;TMR0セット
MOVLW 0A0h ;TMR0割り込みを使用する
MOVWF INTCON
; ==============================================================
; メイン処理
CALL acquisition
BSF ADCON0,GO ;A/D変換開始
MAIN
BTFSS ADCON0,GO ;A/D変換完了?
CALL ADread
; BTFSC timer,T500mS ;500mSフラグセット?
; CALL S500mS
BTFSC timer,T10mS ;10mSフラグセット?
CALL S10mS
GOTO MAIN
; ===== A/D変換完了 =====
ADread
MOVF ADRESH,W ;A/D変換結果読み出し
MOVWF AD_save
CALL acquisition
BSF ADCON0,GO ;A/D変換開始
RETURN
; ===== ホールド用コンデンサの充電を待つ時間(20u秒) =====
acquisition
MOVLW d'5'
MOVWF acq
acq_loop
DECFSZ acq,F
GOTO acq_loop
RETURN
; ===== 10mS経過処理(PWMの周期にA/D変換結果をセット) =====
S10mS
BCF timer,T10mS ;10mSフラグクリア
MOVF AD_save,W
BSF STATUS,RP0 ;■バンク1
MOVWF PR2 ;A/D変換結果をPWM周期にセット
BCF STATUS,RP0 ;■バンク0
MOVWF CCPR1L ;PWMデューティーサイクル
BCF STATUS,C ;デューティを
RRF CCPR1L,F ;周期の1/2にする
; CLRF TMR2
RETURN
; ===== 500mS経過処理(LEDを0.5秒毎に点滅) =====
S500mS
BCF timer,T500mS ;500mSフラグクリア
MOVLW 020h ;GP5を
XORWF GPIO,F ;前回ONならOFFに、OFFならONに
RETURN
END
; =========================== ここまで ===============================