Výkonové zesilovače

Z HPM wiki
Přejít na: navigace, hledání

Obsah

Seznam užitečných odkazů k tématu Výkonové zesilovače:

Maxim audio příručka - v závěru jsou uvedeny základní principy jednotlivých tříd zesilovačů

Server HW.cz - zesilovače A až H: Příručka vývojáře moderních audiosystémů - česky podle předchozího odkazu na Maxim

Server elweb.cz - principy zesilovačů třídy D, zmínka o ostatních třídách

Principy zesilovačů třídy D, řízení

Zesilovač třídy D s PAM8403 - Datasheet výrobce, Datasheet, poznámky pro konstrukci,

Ukrajinská konstrukce zesilovače třídy D s AVR na Pandatronu

Ukrajinská konstrukce zesilovače třídy D s AVR v originále

Ukrajinská konstrukce zesilovače třídy D s AVR v originále, 2. link

Zesilovač třídy D s ATtiny45 ze cvičení:

Zesilovač využívá procesor AVR ATtiny45 (ATtiny25, apod.), analogovém 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ů AVR. 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.

Schéma zapojení:

ZesD45.png

Komentovaný program v AVR assembleru pro náš zesilovač:


;ZESILOVAČ D s ATtiny45 

;V131018

 .include "tn45def.inc"

 .def	ZER	= r1		
 .def	TMP	= r16		
 .def	AD_L= r18           ; registry pro L a H část výstupu převodníku
 .def	AD_H= r19		

 .org	0x0000              ; definice vektorů přerušení
  		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              ; adresa začátku programu
 
 Reset:                     ; po startu musíme AVR inicializovat
 		ldi	TMP,(1<<CLKPCE); nastavení CLKPR – Clock Prescale Register
		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  ; načtení L a H části 10-bitového výsledku A/D převodu
     in  AD_H,ADCH
     sbi ADCSRA,ADSC  ; start nové konverze
     lsr AD_H  ; Logical shift right - zůstane nejvyšší bit=znaménko, LSB=AD_8 do Carry
     ror AD_L  ; Rotate right through carry - LSB zahodíme, do MSB Carry=AD_8
; výsledkem je zahozený nejnižší bit 10-bitového A/D převodníku, nejvyšší bit (polarita 
; půlvlny) v AD_H, významnějších 8 bitů velikosti signálu v AD_L
     out OCR1A,AD_L ; PWM hodnota zatím čeká nachystaná v hw bufferu PWM čítače
     reti
 
Timer:
; ted PWM generátor dokončil předchozí cyklus a načetl data pro nový, tj. hardware 
; opravdu provedl update OCR1A, my dodame 2. stranu mustku=polaritu vstupního signálu:

     out PortB,AD_H ; v LSB je připraven presne ten spravny bit
     reti

				
Init: 						; inicializace periferií

; I/O
 		clr	ZER		;
		out	PortB,ZER	; log. 0 na všechny bity PortB
 		ldi	TMP,(1<<PB2|1<<PB1|1<<PB0) ; PB1,2 - repro, PB2 - kontrolní LED
		out	DDRB,TMP	; PB0, PB1, PB2 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      ; kontrolujeme PLL Lock Detector = bit0
		sbrs	TMP,0		; Skip if Bit Set - Je PLL hodin periferií zavěšené?
		rjmp	PLLchk		; když ano, lze hodiny použít, jinak čekáme na zavěšení PLL		
		ldi	TMP,(1<<PCKE|1<<PLLE|1<<LSM) ; nastavení pro 32 MHz hodiny periferií
		out	PLLCSR,TMP	; PCK enable, PLL enable, Low Speed Mode CLKpck:2 
		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<<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




; kontrolní blikání na PB2 pro případ, že nikde nic nežije
Blik:	sbis 	PortB,2
		rjmp	Blik1
		cbi 	PortB,2
		reti
Blik1:	sbi	PortB,2
		reti


Komentovaný program v AVR assembleru pro "ukrajinský" zesilovač:

;*********************************************************************
;	Zesilovač třídy D.
;**************************************
 .include "tn15def.inc"
;**************************************
;	Jména registrů.
 .def	ZER	= r1		
 .def	TMP	= r16		
 .def	TMP1	= r17		
 .def	AD_L	= r18		
 .def	AD_H	= r19		
;**************************************
 .org	$000
  		rjmp	Reset			;
 .org	OVF1addr				;
 		rjmp	Nol			; přerušení po přeplnění časovače T1
 .org	ADCCaddr					;
 		rjmp	Work			; přerušení od A/D přev.
;**************************************
 .org	$009
 
 Reset:
; max. taktovací kmitočet.
 		ser		TMP		; =$FF
		out		OSCCAL,TMP	;  nastaven na max - riskantní
		clr		AD_L		; =0
		clr		AD_H		; =0
; podprogramy inicializace.
		rcall	Ou_in			; porty I/O
		rcall	Ad_n			; ADC
		rcall	Tim_1		 	; časovač T1
		sei


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




