PIC 35:LED 電圧計(7-Segment LED) A


[基板]

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

inserted by FC2 system