avr 119:Simple A/D 電圧計C


V mater

 avr72-75で「Simple A/D の電圧計」を紹介しました。少し暇が出来たので再び出して色々な実験をした所、幾つかの点が新規に解りました。

 結論を先にいうと「あまり精度は取れないが、能力を知って使えば実用性もあり、それなりに使える」と思います(誤差0.2V)。
 avrの仲間は最近A/D変換機能を内蔵したものが安価に出回っています。それに比べると「Simple A/D の電圧計」は性能的にいまいちで出番はありません、でも今回の実験をここに入れて置きます。

 簡単な電圧表示には使えるかも知れません。作ったものはMax 22Vのものです、本当は8Bitなので255まで扱えるのですが補正しているのでそれ以上は出ません。
 それも補正が細かくしてないので、少し荒っぽいです。でも作ってみると再現性も良くまあまあ使えると思っています。

 写真はセラロックが付いてますが作動していません、内部発振をさせその後取り去っています。
[SOFT=SDCV-7A]



全体の構成

 A/D 変換部分はすこぶる簡単です。CRの充電の電圧上昇と入力電圧を比較しその時間差を数字にして電圧としてLEDに表示するものです。
 電圧はリニアに充電しないのでその補正が必要です、結果を予め調べた数字に補正して表示をさせています。これで誤差0.2V(公表、実際は0.3V程あり、でも内緒!)です。

 LEDはカソードコモン3桁の物を使った、これは「安くて配線が省略出来る」それだけ!の理由です。
 CRは473と約100KΩのコンビでこれは以前のコンビをそのまま使った。

 今回の実験ではAT90S1200Aを使い内部発振約1MHzです。以前「自己発振の動作では不安定で使えない、と思っていました」が実験の結果少し性能は悪化するが自己発振でも十分使えることが解った。

 これでセラロック調達の必要がなくなりより簡単です。全体としてハードの構成は質素になりましたが問題はソフトにウエイトが掛かって来ました。
 手元のセラロックの電圧計からセラロックをはずし自己発振にしても結構使えます。何十台も実験したわけではありませんが、手元の3台全てセラロック発振から自己発振に変更しています(基板にはセラロックが付いているが使っていない)。

SADC Vmater

 8/9ピンはLに設定すると作動する。但し、電源SWを入れた所でチュックしてそれぞれ動作する(後から変更しても受け付けない)。
 動作の変更は一度電源を切ってから変更して電源SWを入れる。


作ってみて

 実験中、以外とVRでのカバー範囲が広くCRを交換したり周波数を変更(セラロックの時)しても「VR調整だけで対応出来る」のにはびっくりでした。
 これならセラロック不用だし、安価なコンデンサ(選別不用)も使えそうだ・・・。

 念の為ドライヤーでコンデンサを加熱すると表示は変わった。これは当初から予想していたもの「温度が上がるとマイラー部分が膨らんで容量が低下する」。ここはあまり変化するとまずい!これに対してはポジスタを付けて幾分補正することにした。

 あと3端子レギュレタはどうかと思い半田ゴテを付けて周波数の変化を見る、やはり発振周波数が変化して0.2Vほど低下した。でも100℃以上も変わることも無いのでこの件はパス(無視)することにした。

 総合的に見ると、セラロックを付けた物を並べた場合は負けるが「安さと簡易さでは面白い」と思いました、元々性能はあまり期待出来ませんからある程度妥協すると考えれば、セラロック無しの電圧計はそれなりに意義があると思います。

 結局、表示誤差を0.2Vまで認めるとすると、まあまあのものが出来上がった。表示の初期変動はやはり0.2V程有り、当初 [10.0V]で調整しスイッチを入れると5分程度で安定しその時[9.8V]の表示となる、まあ安価なので仕方がない、アナログよりましです。

2006/4/27


プログラム [SDCV_7A]プログラム(続き)
;*********************************************************
;Title	:Voltmeter (Symple A/D)	Ver 7A
;MCU	:AT90S1200A 1 MHz
;	:Ver 7 Common casode type LED
;last	:2006/4/9 	BY M.Kikuchi
;*********************************************************
.include "C:\AVRTOOLS\APPNOTES\1200def.inc"
.eseg				;EEPROM segment
.org	0
table1:	.db	$c0,$f9,$a4,$b0,$99,$92,$83,$f8
	;digit	0   1   2   3   4   5   6   7
	.db	$80,$98,$ff,$ff,$ff,$ff,$ff,$bf
	;digit	8   9   a   b   c   d   e   f
	;LED DATA
.cseg				;code segment begin
.org	0
;--------------------------------------------------------
		;A/Cin		 PB0-1
		;led_b-g	 PB2-PB7 a=PD2 dp=PD1
				;PD0 L=*2