;********************************
 Work: ; přerušení od A/D přev.
;********************************
; čtení hodnoty z převodníku
 		in		AD_L,ADCL	; ADC7..ADC0
		in		AD_H,ADCH	; ------ ADC9 ADC8
; spuštění ADC (pro VMLAB).
		sbi		ADCSR,ADSC	;
; posun vpravo o 1 místo.
		lsr		AD_H		; ------- ADC9 (rozlišuje kladnou a zápornou půlvlnu)
		ror		AD_L		; ADC8..ADC1 (8-bitová hodnota, ADC0 zahozen do C)
; kladná půlvlna.				
		sbrc	AD_H,0			; Skip if Bit 0 in Register AD_H Cleared (dolní půlvlna)
		rjmp	Plus			; když ne, tak odskok na Plus
; záporná půlvlna.
		sbrs	AD_H,0			;  Skip if Bit 0 in Register AD_H Set (horní půlvlna)
		rjmp	Minus			; když ne, tak odskok na Minus
 Plus: ; zapnuta kladná.
		cbi		PortB,2		; OUT+ = L    Clear Bit in I/O register
		sbi		PortB,0		; OUT- = H    Set Bit in I/O register
 		reti
 Minus: ; zapnuta záporná.
		cbi		PortB,0		; OUT- = L
		sbi		PortB,2		; OUT+ = H
 		reti


;*********************************************
  Nol: ; přerušení po přeplnění časovače T1
;*********************************************
; obnova registru PWM  	
		out		OCR1A,AD_L	;  Do časovače PWM velikost vst. signálu
		reti
;********************************



; inicializace				
 Ou_in: ; porty I/O.
 		clr		ZER		;
		out		PortB,ZER	;    log. 0 na PortB
 		ldi		TMP,(1<<PB2|1<<PB1|1<<PB0);
		out		DDRB,TMP	;   PB0, PB1, PB2 nastaveny jako výstup
		ret
 
 Ad_n: ; ADC.
 		ldi		TMP,(1<<MUX1|1<<MUX0);
		out		ADMUX,TMP	;    vstup převodníku na PB4/ADC3
		ldi		TMP,(1<<ADEN|1<<ADSC|1<<ADFR|1<<ADIE|1<<ADPS1); |1<<ADPS0
		out		ADCSR,TMP	; mód ADC - enable, start, free running, int.en., CK:8
		ret
 
 Tim_1: ; časovač T1.
 		ser		TMP		; =$FF
		out		OCR1B,TMP	; rozsah PWM = $FF (zhruba odpovídá f=100 kHz)
		out		OCR1A,ZER	; komparační úroveň PWM
		out		TCNT1,ZER	; vynulovat časovač/čítač T/C1
		ldi		TMP,(1<<PWM1|1<<COM1A1|1<<CS10);
		out		TCCR1,TMP	; PWM1 enable, OC1A/PB1 nulován při shodě čítače, CK*16
		ldi		TMP,(1<<TOV1)	; 
		out		TIFR,TMP	; interrupt když nastane overflow T/C1
		out		TIMSK,TMP	; interrupt enable pro overflow T/C1
		ret


První pokusy s AVR mikrokontroléry

Pro první pokus určitě použijte simulátor zabudovaný v programu AVR Studio. Jste-li ve škole v laboratoři 362, je software již připraven. Jinak si AVR Studio nejprve nainstalujte - třeba se podívejte na návod an MAM wiki.

V AVR Studiu založte nový projekt, napište pár instrukcí v assembleru dle instrukčního souboru nebo okopírujte vzorový program a program přeložte a zkuste krokovat. Vše je velmi obrázkové a názorné, takže asi pochopíte, jak se podívat do registrů a ověřit, že instrukce dělají to, co jste čekali.

Jako první úkol zkusíme ovládnout LED připojenou k mikrokontroleru. Pro nízkopříkonové LED stačí přímo proud dodávaný výstupem procesoru, LED jde zapojit podle jednoho z následujících schémat. Trochu lépe spíná výstup k zemi, pro větší proudy nebo při malém napájecím napětí bychom tedy měli preferovat zapojení s LED připojenou k +5 V a spínanou log. L na výstupu. Nesmíme zapomenout nastavit správnou hodnotu sériového rezistoru R1 = (napájecí napětí - úbytek na diodě a na sepnutém výstupu)/požadovaný proud. Pokud potřebujeme vstup z kontaktu, zapojíme ho podle vzoru u vstupu PD5, rezistor R2 nastavuje na vstupu PD5 úroveň H při rozpojeném spínači, ve skutečnosti ho nezapojujeme jako vnější součástku, ale aktivujeme vnitřní pull-up rezistor.

AVR-LED.png AVR-1LED.png

