Logo del sito i2viu

WATTMETRO  DI  B.F.  PER  CARICHI  4 - 8 OHM
by Vittorio Crapella - i2viu

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 

 A led con LM3915              Vecchio KIT Amtron UK455

Disclaimer     INDEX             Torna indietro