.equ	led_dp	= 1		;PD1
.equ	led_a	= 2		;PD2
.equ	led_d1	= 3		;LED digit1 PD3
.equ	led_d2	= 4		;LED digit2 PD4
.equ	led_d3	= 5		;LED digit3 PD5 **.*/L=*.**
.equ	disc	= 6		;dis cherge PD6
.equ	preset	=-8		;for LED span
.def	save	= r0		;temp
.def	temp	= r16		;
.def	ad_c	= r17		;main counter
.def	led_r	= r18		;LED
.def	leddc	= r19		;LED D counter
.def	wark	= r20		;10
.def	warkl	= r21		;1
.def	warkh	= r22		;100
.def	divisor	= r23		; 10
.def	w_c1	= r24		;Wait
.def	w_c2	= r25		;Wait
.def	back_1	= r26		;data_back
.def	back_2	= r27		;data_back
.def	flag	= r30		;bit5 set=dp100 no=dp10
.def	itemp	= r31		;

;Interrupt Vector Address -------------------------------
	rjmp	reset		;Reset handle
	reti			;Ex 0
	rjmp	led_dsp		;timer overflow 0
	reti			;Analog Comparator

reset:	ldi	temp,0b01000110 ;1=out 0=in
	out	DDRD,temp
	ldi	temp,0b00111001	;Pull up
	out	PortD,temp
	ldi	temp,0b11111100	;out LED
	out	DDRB,temp	;
	ldi	w_c2,2		;1mS
	rcall	timer1
	in	temp,PinD	;nead wait
	com	temp
	andi	temp,$38
	mov	flag,temp	;keep
	ldi	temp,0b01111110 ;1=out 0=in
	out	DDRD,temp	; 
	ldi	temp,0b00111001	;PD0=P_UP PD1.2 led_dp/a=L
	out	PortD,temp	;
	ldi	temp,4		;1/256=3.9KHz
	out	TCCR0,temp	;
	ldi	temp,preset	; 8 =2mS
	out	TCNT0,temp	;
	ldi	leddc,0		;LED_d counter
convert_init:
	ldi	temp,0		;AC set/ACD 0=on 1=off/ACIS1=1 ACIS0=0
	out	ACSR,temp	;interrupt off
	out	PortB,temp	;LED off
	ldi	temp,2		;
	out	TIMSK,temp	;timer on
	sei			;set   interrupt
;MAIN ---------------------------------------------------
	rjmp	begin2-1
begin:	cbi	PortD,disc	;capacitor discharg
	ldi	temp,2		;
	out	TIMSK,temp	;timer enable
	rcall	wait0		;100mS LED on
	clr	temp		;
	out	TIMSK,temp	;timer off
	clr	ad_c		;A/D counter reset
	sbi	PortD,disc	;Start charging of capacitor
begin2:	nop
	nop
	sbic	ACSR,ACO	;A/C out ck
	rjmp	begin3		;exit
	inc	ad_c		;+1
	brne	begin2
;warkh=100 wark=10 warkl=1	;over count
	ldi	wark,$0f
	ldi	warkl,$0f
	ldi	warkh,0
	rjmp	begin
begin3:				;Tuning
	mov	wark,ad_c
	cpi	ad_c,118	;
	brsh	begin4
	cpi	ad_c,24		;26-0
	brsh	begin3b		;121-26=normal
	dec	wark		;-1
	cpi	ad_c,18		;
	brsh	begin3b
	dec	wark		;-1
	cpi	ad_c,12		;
	brsh	begin3b
	dec	wark		;-1
begin3b:
	rjmp	b_end
begin4:				;121
	dec	wark		;-1
	cpi	ad_c,132
	brlo	b_end
	dec	wark		;-2
	cpi	ad_c,141
	brlo	b_end
	dec	wark		;-3
	cpi	ad_c,150
	brlo	b_end
	dec	wark		;-4
	cpi	ad_c,158
	brlo	b_end
	dec	wark		;-5
	cpi	ad_c,166
	brlo	b_end
	dec	wark		;-6
	cpi	ad_c,178
	brlo	b_end
	dec	wark		;-7
	cpi	ad_c,185
	brlo	b_end
	dec	wark		;-8
	cpi	ad_c,193
	brlo	b_end
	dec	wark		;-9
	cpi	ad_c,200
	brlo	b_end
	dec	wark		;-10
	cpi	ad_c,206
	brlo	b_end
	dec	wark		;-11
	cpi	ad_c,212
	brlo	b_end
	dec	wark		;-12
	cpi	ad_c,218
	brlo	b_end
	dec	wark		;-13
	cpi	ad_c,224
	brlo	b_end
	dec	wark		;-14
	cpi	ad_c,230
	brlo	b_end
	dec	wark		;-15
	cpi	ad_c,235
	brlo	b_end
	dec	wark		;-16
	cpi	ad_c,240
	brlo	b_end
	dec	wark		;-17
	cpi	ad_c,244
	brlo	b_end
	dec	wark		;-18
	cpi	ad_c,248
	brlo	b_end
	dec	wark		;-19
	cpi	ad_c,252
	brlo	b_end
	dec	wark		;-20
