■ トピック関連記事
無題 投稿者:太郎 投稿日:2008/01/02(Wed) 12:27 No.728

はじめまして。
年始そうそう質問させていただきます。

アセンブラでPICを動かしているのですが最近はAD変換に挑戦しています。
16f877というマイコンを使用します。

自分で書いたプログラムは

;16F877のAD変換

;AN0 = A
;AN1 = D
;AN2 = D
;AN3 = D
;AN4 = D

;*********************************************
;AD変換の説明
;*********************************************

;1.ADモジュールの構成を設定 (初期化処理)
; どのピンでAD変換するか決める。→ADCON1
; AD変換のスイッチをオンにする。→ADCON0

;2.AD変換の準備のため待つ。
; 入力取得時間経過を待つ 20μ秒

;3.変換をはじめる。
; ADCON0のGOを1にするとAD変換が始まる。

;4.変換が終わったか調べる。
; AD変換が終わるとADCON0のGOが0になるので比較演算等の処理をするのはそれからにする。

;5.変換結果を読み込む。
; 変換結果がADRESHとADRESLに入っているので、どこか他の場所に移す。

;*********************************************
LIST P=PIC16F877
INCLUDE "P16f877.inc"
__CONFIG _HS_OSC & _PWRTE_ON & _WDT_OFF & _LVP_OFF
;*********************************************

CBLOCK 024h
TIMCNT ;タイマ用カウンタ
TIM2CNT
TIM5CNT
TIM1CNT

ADHK_H ;AD変換の値(上の8ビット)
ADHK_L ;AD変換の値(下の8ビット)

PORTB_OUT
ENDC

;*********************************************************
ORG 0
;*********************************************************
;<ここで1番>
SET_IO ;初期処理
BSF STATUS,RP0 ;これからピンの設定をする。
BCF INTCON,GIE ;(割り込み禁止)
MOVLW 0EH
MOVWF ADCON1 ;RA0のみアナログ、(ADFM=0(結果左詰))
MOVLW 07H
MOVWF OPTION_REG ;(内部クロック、プリスケーラ1:256)

MOVLW 01H
MOVWF TRISA ;ポートAのRA0は入力、他は出力
CLRF TRISB ;ポートBを出力モードに設定
CLRF TRISC ;ポートCを出力モードに設定
CLRF TRISD ;ポートDを出力モードに設定
CLRF TRISE ;ポートEを出力モードに設定
BCF STATUS,RP0 ;これでピンの設定は終わり。
MOVLW 080H ;A/Dコンバータをオフにする。
MOVWF ADCON0 ;ADCON0に080hを書き込むとオフになる。

ADSTART ;A/D変換をはじめる。

MOVLW 081H ;(Fosc/32,ch0,A/D on)
MOVWF ADCON0 ;ADCON0に081hを書き込むとオンになる。

;<ここで2番>
CALL TIM20 ;20μsec待ち = AD変換には時間が必要。

;<ここで3番>
BSF ADCON0,GO ;AD変換スタート

WAITE ;AD変換結果待ち

;<ここで4番>
BTFSC ADCON0,GO ;AD変換が終わるとADCON0のGOが0になるので調べている。
GOTO WAITE ;終わっていないなら前に戻る。

;<ここで5番>
;AD変換された値を読み込む。
MOVF ADRESH,W ;(AD上位ビット(左詰め))
MOVWF ADHK_H
BSF STATUS,RP0 ;(バンク1へ切替)
MOVF ADRESL,W
BCF STATUS,RP0 ;(バンク0に戻す)
MOVWF ADHK_L

;************************************************************
;AD変換の結果はADHK_HとADHK_Lに入ってる。
;ここからメインの処理を書く。

MOVF ADHK_L,W
MOVWF PORTB

GOTO ADSTART

;************************************************************

TIM20 ;約20μSECタイマ
MOVLW 012H
MOVWF TIMCNT
TIMLP
DECFSZ TIMCNT,F
GOTO TIMLP
RETURN
TIM02 ;約0.2mSECタイマ
MOVLW 0FFH
MOVWF TIM2CNT
TIM2LP NOP
DECFSZ TIM2CNT,F
GOTO TIM2LP
RETURN

;*********************************************************
END

なのですが、まともに動いてくれません。
もしかしたら回路的にも間違っているのかもしれません。
プログラム的にはどうでしょうか?
判定よろしくお願いします。

Re: 無題 - yas   2008/01/03(Thu) 13:13 No.729
あけましておめでとうございます
初めまして太郎さん
私もPIC初心者です 気になってシミュレーションしてみましたが
正常に動作しました
手持ちで877が無ので実機では確認していません
一応 コンパイルの通ったプログラムアップしておきます
まぁ 上のプログラムですが ^^;

877のDIPタイプを入手したら試してみます

[添付]: 3211 bytes

Re: 無題 - yamasan   2008/01/05(Sat) 11:14 No.730
 太郎さん、はじめまして。yasさんと同じく私も 16f877は使ったことがないので
正確ではないですが、全体としてはプログラムは特に問題となる箇所はわかりませんでした。
 ただ、TIM20の 20[uS]は、定数の設定が違っていると思われます。次の TIM02の定数から
察すると 20[MHz]の水晶orセラロックで動いていると思われます。
現在の 012Hでは 11[uS]程度となるはずです。0x21H で 20[uS]程度になるはず。
でも、A/Dのチャネルを切り替えていないので、これがうまく動かない原因とは思えませんが。
 結果の確認は PORTBに LED8個つけてされているのでしょうか?。
そこらへんも書いていただけると参考になるかも。
 また PORTBに出力するのは ADHK_Hがわかりやすいのでは?。
 タイマのところにコメントをつけたソースを添付します(ちょっといい加減ですが)。

[添付]: 608 bytes

処理 記事No 暗証キー

- Joyful Note -