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台全てセラロック発振から自己発振に変更しています(基板にはセラロックが付いているが使っていない)。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]