b_end:
;-----------------------------------------------
	clr	warkl
	clr	warkh
	cpi	wark,2		;Min 2>0
	brsh	b_end2
	clr	wark
b_end2:
	sbic	PinD,0		;check PD0
	rjmp	p1		;
	add	wark,wark
	brcc	p1
	ldi	warkl,1
p1:				;Pool
	mov	temp,wark	;copy
	sub	temp,back_1
	brcc	p2
	neg	temp
p2:	cpi	temp,8		;8 under
	brsh	p3
	mov	back_1,wark	;yes
	mov	back_2,warkl
	add	wark,back_1	;*2
	adc	warkl,back_2
	ror	warkl		;1/2
	ror	wark
p3:	mov	back_1,wark	;
	mov	back_2,warkl
	rcall	bto10
	rjmp	begin		;over to repeat
;---------------------------------------------------
;wark(DATA)+warkl=1 to bto11
;binary 9bit(512) to BCD(10)
;warkh=100 wark=10 warkl=1 use temp

bto10:	cpi	wark,100	;100over_ck
	brlo	bto12		;lower
	subi	wark,100	;
	inc	warkh		;add 100
	rjmp	bto10		;loop ck repeat
bto12:	dec	warkl
	brne	bto13
	inc	warkh
	inc	warkh
	clr	warkl
	subi	wark,-56
	rjmp	bto10
bto13:	ldi	divisor,10	;10
	clr	warkl		;
	ldi	temp,9
d_1:	rol	wark
	dec	temp
	brne	d_2
	ret			;end
d_2:	rol	warkl
	sub	warkl,divisor
	brcc	d_3
	add	warkl,divisor
	clc
	rjmp	d_1
d_3:	sec
	rjmp	d_1
;---------------------------------------------------
; timer Interrupt:selected LED digits 1-3 & ON

led_dsp:in	save,SREG	;
	sbi	PORTD,led_d1	;clear
	sbi	PORTD,led_d2	;clear
	sbi	PORTD,led_d3	;clear
	cbi	PortD,led_dp	;[.]clear
	inc	leddc		;
	cpi	leddc,3		;
	breq	led_dsp3	;
	cpi	leddc,2		;
	breq	led_dsp2	;
	cpi	leddc,1		;
	breq	led_dsp1	;
led_dsp3:
	ldi	leddc,0		;
	cpi	warkh,0		;100
	breq	led_dsp4	;
	mov	led_r,warkh	;led_r=DATA and
	rcall	led_on		;LED_Cathode
	sbrc	flag,5		;L=on
	sbi	PortD,led_dp	;[.]
	cbi	PORTD,led_d3	;LED_Anode
	rjmp	led_dsp4	;
led_dsp2:
	mov	led_r,wark	;10
	rcall	led_on		;
	sbrs	flag,5		;
	sbi	PortD,led_dp	;[.]
	cbi	PORTD,led_d2	;
	rjmp	led_dsp4	;
led_dsp1:
	mov	led_r,warkl	;1
	rcall	led_on		;
	cbi	PORTD,led_d1	;
led_dsp4:
	ldi	itemp,preset
	out	TCNT0,itemp	;counter agin
	out	SREG,save	;
	reti			;end

;---------------------------------------------------
;	led_r to LED display	:EEPROM to LEDdata
;***************************************************
led_on:
	sbic	EECR,EEWE	;EEPROM ck
	rjmp	led_on		;loop
	andi	led_r,$0f	;4bit
	out	EEAR,led_r	;send address to EEPROM
	sbi	EECR,EERE	;strobe EEPROM
	in	temp,EEDR	;read decoded number
	lsl	temp		;PB1-7
	com	temp		;add: A to Cathode common
	cbi	PortD,led_a	;
	sbrc	temp,1
	sbi	PortD,led_a	;led set
led_o2:	andi	temp,0b11111100	;input mask
	out	PORTB,temp	;LED bcdefg set
	ret
;--------------------------------------------------
;	WAIT=100mS	for LED display
wait0:	ldi	w_c2,100	;100mS
timer1:	ldi	w_c1,100	;10*100*1=1mS
timer2:	nop
	nop
	nop
	nop
	nop
	nop
	nop
	dec	w_c1		;1
	brne	timer2		;2
	dec	w_c2
	brne	timer1
	ret
;-----------------------------------------------

[もどる]もどる [MENU

inserted by FC2 system