10bitのA/D変換を使って電圧計にする。[Step 6]
前回でLED3桁に数字"123"が出せるようになったので、今度はA/D変換を使って電圧計にして使ってみる事にしました。
8Bit動作と10Bit動作がありますが「10Bitの0-999の表示」です。ただチラツキが多少含まれるのは仕方が無い!実際に作ってみると、表示のところでチラツキが多くしばらく使えない状態だった。結局割込みのところで一部喧嘩をしているようです。
A/D変換部分の範囲を予定部分よりも広げこの間を動作禁止とした。これでかなりチラツキが減ったが完全ではない、これってデジタルの宿命で本当は後ろの2Bitは削りたいものです。
そこで結局、最終桁表示は強制的に[0-5]にする事にしました。必要によって、スイッチでノーマル(0-9)表示も出来る様にしていつでも見えるようにした。現在[0-9.99]の表示にしてある、これで10V近くまで測れるがこれ以上電圧を加えると壊れる可能性があるので、入力にツエナーでも入れると安心かも知れない。
今の所、電池006Pの電圧表示にでも使おうか!と思っています、ちょうど25mA前後電流が流れ、電池チェック用に適当な負荷になっている。(2007/10/23)その後、PIC16F88から16F819に移植して使っています。以前ICを購入してあまっている為です。(2008/12/24)
プログラム @ プログラム A ;PIC 16F88 ;2007/8/20 BY M.Kikuchi ;8/22 1] LED ON-OFF Progarraming Timer ;9/1 3] Use Timer2 ;9/1 4] Interrupt ON with Timer2 ;9/29 5]16bit data to LED data & Interrupt SW DATA=123 ;10/1 6]A/D ON ;----------------------------------------- LIST P=PIC16F88 INCLUDE "P16F88.INC" __CONFIG 0x2007,0x3f50 __CONFIG 0x2008,0x3ffc ; ERRORLEVEL -302 ;----------------------------------------- LED0 equ 0x04 ;A4 Digit0 LED1 equ 0x06 ;A6 Digit1 LED2 equ 0x07 ;A7 Digit2 TEMP EQU 20H ;tempolary work TE1 EQU 21H ;tempolary work TE2 EQU 22H ;tempolary work CNT1 equ 0x30 ;for Wait CNT2 equ 0x31 ;for Wait ICUT equ 0x32 ;counter LEDD0 equ 0x34 ;LED DATA LEDD1 equ 0x35 LEDD2 equ 0x36 BYTE0 EQU 0x37 ;Bynary data 0 BYTE1 EQU 0x38 ;Bynary data 1 DIGIT12 EQU 0x39 ;BCD1,2 digit DIGIT34 EQU 0x3a ;BCD3.4 digit DIGIT56 EQU 0x3b ;BCD5 digit BACKF equ 0x41 BACK2 equ 0x42 ;----------------------------------------- org 0 goto begin ;------------------------------------------ org 4 ;2007/9/29 Timer2 Interrupt 3LED movwf BACK2 ;keep movf STATUS,W movwf BACKF ;keep incf ICUT ,F movf ICUT ,W sublw 0x03 btfss STATUS,Z goto INT2 clrf ICUT bsf PORTA,LED1 ;off movlw 0x80 btfsc PORTA,5 iorwf LEDD2,W ;Decimal Point btfss PORTA,5 movf LEDD2,W movwf PORTB bcf PORTA,LED2 ;on goto INTEND INT2 movf ICUT,W sublw 0x02 btfss STATUS,Z ; goto INT3 bsf PORTA,LED0 ;off movlw 0x80 btfss PORTA,5 iorwf LEDD1,W ;Decimal Point btfsc PORTA,5 movf LEDD1,W movwf PORTB bcf PORTA,LED1 ;on goto INTEND INT3 bsf PORTA,LED2 ;off movf LEDD0,W movwf PORTB bcf PORTA,LED0 ;on INTEND movf BACKF,W movfw STATUS bcf PIR1,TMR2IF ;clear flag movf BACK2,W retfie ;------------------------------------------ begin call INITA clrf ICUT movlw 0x07 ;Post=1/1 ON Presacle=1/16 ;1Mhz/16/256=4mSec*3 movwf T2CON ;set of Timer2 bsf INTCON,GIE ;Interupt on bsf INTCON,PEIE ; ;Main Program AD_CON movlw b'01001001' ;01=Fosc/8 ch1=001 go * ADON movwf ADCON0 call WAIT_2 ; bcf INTCON,PEIE ;Interrupt off ;GIE or PEIE bsf ADCON0,GO ;start AD AD_CLP btfsc ADCON0,GO goto AD_CLP movf ADRESH,W ;read H andlw 0x03 movwf BYTE1 banksel ADRESL movf ADRESL,W ;read L banksel BYTE0 movwf BYTE0 bcf ADCON0,ADON ;Power off call BITOBCD ;binary to DATA movf DIGIT34,W call BCD_LEDD movwf LEDD2 ;LED 100 swapf DIGIT12,W call BCD_LEDD movwf LEDD1 ;LED 10 movf DIGIT12,W ; 2007/10/2 cut of Last digit btfss PORTA,0x02 ;SW check goto AD_pass andlw 0x0f ;mask sublw 0x05 btfsc STATUS,C movlw 0x00 btfss STATUS,C movlw 0x05 AD_pass call BCD_LEDD movwf LEDD0 ;LED 1 bsf INTCON,PEIE ;Interrupt enable ;----------------------------------------- movlw 0x80 ;TEST WAIT movwf CNT2 MLP call WAIT decfsz CNT2,F goto MLP goto AD_CON ;Repeat ;----------------------------------------- WAIT movlw 0x00 ;1mSec movwf CNT1 W2 nop ;4*256=1mSec decfsz CNT1,F goto W2 WAIT_2 return ;----------------------------------------- ; INITIALIZING PORTA INITA BANKSEL PORTA ; select bank of PORTA CLRF PORTA ; Initialize PORTA by ; clearing output data latches BANKSEL ANSEL ; Select Bank of ANSEL MOVLW 0x03 ; Configure A0/A1=Analog I/O MOVWF ANSEL ; as digital inputs(PIC16F88 DEVICES ONLY) CLRF TRISB ; Set RB<7:0> as output MOVLW B'00101111' ;0=output 1=Input MOVWF TRISA ; Set RA<7:0> as outputs movlw 0x60 ;INTRC=4MHz movwf OSCCON ;set bsf PIE1,TMR2IE ; movlw B'10000000' ;10bit/AVdd-AVss movwf ADCON1 ;9fh BANKSEL PORTB ; clrf PORTB ;off return ;------------------------------------------ ;BCD to 7segments LED data BCD_LEDD andlw 0x0f ;MASK addwf PCL,F retlw 0x3f ;'0' Common Cathode retlw 0x06 ;'1' retlw 0x5b ;'2' retlw 0x4f ;'3' retlw 0x66 ;'4' retlw 0x6d ;'5' retlw 0x7d ;'6' retlw 0x07 ;'7' retlw 0x7f ;'8' retlw 0x6f ;'9' ;----- 16Bit Binary to BCD ----- ; Max 65535 ; BYTE0,1 to DIGIT12,34,5 BITOBCD BCF STATUS,C ;Carry reset MOVLW 010H ;16Bit siftcount MOVWF TE2 ;set CLRF DIGIT12 ;BCD data clear CLRF DIGIT34 CLRF DIGIT56 BLOOP RLF BYTE0,F ;shift BYTE to digit RLF BYTE1,F RLF DIGIT12,F RLF DIGIT34,F RLF DIGIT56,F DECFSZ TE2,F ;End ? GOTO ADJST ;BCD RETURN ;----- BCD ----- ADJST MOVF DIGIT12,W ;DIGIT12 adjust to BCD CALL ADJBCD MOVWF DIGIT12 MOVF DIGIT34,W ;DIGIT34 adjust to BCD CALL ADJBCD MOVWF DIGIT34 MOVF DIGIT56,W ;DIGIT56 adjust to BCD CALL ADJBCD MOVWF DIGIT56 GOTO BLOOP ;----- 1deg BCD tune ----- ADJBCD MOVWF TE1 ;save MOVLW 0x03 ;W+3 ADDWF TE1,W MOVWF TEMP BTFSC TEMP,3 ;Test W+3>7 MOVWF TE1 ;>7 then W+3 else W MOVLW 0x30 ;W+30 ADDWF TE1,W MOVWF TEMP BTFSC TEMP,7 ;Test W+30>7* MOVWF TE1 ;>70 then W+30 else W MOVF TE1,W RETURN ;------------------------------------------ end
2007/OCT/6
もどる [MAIN MENU]