Zesilovač v třídě D

Z MAM wiki

Verze z 26. 3. 2012, 19:53; Horcik (diskuse | příspěvky)
(rozdíl) ← Starší verze | zobrazit aktuální verzi (rozdíl) | Novější verze → (rozdíl)
Přejít na: navigace, hledání

Zesilovač v třídě D

Zesilovač využívá procesor AVR ATtiny45 (ATtiny25, apod.), analogový vstup je v AVR nakonfigurován jako diferenční se zesílením 20 a referenčním napětím (=plný rozsah při zesílení 1) 1,1 V, z toho plyne povolená amplituda vstupního signálu 55 mV špička-špička, necelých 20 mV efektivní hodnoty sinusového průběhu. Analogový vstup tvoří upínací obvod R1-R2-C1, který posune vstupní signál na stejnosměrnou úroveň zhruba poloviny Ucc a přivede ho na jeden z diferenčních vstupů A/D převodníku mikropočítače. Na druhý vstup je přivedena stejnosměrná složka téhož napětí vyfiltrovaná dolní propustí R3C2, AVR převede střídavou složku bipolárním A/D převodníkem na desetibitové číslo ve dvojkovém doplňku. Znaménkový bit výsledku potom přepíná jednu polovinu H-můstku s reproduktorem, druhá polovina můstku je řízena PWM signálem z nejvyšších 8 bitů převedeného čísla, nejnižší bit není využit.

Schéma zapojení:

Vzorový program:


;ZESILOVAČ D s ATtiny45

 .include "tn45def.inc"

 .def	ZER	= r1		
 .def	TMP	= r16		
 .def	AD_L= r18		
 .def	AD_H= r19		

 .org	0x0000
  		rjmp	Reset
 .org	OVF1addr			; přerušení po PWM1 overflow
 		rjmp	Timer	
 .org	ADCCaddr	
 		rjmp	ADconv		; přerušení po ukončení A/D převodu

 .org	0x0010
 
 Reset:
 		ldi		TMP,(1<<CLKPCE);
		out		CLKPR,TMP	; příprava zápisu pro předdělič hodin
 		ldi		TMP,(1<<CLKPS1);
		out		CLKPR,TMP	; předdělič hodin CK:4 (=>2 MHz)
 		clr		AD_L		; =0
		clr		AD_H		; =0

; podprogramy inicializace I/O, ADC, TC1

		rcall	init	

		sei					; enable všech interruptů


;***************************************
 Main: 	rjmp	Main		; hlavní program (nekonečná smyčka)


ADconv:
     in  AD_L,ADCL
     in  AD_H,ADCH
     sbi ADCSRA,ADSC
     lsr AD_H
     ror AD_L
     out OCR1A,AD_L ; PWM hodnota zatím čeká v hw bufferu
     reti
 
Timer:
     ; ted hardware opravdu provedl update OCR1A, my dodame 2. stranu mustku:
     out PortB,AD_H ; v LSB je nahodou presne ten spravny bit
     reti

				
Init: 						; inicializace periferií

; I/O
 		clr		ZER		;
		out		PortB,ZER	; log. 0 na PortB
 		ldi		TMP,(1<<PB2|1<<PB1|1<<PB0)

		out		PortB,TMP

		out		DDRB,TMP	; PB0, PB1 nastaveny jako výstup
 
; PWM v časovači 1A
		ldi		TMP,(1<<PLLE|1<<LSM);
		out		PLLCSR,TMP	; PLL enable, Low Speed Mode CLKpck:2 pro 32 MHz perif.
		rcall 	Wait		; wait trochu více než povinných 100 us pro PLL lock
PLLchk:	in		TMP,PLLCSR
		sbrs	TMP,0		; Je PLL hodin periferií zavěšené?
		rjmp	PLLchk		; když ano, lze hodiny použít		
		ldi		TMP,(1<<PCKE|1<<PLLE|1<<LSM)
		out		PLLCSR,TMP	; PCK enable, Low Speed Mode CLKpck:2 pro 32 MHz perif.
		ldi		TMP,(1<<TOV1)	; 
		out		OCR1A,ZER	; komparační úroveň PWM
		out		TCNT1,ZER	; vynulovat časovač/čítač T/C1
		ldi		TMP,(1<<PWM1A|1<<COM1A1|1<<CS11|1<<CS10);
		out		TCCR1,TMP	; mód Fast PWM, OC1A nulován při shodě čítače, bez předděliče
 		ldi		TMP,(1<<PCKE|1<<LSM);
		out		TIFR,TMP	; interrupt, když nastane overflow T/C1
		ldi		TMP,(1<<TOIE1)
		out		TIMSK,TMP	; interrupt enable pro overflow T/C1

;ADC
 		ldi		TMP,(1<<MUX2|1<<MUX1|1<<MUX0|0<<ADLAR|1<<REFS1)
		out		ADMUX,TMP	; bipol. vstup převodníku na PB4/ADC2-PB3/ADC3, G=20, Uref 1,1 V
		ldi		TMP,(1<<ADEN|1<<ADSC|1<<ADIE|1<<ADPS1|1<<ADPS0|0<<ADATE)
		out		ADCSRA,TMP	; mód ADC - enable, start, NOT free running (0<<ADATE), int.en., CK:16 (125 kHz)
		ldi		TMP,(1<<BIN)
		out		ADCSRB,TMP	; bipolární vstup
		ldi		TMP,(1<<ADC3D|1<<ADC2D)
		out		DIDR0,TMP	; disabluje digitální vstupy na analogových vývodech
		ret 

Wait:	ldi		TMP,0x4F	; wait cca 3*80 cyklů
Wait1:	dec		TMP
		brne	Wait1
		ret

Osobní nástroje