|
WATTMETRO DI B.F. PER CARICHI 4 - 8 OHM |
Quello che segue è il progetto di un Wattmetro capace di misurare potenze fino a 150W e mostrare il valore su 3 digit di tipo a 7 segmenti utilizzando un ST6220 che legge la tensione con l'ADC proveniente da un circuito di condizionamento fatto da un raddrizzatore a doppia semionda con operazionale LM358.
Il micro ST6 prende il valore letto con ADC ne fa il quadrato e poi divide per 400 e mette il risultato a tre cifre gestendo la virgola indicando potenze da 0,01 W fino a 150 W.
Tramite un deviatore è possibile leggere potenze sia per carichi da 4 sia da 8 Ohm mantenendo lo stesso fondo scala di 150W.
La foto mostra il display che segna 14,4 Watt e il multimetro che segna i volt efficaci sul carico di 4 Ohm
Pw = V2 / R = 7,54 x 7,54 / 4 = 56,85 / 4 = 14,2 W il display segna 14,4 W
Per la taratura dei trimmer sull'entrata si può fare prendendo una tensione del secondario di un trasformatore con tensione compresa tra 9 e 15Vac ma va bene anche 18 Vac oppure direttamente prelevando la tensione su una cassa dell'ampli mentre riproduce ad un livello costante un segnale a frequenza fissa ad esempio 1Khz.
La procedura migliore è la seguente:
1- accertarsi che LM358 sia alimentato correttamente e che in uscita dia 0V quando entra 0V.
2- regolare i trimmer a metà corsa e mettere il deviatore sui 4 Ohm
3- staccare provvisoriamente l'ingresso ADC dall'uscita del 358
4- inviare il segnale d'ingresso proveniente da un trasformatore o dall'amplificatore
5- misurare la tensione alternata reale in entrata con voltmetro Vac (valore efficace)
6- misurare la tensione in continua con multimetro ai capi del 10uF in uscita del 358
7- regolare il trimmer T1 per leggere sul multimetro (punto 6) pari a Vac punto 5 diviso 5
8- deviare sugli 8 Ohm e regolare il trimmer T2 per leggere sul multimetro (punto 6)
pari a Vac punto 5 diviso 7
9- Unire ADC out con ADC in e controllare che quanto indicato sul display sia uguale ai W calcolati con la formula Vac al quadrato diviso 4 o 8 Ohm a seconda del caso, se necessario ritoccare i trimmer per una migliore taratura.Sono state verificate misure per frequenza comprese tra 20 Hz e 8 KHz senza notare variazioni significative di potenza misurata.
Superato gli 8 KHz man mano che la frequenza sale sul display la potenza indicata tende a calare questo a causa dei diodi 1N4148 che cominciano a far sentire il loro limite.
Usare diodi più veloci sicuramente permettono misure anche a frequenza superiore, un diodo ideale già utilizzato in altre occasioni è il BA243.File ZIP con .ASM, .HEX e schemi .GIF
Foto della realizzazione di Sergio G.
LISTATO
.title "POWER BF" ;23-12-2009 By Vittorio C. i2viu .vers "ST62E20" .w_on ; Abilita la memoria a finestre a .def 0ffh ;Registro accumulatore x .def 080h ;Registro x y .def 081h ;Registro y v .def 082h ;Registro v w .def 083h ;Registro w port_a .def 0c0h ;Registro Dati porta A port_b .def 0c1h ;Registro Dati porta B port_c .def 0c2h ;Registro Dati porta C pdir_a .def 0c4h ;Registro Direzione porta A pdir_b .def 0c5h ;Registro Direzione porta B pdir_c .def 0c6h ;Registro Direzione porta C popt_a .def 0cch ;Registro Opzioni porta A popt_b .def 0cdh ;Registro Opzioni porta B popt_c .def 0ceh ;Registro Opzioni porta C ior .def 0c8h ;Registro Opzioni per le Interruzioni addr .def 0d0h ;Registro Dati dell'A/D converter adcr .def 0d1h ;Registro di Controllo dell'A/D converter psc .def 0d2h ;Registro per il Prescaler del Timer tcr .def 0d3h ;Registro Dati del Timer tscr .def 0d4h ;Registro TSCR del Timer wdog .def 0d8h ;Registro del WatchDog drw .def 0c9h ;Registro della zona dati ROM (Rom Data Window) ;-------------------------------------- ; VARIABILI usate da questo programma ;-------------------------------------- decimi .def 084h ;display unita .def 085h ; " decine .def 086h ; " resto .def 087h ;divisione risul .def 088h aa .def 089h ;per contare le conversioni n1 .def 08ah ;byte più significativo MSB n2 .def 08bh ;byte meno significativo LSB n3 .def 08ch ;divisore rislsb .def 08dh ;risultato LSB rismsb .def 08eh ;risultato MSB punto .def 08fh ;virgola display ;*************************** ;*** Settaggio iniziale *** ;*************************** .org 080h ;080h per 20/25 mentre 880h per 10/15 inizio ; INIZIALIZZAZIONE DELLE PERIFERICHE ldi wdog,0ffh ; RICARICA IL WATCH DOG clr decimi clr unita ldi punto,11110111b ; 0,0 ldi decine,15 ;*** Setta la porta A ldi pdir_a,11111111b ;disponibili solo pa0,1,2,3 ldi popt_a,11111111b ; tutti ouput ldi port_a,11111111b ;*** Setta la porta B ldi pdir_b,00011111b ;pa0,1,2,3,4 output ldi popt_b,00011111b ;pa5 in poi ADC ldi port_b,00100111b ; rimanenti non utilizzati conf. input ldi adcr,0 ;DISABLE A/D INTERRUPT ldi tscr,0 ;DISABLE TIMER INTERRUPT ldi ior,0 ;DISABLE ALL INTERRUPT reti ;RIPRISTINA I FLAG PRINCIPALI jp main ;SALTA AL PROGRAMMA PRINCIPALE ;********************************************* ;* SUBRINE DI INTERRUPT * ;********************************************* ad_int ;INTERRUPT DEL CONVERTITORE A/D reti tim_int ;INTERRUPT DEL TIMER reti BC_int ;INTERRUPT DELLE PORTE A e B reti A_int ;INTERRUPT DELLA PORTA A reti nmi_int ;INTERRUPT NON MASCHERABILE reti ;********************* ;*** SUBROUTINE *** ;********************* display ld a,decimi ;cifra di destra DECIMALI ld port_a,a ;mette sulla porta i DECIMI res 0,port_b ;abilita trans. decimali call delay set 0,port_b ;disabilita tr decimali ld a,unita ;prende UNITA` ld port_a,a ;mette sulla porta UNITA res 1,port_b ;abilita transiStore UNITA call delay set 1,port_b ld a,decine ;DECINE ld port_a,a ;mette sulla porta le DECINE res 2,port_b ;abilita tr decine call delay set 2,port_b rito ret ;ritorna delay ldi y,100 ;circa 2 mS di ritardo decy dec y ldi wdog,255 jrnz decy ret ;----------------------------------------------------------------------------------------- ;DIVISIONE 2 byte divisore in n1 e n2 dividendo in n3 ;Divide un numero compreso tra 1 e 65025 espresso ; in due byte N1 (=msb) e N2 (=lsb) ;con un divisore a 1 byte (1-255) ;restituisce 2 byte RISMSB-RISLSB ;----------------------------------------------------------------------------------------- divid ldi wdog,254 ;carico wdog clr rismsb ;azz. byte risultato MSB clr rislsb ;azzeramento risultato LSB ld a,n3 ;divisore jrnz ldn1 fine ret ldn1 ld a,n1 ;carico nel reg a il byte + significativo jrnz div ;se non e` zero salto ld a,n2 ;altrimenti prendo byte - significativo jrz fine jp ancora ;e vado a dividere div ld a,n2 ;prendo il byte - signif. suba ldi wdog,254 sub a,n3 ;sottraggo una volta n2-n3 jrc decn1 inc rislsb ;suppongo già che n3 ci stia una volta in n2 jrnz suba inc rismsb jpsu jp suba ;se a>= n2 continuo a sottrarre e inc risultato decn1 inc rislsb jrnz decn inc rismsb decn dec n1 ;chiedo riporto al byte + significativo jrz ancora ;e se n1 non e` zero continuo a sottrarre jp suba ancora ldi wdog,254 sub a,n3 ;sottraggo ancora jrc ok jrz okk_ inc rislsb ;incremento ancora il risultato jp ancora ;e continuo fino a che n2>n3 okk_ inc rislsb jp ldre ok add a,n3 ldre ld resto,a ;cosi da avere in a il resto ret ;____________________________ ;LEGGE ADC e VISUALIZZA ;____________________________ attendi clr resto clr risul ldi aa,255 averr1 ldi wdog,255 ldi pdir_b,00011111b ldi popt_b,00111111b ;configura pora B come ADC ldi a,00111111b and a,punto ;gestione punto display ld port_b,a ldi adcr,00110000b ;abilita A/D att jrr 6,adcr,att ;attende conversione nop ld a,addr ;mette in a il valore convertito add a,resto ;somma il precedente valore con il nuovo jrnc averr2 ;se non c’è riporto salta inc risul ;altrimenti incrementa averr2 ld resto,a ld a,aa ;verifica se ha eseguito 255 conversioni jrnz decaa jp averr4 ;se si salta decaa dec aa ;altrimenti un conversione in meno ldi popt_b,00011111b call display jp averr1 ;continua a convertire averr4 ld a,resto ;arrotonda cpi a,127 ;se a <127 salta jrc averr3 ;altrimenti arrotonda incrementando risul inc risul ;valore mediato 255 volte va in a averr3 ld a,risul ret ;FA IL QUADRATO quadrat ldi wdog,255 clr v ;azzera reg v ld w,a ;per contare quante volte sommare dec w ld x,a ;valore in x da usare per sommare ad a somma add a,x ; somma a+x jrnc decw inc v ;MSB ldi wdog,255 decw dec w ;conta le volte jrnz somma ;se non ha finito salta ld n2,a ;n2= LSB ld a,v ;mette MSB in a ld n1,a ;n1=MSB ret ;DIVIDE PER 4 div4 ldi n3,4 ;altrimenti divide per 4 call divid set 3,punto ;punto decimale 0,0X res 4,punto clr decine clr unita ld a,rislsb ld decimi,a ret ;****************************************** ;PROGRAMMA PRINCIPALE ;****************************************** main ldi wdog,255 call attendi ;legge tensione cpi a,2 jrnc calqua ;se minore di 1 potenza troppo bassa e ricomincia clr decimi clr unita ldi decine,15 ;decine spente ldi punto,11110111b ; 0,0 jp main calqua call quadrat ;fa il quadrato di ADC cpi a,0 ;a contiene MSB e se MSB>0 jrnz div40 ;salta e divide per 40 ld a,n2 ;altrimenti verifica LSB cpi a,40 jrnc div40 ;se >= 40 va a dividere per 40 call div4 jp main div40 ldi n3,40 ;n1 e n2 sono già messi quando fa quadrato call divid ld decimi,a ;a=resto resto in decimi ld a,rismsb ;verifica se non è 0 jrz cpia10 ;se non è 0 allora ld n1,a ;riprende rismsb e lo mete in n1 per dividerlo ld a,rislsb jp ldn2 cpia10 ld a,rislsb cpi a,10 jrnc div10 set 3,punto ;punto decimale 0,XX res 4,punto clr decine ld unita,a ;risul in unita call aggiust jp main div10 clr n1 ;prepara x divisione ldn2 ld n2,a ;rislsb in n2 ldi n3,10 ;divisore call divid ;1a divisone x 10 ;ld decimi,a ;ricorda resto ld a,rislsb ;rismsb è sicuramente 0 riprende cpi a,10 ;pertanto verifica solo risLSB jrnc div10_ ;se >= 10 salta e divide ancora set 3,punto ;altrimenti punto decimale X,XX res 4,punto jp main_ div10_ clr n1 ;prepara x divisione ld n2,a ;e rislsb in n2 ldi n3,10 ;divisore call divid ;2a divisone x 10 ld a,rislsb cpi a,10 jrnc ldare ;se >= salta res 3,punto set 4,punto ;punto decimale XX,X jp main_ ldare ld a,resto ; a= resto ultia divisione ld decimi,a clr n1 ;prepara per divisone ld a,rislsb ld n2,a ldi n3,10 call divid ;3a divisione res 3,punto ;senza virgola res 4,punto ld a,resto ld unita,a ;secondo resto ld a,rislsb ld decine,a jp main main_ ;DUd (D)ecine (U)nita (d)ecimi ld a,resto ;XXX ld unita,a ;secondo resto ld a,rislsb ld decine,a call aggiust jp main aggiust ld a,decimi cpi a,4 jrc ret_ clr n1 ;prepara x divisione ld n2,a ;rislsb in n2 ldi n3,4 ;divisore call divid ld a,rislsb ld decimi,a ret_ ret ;------------------------- ;VETTORI DI INTERRUPTS ;------------------------- .org 0ff0h jp ad_int ;A/D int vector #4 jp tim_int ;timer int vector #3 jp BC_int ;port B & C int vector #2 jp A_int ;port A int vector #1 .org 0ffch jp nmi_int ;nmi int vector #0 jp inizio ;reset vector .end