JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

MPLABアセンブラ PIC16F1827 ADCテスト

2024-11-28 13:30:49 | MPLAB アセンブラ
  MPLAB IDE v9.82, MPASM v5.51, PICKit3の環境で、PIC16F1827のADCのテストをします。 

 PIC16F1827は、10bit分解能のADコンバータ(ADC)を12チャンネル持っています。今回はこのADCの使い方を勉強します。

 回路図です。電圧はVRで調整して、17番ピンのAN0(RA0)から入力して、AD変換してその値をシリアル通信で出力してTeraTermで、その値を読み取ります。今回もICSPでプログラミングし、電源(5V)はUSBシリアル変換モジュールFT-234から供給します。PICのクロックは内蔵の4MHzとします。


 AD変換の手順です。
 1 アナログ入力ピンの指定とピンの入力設定
 2 ADCのチャンネル指定とADCを有効にする。
 3 ADCの準備時間(チャージ時間)を待ち、AD変換をスタート
 4 AD変換が終わったら変換結果を取り出す。

 まず、ANSELAレジスタとANSELBレジスタでアナログピンを指定します。


 AN0を使用しますので、bit0を1にして、他のビットは0にします。
 ANSELA=b'00000001'


 AN5~AN11は使わないので、
 ANSELB=b'00000000' つまり、CLRF  ANSELB

 つぎにADCのチャンネルをADCON0レジスタで指定します。


 bit6~bit2でチャンネルを設定します。AN0の場合、CHS4-CHS0=00000
 bit0のADON=1としてADCを有効にします。

 更にADCON1でADCの各種設定をします。
 AD変換結果を右詰めでADRESHとADRESLに格納しますので、bit7のADFM=1とします。また、ADCのクロックは、Fosc=4MHzの1/4で1MHz=1usとしますので、ADCS2-ADCS0=100とします。
 ADCの負参照電圧はVss(GND)としますので、bit2のADNREF=0、正参照電圧は、Vddとしますので、ADPREF1-ADPREF0=00とします。
 以上からADCON1=b'11000000'と設定します。


 EUSARTの設定とバイナリからBCDへの変換は、これまでの記事と同じです。

 プログラムです。1秒ごとにAN0の電圧をAD変換してシリアル通信で出力します。"ADC "+変換値でTeraTermに表示されます。チャージ時間は、MAINループ内で確保できると考え、特にとっていません。
-------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PIC16F1827 ADC TEST
; 2014.11.28
; JH7UBC Keiji Hata
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

              LIST      P=PIC16F1827
              INCLUDE           P16F1827.INC
              
   __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
   __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF
              
              ERRORLEVEL    -302

              CBLOCK             020h
              BYTE0
              BYTE1
              DIGIT12
              DIGIT34
              SHIFT
              WORK1
              TEMP
              CNT1ms
              CNT250ms
              ENDC

SETUP
;クロック設定
              BANKSEL           OSCCON
              MOVLW              b'01101000'         ;PLLなし、4MHz,Fosc
              MOVWF              OSCCON
;入出力設定
              BANKSEL           TRISA
              MOVLW              b'00000001'         ;RA0とRA5は入力、他は出力
              MOVWF              TRISA
              MOVLW              b'00000010'         ;RB1は入力、他は出力
              MOVWF              TRISB
              BANKSEL           ANSELA
              MOVLW              b'00000001'         ;AN0を使用する。AN1-AN4使用しない
              MOVWF              ANSELA
              CLRF     ANSELB                            ;AN5-AN11使用しない
;ADC関係設定
              BANKSEL ADCON0
              MOVLW              b'00000001'         ;AN0を使う。ADC Enable
              MOVWF              ADCON0
              BANKSEL           ADCON1
              MOVLW              b'11000000'         ;右詰め、クロックFosc/4=1us、Vref-=Vss、Vref+=Vdd
              MOVWF              ADCON1
 
;USART設定
;RX,TX PIN 設定
              BANKSEL           APFCON0
              BCF                     APFCON0,7        ;RXDSEL=0 RX=RB1
              BCF                     APFCON1,0        ;RXCKSEL=0 TX=RB2     
              BANKSEL           TXSTA
              MOVLW              b'00100100'
              MOVWF              TXSTA                ;非同期モード、高速通信モードBRGH=1
              BANKSEL           RCSTA
              MOVLW              090h
              MOVWF              RCSTA                ;受信可、非同期モード
              BANKSEL           BAUDCON
              BCF                     BAUDCON,3      ;BRG16=0 BRG 8bit
              MOVLW              019h                    ;019h=25
              MOVWF              SPBRGL                            ;Fosc=4MHz,Baud Rate=9600bps
              
MAIN
              MOVLW              "A"
              CALL     SENDCHR
              MOVLW              "D"
              CALL     SENDCHR
              MOVLW              "C"
              CALL     SENDCHR
              MOVLW              " "
              CALL     SENDCHR
              BANKSEL           ADCON0
              BSF       ADCON0,ADGO ;AD変換スタート
              BTFSC  ADCON0,ADGO ;変換終了まで待つ
              GOTO   $-1
              BANKSEL           ADRESL
              MOVFW              ADRESL                            ;変換結果を格納
              BANKSEL           BYTE0
              MOVWF              BYTE0
              BANKSEL           ADRESH
              MOVFW              ADRESH
              BANKSEL           BYTE1
              MOVWF              BYTE1
              CALL     CONV_BCD        ;バイナリからBCDに変換
              CALL     NUMPRINT
              CALL     LOOP250ms
              CALL     LOOP250ms
              CALL     LOOP250ms
              CALL     LOOP250ms
              GOTO   MAIN