Zajímavé je připojit dvoubarevnou LED, která ma v jednom pouzdře dvě antiparalelně zapojené různobarevné diody. Jak to uděláme je vidět z následujícího schématu, diodu zapojíme mezi dva výstupy a tím řídíme přítomnost a polaritu napětí na diodách. Sériový odpor volíme jako kompromis vzhledem k různým úbytkům na různobarevných LED. Současně je ve schématu nakresleno zjednodušené zapojení spínače na vstupu, vnější rezistor je nahrazen vnitřním pull-up rezistorem v AVR (naznačen čárkovaně), který lze aktivovat vhodnou konfigurací vstupu s měkkou log. H.

AVR-2LED.png

K nastavení módu činnosti jednotlivých bitů I/O portu a pro zápis nebo čtení dat slouží trojice registrů DDRx, PORTx a PINx. DDRx určuje směr, PORT nastavuje výstupní data nebo pull-up rezistor a PINx obsahuje ve všech konfiguracích portu data přečtená ze vstupu podle tabulky


DDRx PORTx I/O pull-up funkce vývodu PINx
0 0 IN ne vstup bez pull-up rezistoru log. úroveň na vývodu
0 1 IN ano vstup s pull-up rezistorem (PORT=1 zde znamená "měkkou H") log. úroveň na vývodu
1 0 OUT ne výstup ve stavu L log. úroveň na vývodu
1 1 OUT ne výstup ve stavu H log. úroveň na vývodu


Pro úplnost, pull-up rezistory lze globálně zakázat dalším konfiguračním bitem (PUD bit v registru MCUCR).


Pro první pokusy můžete použít třeba tento program:


; 
; First ASM Programm for the Evaluation Board
;
; Example of LED blinking program for ATmega168
;

	.equ DDRD = 0x0A	;DDRD address
	.equ PORTD = 0x0B	;PORTD address
	.equ LED = 6	;bit of the output port C with LED

	sbi DDRD, LED	

Main: 
	sbi PORTD, LED	
	rcall Delay_06s	
	cbi PORTD, LED	
	rcall Delay_06s	
	rjmp Main

Delay_06s:
	ldi R16, 3
Delay:
  	inc R1		
	brne Delay	
	inc R2		
	brne Delay	
	dec R16	
	brne Delay
	ret			

Pro přehlednost by měl být program okomentován, navíc zde máme přidanou další funkci:


; 
; First ASM Programm for the Evaluation Board
;
; Example of LED blinking program for ATmega168
;
; LED cathode connected to PORT D bit 6, anode to +Ucc,
; 3 switches S1, S2, S3 connected to PORT C bit 1, 2, 3 (PC1, PC2, PC3),
; connect JP1 to GND
; 

; microcomputer hardware definition
; it is necessary to say the assembler something about our HW:

	.equ DDRC = 0x07	;DDRC address
	.equ PORTC = 0x08	;PORTC address
	.equ PINC = 0x06	;PIND address

	.equ DDRD = 0x0A	;DDRD address
	.equ PORTD = 0x0B	;PORTD address
	.equ PIND = 0x09	;PIND address

;normally we use the complete definition from the definition file:
;	.INCLUDE "m168def.inc"

	.equ LED = 6	;bit of the output port C with LED
	.equ S1 = 1		;bit of the input port D with Switch1


	
; Initialization
	
	sbi DDRD, LED	;Set Bit Immediately - LED pin is output
;	cbi PORTD, LED	;LED ON (LED is ON when log. 0 on this bit) - not necessary, log. 0 from AVR initialization


;	cbi DDRC, S1	;Clear Bit Imm. - not necessary, log. 0 from AVR initialization
	sbi PORTC, S1	;pull-up resistor on the switch input

;
; Main program start
;
; blinking LED
;
;
; modification:
; when S1 pressed then LED continuously ON until S1 released
;    (uncomment the first two lines)
;
; To do: when S2 pressed then LED continuously OFF until S2 released
;
Main: 
	
	sbis PINC, S1	;skip next instruction if bit is set
	rjmp S1_ON	;relative jump to Switch on subroutine

	sbi PORTD, LED	;LED OFF
	rcall Delay_06s	;relative call (not very far) to Delay 0,5 s
	cbi PORTD, LED	;LED ON
	rcall Delay_06s	

	rjmp Main	;loop to start

S1_ON:
	cbi PORTD, LED	;LED ON
	rjmp Main


; Delay loop cca 0,6 s for 1 MHz AVR clock:
;
; based on incrementing/decrementing of the register until 0
;
Delay_06s:
	ldi R16, 3	;prepare for 3 loops of 256x256 loops (1 Clk)
Delay:
  	inc R1		;256 incrementing of R1 (1 Clk)
	brne Delay	;Branch if Not Equal - until 0, then go to R2 (1/2 Clk)
	inc R2		;repeat it 256x (1 Clk)
	brne Delay	; (1/2 Clk)
	dec R16		;and that all do 3x (1 Clk)
	brne Delay	; (1/2 Clk)
	ret			;return after 3+4+(256*256*3+256*3+3)*3-256*3-3 Clk pulses. Why?

Osobní nástroje
Jmenné prostory
Varianty
Akce
Navigace
Nástroje