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