NUMPRINT
              BANKSEL           DIGIT34
              MOVFW              DIGIT34
              MOVWF              WORK1
              MOVWF              TEMP
              SWAPF  TEMP,W
              ANDLW 0Fh                      ;DIGIT34の上位4bitを取り出す
              IORLW  30h                      ;ASCIIコードに変換
              CALL     SENDCHR
              BANKSEL           WORK1
              MOVFW              WORK1
              ANDLW 0Fh                      ;DIGIT34の下位4bitを取り出す
              IORLW  30h                      ;ASCIIコードに変換
              CALL     SENDCHR
              BANKSEL           DIGIT12
              MOVFW              DIGIT12
              MOVWF              WORK1
              MOVWF              TEMP
              SWAPF  TEMP,W
              ANDLW 0Fh                      ;DIGIT12の上位4bitを取り出す
              IORLW  30h                      ;ASCIIコードに変換
              CALL     SENDCHR
              BANKSEL           WORK1
              MOVFW              WORK1
              ANDLW 0Fh                      ;DIGIT12の下位4bitを取り出す。
              IORLW  30h                      ;ASCIIコードに変換
              CALL     SENDCHR
              MOVLW              0Dh                     ;改行コード
              CALL    SENDCHR
     MOVLW       0Ah                      ;NLコード
     CALL     SENDCHR
              RETURN
              
;1文字送信          
SENDCHR
              BANKSEL           TXSTA
              BTFSS   TXSTA,TRMT     ;送信可能かチェック(1:可 0:禁止)
              GOTO   $-1
              MOVWF              TXREG
              RETURN
              
;1文字受信
GETCHR
              BANKSEL           PIR1
              BTFSS   PIR1,RCIF           ;RCIF=1ならスキップ
              GOTO   $-1
              BANKSEL           RCREG
              MOVFW              RCREG
              RETURN
              
;--------------------------------------------
; バイナリからBCDへの変換
;--------------------------------------------
CONV_BCD
              BANKSEL           STATUS
              BCF                     STATUS,C          ;キャリーをクリア
              MOVLW              10h                                    ;16ビットカウンタ
              MOVWF              SHIFT                 ;SHIFT=8 
              CLRF     DIGIT12                           ;BCDデータクリア
              CLRF     DIGIT34
LOOP
              RLF                     BYTE0,F                            ;shift  BYTE to DIGIT
              RLF                     BYTE1,F
              RLF                     DIGIT12,F
              RLF                     DIGIT34,F
              DECFSZ              SHIFT,F              ;end check
              GOTO   ADJST                 ;adjust to BCD
              RETURN
ADJST
              MOVF   DIGIT12,W         ;DIGIT12 adjust TO BCD
              CALL     ADJBCD
              MOVWF              DIGIT12
              MOVF   DIGIT34,W         ;DIGIT34 adjust to BCD
              CALL     ADJBCD
              MOVWF              DIGIT34
              GOTO   LOOP

;****   Each digit adjust to BCD  ****
ADJBCD
              MOVWF              WORK1               ;save
              MOVLW              3                                        ;W+3
              ADDWF WORK1,W
              MOVWF              TEMP
              BTFSC   TEMP,3               ;Test W+3>7
              MOVWF              WORK1               ;>7 then W+3 else W
              MOVLW              030h                    ;W+30
              ADDWF WORK1,W
              MOVWF              TEMP    
              BTFSC   TEMP,7               ;Test W+30>7*
              MOVWF              WORK1               ;>70 then W+30 else W
              MOVF   WORK1,W
              RETURN

;250msタイマー
LOOP250ms
              MOVLW              0FAh                    ;0FAh=250
              BANKSEL           CNT250ms
              MOVWF              CNT250ms
LOOP2
              CALL     LOOP1ms
              DECFSZ              CNT250ms
              GOTO   LOOP2
              RETURN

;1msループ
LOOP1ms
              MOVLW              0F9h                    ;0F9h=249
              MOVWF              CNT1ms
LOOP1
              NOP
              DECFSZ              CNT1ms,F
              GOTO   LOOP1
              RETURN             
              
              END
              
-------------------------------------------------

 ブレッドボードです。


 TeraTermの画面です。
 ボリュームを回すと電圧が変化し、電圧(0~5V)に対応したAD変換値0~1023が表示されました。


 トラブルシューティング

 最初にプログラムを書いた時は、1秒ごとに"ADC 0000"とだけ表示され、ボリュームを回しても数値が変化しませんでした。
 IDEでシミュレーションするとバイナリBCD変換がうまくいっていないことが分かりました。このルーチンは既に何度も使用して動作は確認してあります。
 はて、何が原因か?分かるまで少し時間がかかりました。
 ADRESLとADRESHの値をBYTE0とBYTE1に格納するのですが、ここがうまくいっていませんでした。これまで、BYTE0やBYTE1などのGPRに数値を書き込むときはBANK切り替えを気にしていなかったのですが、この時もBANKSEL  BYTE0などと指定しなければならなかったようです。

 ということで、SFRの時はもちろんGPRの時もBANKSELでレジスタのバンクを指定することにしまいた。これで問題なく動作するようになりました。


最新の画像もっと見る

コメントを投稿