Questo semplice progetto mostra come sia possibile regolare due uscite di un convertitore boost utilizzando il microcontrollore Tiny13 AVR dell’Atmel/Microchip. In particolare vengono sfruttate la periferica interna di conversione analogico-digitale e i PWM che il piccolo ma efficiente microcontrollore mette a disposizione.
La maggior parte dei dispositivi portatili fa uso di batterie e allo stesso tempo integra uno o più microcontrollori. Sul mercato esistono microcontrollori in grado di funzionare fino a 1,8 V e in questo caso due semplici batterie stilo di tipo AA o AAA sono sufficienti per alimentare il dispositivo. Tuttavia, molto spesso, sono richieste anche tensioni superiori necessarie per esempio per il funzionamento dei LED di retro illuminazione di uno schermo LCD che solitamente richiedono tensioni superiori ai 5 V. In questo caso risulta indispensabile utilizzare un convertitore DC/DC di tipo boost, che con un po’ di componentistica aggiuntiva permette di innalzare il livello di tensione al valore richiesto.
Il convertitore DC/DC boost
La tipica struttura circuitale di un convertitore boost è schematizzata in figura 1.
Si tratta di un regolatore switching dove la tensione di uscita raggiunge valori superiori alla tensione d’ingresso. Esistono due tipologie di regolatori boost: quelli che operano in CCM (Continuous Conduction Mode) o in DCM (Discontinuous Conduction Mode). La tipologia DCM è più facile da realizzare e deve il suo nome al fatto che la corrente che scorre nell’induttanza diventa nulla per un breve istante durante il periodo della forma d’onda PWM. In modalità CCM la corrente nell’induttanza non è mai nulla. Sempre con riferimento alla figura 1, quando lo switch è in posizione “on” la massima corrente scorre nell’induttanza al termine del periodo alto dell’uscita PWM raggiungendo il seguente valore:
dove VDC è la tensione d’ingresso, D è il duty cycle e T è il periodo dell’onda PWM. L è il valore dell’induttanza utilizzata. La corrente attraverso il diodo scende a zero in un tempo TR pari a:
La corrente che arriva al carico si può ottenere come media della corrente che passa per il diodo, quindi:
Andando a sostituire le equazioni precedentemente ricavate otteniamo:
da cui è possibile ricavare la tensione d’uscita:
Dal valore del condensatore in uscita dipende il ripple presente su VOUT, si ha dunque:
dove dV/dt rappresenta la caduta di tensione durante il periodo del segnale PWM, I è la corrente al carico e C è il valore di capacità richiesto. Il periodo totale del PWM è T ed è costante, D come detto è il duty cycle del PWM e TR è il tempo in cui il diodo rimane in conduzione. Al termine del tempo TR la corrente del diodo si azzera. Il periodo dell’onda PWM è quindi T>DxT+TR per la modalità di regolatori boost DCM. La differenza tra i due termini della disequazione è il tempo morto, o dead time, in cui la corrente nell’induttore è nulla. Nello schema di figura 1 è riportato un interruttore ideale; nella realtà si utilizza un BJT o un MOSFET, quest’ultimo da preferire poiché può lasciare passare correnti elevate garantendo efficienze migliori e tempi di commutazione ridotti. In alcuni casi, specie quando si lavora a basse tensioni, è difficile reperire un MOSFET in grado di lavorare con una tensione ridotta tra gate e source, o almeno può risultare poco economico, allora si preferisce utilizzare i BJT.
Un microcontrollore per gestire il regolatore boost
Cerchiamo ora di utilizzare un microcontrollore di dimensioni ridotte, dotato solamente di otto pin, per creare ben due convertitori boost. Il microcontrollore è il Tiny13 AVR della ATMEL. In uscita scegliamo di generare due tensioni di 7,5 V e 15 V partendo da una tensione di 3 V. Il progetto è completamente scalabile e può essere modificato per ottenere molteplici valori della tensione d’uscita, solamente variando il software del microcontrollore. Come detto al termine del paragrafo precedente, utilizziamo dei BJT per il nostro convertitore boost, ottenendo il circuito in figura 2.
Attraverso il microcontrollore possiamo generare delle onde PWM a frequenza da 10 kHz a più di 200 kHz, anche se le frequenze alte sono da preferire poiché consentono di ridurre il valore dell’induttore e quindi anche le sue dimensioni. Il Tiny13 AVR ha un “fast” PWM mode in cui arriva a 37,5 kHz con una risoluzione di 8 bit. Ovviamente una risoluzione superiore garantirebbe una maggiore precisione e finezza nella generazione di un determinato valore di tensione in uscita. Attraverso la prima equazione ottenuta nel paragrafo precedente si può determinare la corrente massima nell’induttanza che risulta di 0,81 A se scegliamo L=20 uH. Il transistor di conseguenza deve essere scelto in maniera da poter tollerare una corrente di collettore superiore a tale valore. Per il progetto scegliamo un transistor NPN, il 2SD789, che ha una corrente di collettore di 1 A. Sempre dalle equazioni ricavate in precedenza calcoliamo la massima corrente che può essere fornita al carico per l’uscita a 7,5 V, che risulta di 54 mA. Poiché il Tiny13 può gestire due uscite PWM e quattro canali ADC a 10 bit, utilizziamo il secondo canale PWM e un ulteriore ADC per ottenere l’uscita a 15 V con una corrente massima al carico di 15 mA. In questo caso l’induttanza scelta ha il valore di 100 uH. L’ultimo passo è il calcolo della capacità d’uscita. Se desideriamo tollerare un ripple di 5 mV, il valore della capacità risulta per l’uscita a 7,5 V di 270 uF, calcolato per una corrente di 50 mA con un periodo del PWM pari a 27 usec. Utilizziamo quindi il valore commerciale più prossimo al valore ottenuto, arrotondando sempre in eccesso e inseriamo una capacità di 330 uF. Allo stesso modo per la seconda uscita a 15 V si ottiene un valore di 81 uF arrotondato a 100 uF.
Un microcontrollore per gestire il regolatore boost
Il software di controllo del microcontrollore è riportato nel listato 1.
#include<avr/interrupt.h> #include<avr/io.h> #define vref 931 // 931 is 1V for a 1.1 internal reference #define MAX_A 70 #define MAX_B 128 volatile unsigned int adc_val[2]; SIGNAL (SIG_ADC) { unsigned int temp, temp1; unsigned char ch; ADCSRA &= ~(1<<ADEN);//ADC disabled temp1=ADCL; temp = ADCH; temp = temp << 8; temp =temp | temp1; ch = ADMUX & 0x01;//channel number //ch = ch ^0x01; //ADMUX = ch | 0x40; if(ch==0) adc_val[0]=temp; else adc_val[1]=temp; ADMUX = ADMUX ^ 0x01; // toggle last bit of MUX to change ADC channel ADCSRA = 0b11101100; //enable ADC ADCSRA = 0b11101100; ch = PORTB ^ 0b00000100; PORTB = ch; } int main(void) { unsigned int ad_temp, temp; DDRB = 0b00000111; TCCR0A = 0b10100011; //Fast PWM on OC0A and OC0B // TCCR0A - Timer/Counter Control Register A // ————————————————————————————- // |COM0A1|COM0A0|COM0B1|COM0B0| – | – | WGM01| WGM00| // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | // ————————————————————————————- TCCR0B = 0b00000001; //Fed by System Clock of 9 600 000 divided by 1 = 9.6 MHz // TCCR0B - Timer/Counter Control Register B // ————————————————————————- // |FOC0A|FOC0B| – | – |WGM02| CS02| CS01| CS00| // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | // ————————————————————————- ADMUX = 0b01000010; //ADC2 is input to ADC // ADMUX - ADC Multiplexer Selection Register // ————————————————————————- // | - |REFS0|ADLAR| - | - | - | MUX1| MUX0| // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | // ————————————————————————- ADCSRA = 0b11101100; //Sampling rate is system clock divided by 16 // ADCSRA - ADC Control and Status Register A // ————————————————————————- // |ADEN |ADSC |ADATE| ADIF| ADIE|ADPS2|ADPS1|ADPS0| // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | // ————————————————————————- ADCSRB=0; DIDR0 = 0b00011000; //Disable Digital input buffer on PB3 and PB4 // DIDR0 - Digital Input Disable Register 0 // ————————————————————————- // | – | – |ADC0D|ADC2D|ADC3D|ADC1D|AIN1D|AIN0D| // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | // ————————————————————————- adc_val[0]=0; adc_val[1]=0; sei(); OCR0A =MAX_A; OCR0B = MAX_B; while(1) { ad_temp = adc_val[0]; if(ad_temp < vref) { OCR0A++; if( OCR0A > MAX_A) OCR0A = MAX_A; } ad_temp = adc_val[0]; if(ad_temp > vref) { OCR0A—; if( OCR0A > MAX_A) OCR0A = 0; } ad_temp = adc_val[1]; if(ad_temp < vref) { OCR0B++; if( OCR0B > MAX_B) OCR0B = MAX_B; } ad_temp = adc_val[1]; if(ad_temp > vref) { OCR0B—; if( OCR0B > MAX_B) OCR0B = 0; } for(temp=0; temp <300; temp++) { temp = temp +1; temp = temp -1; } } }
Listato 1 |
Il programma è scritto in C e utilizza il compilatore AVRGCC open source, disponibile all’indirizzo web www.avrfreaks.net. Il Tiny13 lavora utilizzando un clock interno di 9,6 MHz senza un divisore interno, per tale motivo la frequenza del PWM è ottenuta dalla frequenza di clock attraverso una divisione per 256. La tensione di riferimento interna e di 1,1 V. Il programma principale alternativamente legge i due canali ADC che monitorano le tensioni d’uscita utilizzando routine a interrupt. Il ciclo di main ripete perennemente le operazioni di lettura dei valori di monitoraggio degli ADC e di conseguenza va a regolare i valori dei PWM.
Come si nota, anche i progetti più avanzati a microcontrollore dipendono in gran parte dall’elettronica discreta. Le nuove generazioni dovrebbero studiare massivamente non solo la programmazione di sistemi embedded ma anche molta elettronica generale e i suoi principi più importanti.
D’accordo, ormai i transistor non si studiano quasi più…
Ritengo che la teoria sia sempre e comunque importante. Certo, la polarizzazione dei transistor non ha forse più l’importanza, a livello pratico, che aveva un tempo: oggi si sintetizzano circuiti digitali combinando e muovendo milioni di transistor in un colpo solo. I componenti attuali ad elevata integrazione semplificano i circuiti, aumentano l’affidabilità e riducono i costi. Esistono comunque ancora settori (come l’elettronica analogica e soprattutto RF) dove esperienza, professionalità e conoscenza delle caratteristiche fisiche ed elettroniche dei componenti sono fondamentali.