Caricabatteria USB con ATmega

Caricabatteria USB conATmega

Una connessione USB, un microcontrollore ATMega ed un convertitore DC/DC sono tutto quello che serve per realizzare un caricabatterie per celle a ioni di litio. Scopriamo come Nel 2008 Atmel ha introdotto la nuova famiglia di microcontrollori ATmega16/ 32U4 che combinano interfaccia USB 2.0 e funzionalità analogiche ad elevate prestazioni. Grazie a queste caratteristiche, tali microcontrollori rappresentano una soluzione ideale per sistemi a basso costo e con alimentazione da porta USB per applicazioni come accessori per console di gioco (ad esempio gamepad) o caricabatterie.

E proprio di ciò, un caricabatterie per celle a ioni di litio, parleremo in questo articolo. Di seguito sono riportati i punti salienti dell’applicazione che è basata sulla scheda di valutazione EVK527 per ATmega16/ 32U4; i dettagli sono discussi nell’Application Note di Atmel.

Il problema della carica delle batterie

Prima di presentare i dettagli dell’applicazione, può essere utile introdurre brevemente il problema della carica delle batterie a ioni di litio. Le batterie agli ioni di litio sono la tecnologia oggi più diffusa per le celle ricaricabili. Tra i vantaggi principali vi sono una bassa resistenza interna, un tempo di vita elevato, tempi di carica inferiori, l’assenza di un effetto memoria della cella, una più bassa auto-scarica, minore tossicità.

Lo svantaggio principale è invece legato alla scarsa tolleranza dei dispositivi a sovracarica; in questo caso potrebbero verificarsi elevati assorbimenti di corrente ed un rapido incremento della temperatura interna del dispositivo che potrebbe andare in fuga termica. Non sono rari i casi segnalati di batterie ricaricabili utilizzate in apparecchiature consumer (computer portatili, ad esempio) che sono esplose, provocando non pochi danni, proprio per problemi al circuito di carica. La procedura di carica di una batteria agli ioni di litio prevede tre diverse fasi, come mostrato schematicamente in figura 1.

carica_celle_ioni_di_litio_procedura

Le prime due sono a corrente costante mentre la terza a tensione costante. Il passaggio tra le prime due fasi è dettato dal raggiungimento di soglie per la tensione della cella. Il processo di carica termina invece quando, nell’ultima fase di carica a tensione costante, la corrente assorbita, che decresce nel tempo, scende al di sotto di una soglia. I valori delle soglie e delle correnti di carica da applicare per le diverse fasi sono definiti dal costruttore e specifici della particolare serie di batterie; i valori in figura 1 sono da riferirsi ad una batteria della seria VARTA ™ EasyPack da 550mAh.

Il cuore del circuito: l’ATmega

Per realizzare il nostro circuito caricabatteria, tutto quello che ci occorre sono quindi una tensione di alimentazione in ingresso (ad esempio a 5V), un circuito di conversione DC/DC per generare la tensione di carica della batteria ed un microcontrollore per controllare il processo di carica secondo lo schema indicato in precedenza. Tutte queste risorse sono disponibili sulla scheda di sviluppo EVK527 mostrata in figura 2. La scheda, infatti, si basa su un micro ATmega32U4 con 32 KB di memoria Flash, porta USB 2.0 e ADC a 12 canali e dispone di un circuito di conversione DC/DC con topologia buck e controllo di tipo PWM generato direttamente dal microcontrollore.

La porta USB può essere usata sia per derivare l’alimentazione per la scheda ed il circuito di carica della batteria che come linea di comunicazione con un terminale remoto. L’ATmega32U4 è un microcontrollore con architettura RISC con capacità di calcolo fino a 16 MIPS; include un register file di 32 x 8 locazioni ed un moltiplicatore embedded in grado di eseguire un’operazione in 2 cicli di clock. Include 32KByte di memoria flash in-system selfprogrammable, 2.5 KByte di memoria SRAM ed EEPROM di dimensioni 1 KByte. Dispone, come detto, di una porta USB 2.0 in grado di sostenere data rate in trasferimento fino a 12 Mbps ed di un convertitore ADC a 12 canali e 10-bit di risoluzione. Integra un circuito PLL, timer e counter ad 8 e 16 bit, diversi canali PWM anche per applicazioni high-speed, interfaccia SPI master/slave e porta USART programmabile con controllo di flusso hardware.

Supporta tensioni di alimentazione tra 2.7 V e 5.5V; la corrente assorbita, ad una frequenza di clock di 4 MHz, è di solo 2.2 mA, rendendo così ideale il dispositivo per applicazioni con alimentazione da porta USB. L’Application Note [3] mostra come implementare una porta di comunicazione virtuale CDC (communication device class) mediante l’interfaccia USB, realizzando così un semplice convertitore USB-seriale tramite l’ATmega. Questa stessa funzionalità è usata nel caso del nostro caricabatteria per stabilire un canale di comunicazione tra la scheda di sviluppo EVK527 ed un terminale remoto per l’invio di informazioni relative allo stato del processo di carica. Il convertitore ADC dell’ATmega è invece usato per controllare costantemente lo stato di carica della batteria.

Il circuito di conversione DC/DC

Come accennato in precedenza, per generare la tensione di carica della batteria occorre un circuito di conversione della tensione DC/DC. La scheda utilizza un convertitore buck il cui schema di principio è mostrato in figura 3. I convertitori buck sono convertitori in continua di tipo step-down caratterizzati da elevata efficienza (tipicamente maggiore del 95%). Il principio di funzionamento su cui si basano è piuttosto semplice; un induttore viene caricato e scaricato alternativamente attraverso un diodo ed uno switch (tipicamente un transistor) per trasferire energia dall’ingresso verso il carico.

convertitore_buck_schema_principio

Se la corrente attraverso l’induttore non si riduce mai a zero, il convertitore opera in modalità continua seconda lo schema temporale riportato in figura 4a. In questo caso, quando lo switch è chiuso il diodo è contro polarizzato; quindi non conduce. L’induttore assorbe energia dall’ingresso e la corrente aumenta linearmente. Quanto lo switch viene aperto, il diodo viene forzato in conduzione e l’induttore eroga l’energia immagazzinata; l’intensità della corrente decresce linearmente nel tempo.

convertitore_buck_funzionamento

Il rapporto tra la tensione di ingresso e quella di uscita è dato dal duty cycle del periodo di commutazione dello switch. Se invece l’induttore si scarica completamente durante l’intervallo di off dello switch, il convertitore opera in modalità discontinua (figura 4b); la tensione di uscita in questo caso è funzione anche del valore dell’induttore, del periodo di commutazione dello switch e della corrente assorbita dal carico. Nel nostro caso, lo switch del convertitore buck viene controllato direttamente dal microcontrollore sfruttando una delle uscite PWM disponibili a bordo dell’ATmega; in questo modo sarà possibile controllare in maniera precisa il duty-cycle del periodo di commutazione e quindi, per quanto osservato in precedenza, la tensione di uscita del circuito.

Il clock per il circuito PWM viene generato internamente al microcontrollore mediante PLL e post-scaler; la frequenza impostata è la massima consentita di 64 MHz, così da ottenere la massima risoluzione possibile nella modulazione del duty-cycle. Il segnale PWM di controllo risultante ha un periodo 250 KHz.

Il software applicativo

Il software applicativo del nostro caricabatteria può essere scaricato dall’indirizzo web indicato nei riferimenti [2]. Prima di usare la scheda di sviluppo per applicazioni proprie, tenere presente che l’esempio è stato sviluppato per una particolare batteria Varta; nel caso quindi di batterie diverse andranno modificati opportuni parametri del software onde evitare di danneggiare il nostro dispositivo. Nell’Application Note ed all’interno dello stesso codice sorgente sono chiaramente riportati i punti dove apportare le modifiche necessarie.

Il listato 1 riporta la funzione main() dell’applicativo che è stato sviluppato per gestire il caricabatteria. Come si vede è piuttosto semplice e schematica. La funzione Usb_enable_regulator() abilita il regolatore interno per i pads USB; tipicamente viene disabilitato per applicazioni con tensioni di alimentazione inferiore a 3.5V per ottimizzare la dissipazione di potenza. Quindi, la funzione wdtdrv_disable() disabilita il watchdog timer del microcontrollore.

Listato 1

int main(void)
{
Usb_enable_regulator();
wdtdrv_disable();
start_boot_if_required();
Clear_prescaler();
scheduler();
return 0;
}

In seguito viene avviato il boot-loader start_boot_if_required() – e resettato il prescaler del clock interno della CPU – clear_prescaler(). Infine viene attivato lo scheduler(). Tale scheduler è un loop infinito che richiama in sequenza i task che sono stati abilitati all’interno del file conf_scheduler.h; non è implementato nessuno schema di pianificazione in tempo reale ma, semplicemente, al termine di un task è chiamato quello immediatamente successivo nella sequenza predefinita. Il ciclo infinito è preceduto dalla inizializzazione dei diversi task previsti mediante chiamata delle apposite funzioni relative. Nella nostra particolare applicazione sono previsti i seguenti tre task : usb_task(), cdc_task() e batt_task(). I primi due si riferiscono alla gestione della porta seriale e della comunicazione con il terminale remoto. Il terzo invece controlla il processo di carica della batteria. Il cuore della funzione è una macchina a stati implementata secondo il diagramma di flusso riportato in figura 5.

macchina_a_stati_diagramma_flusso

Il listato 2 evidenzia la parte di codice corrispondente all’interno del file sorgente batt_task.c. Ad ogni stato, come si vede, è associato un puntatore a funzione che viene usato per chiamare la funzione appropriata all’inizio del ciclo. Ognuna delle funzioni ritorna a sua volta il prossimo stato.

Listato 2

123. unsigned char CurrentState; //!< \brief Global that indicates current state
124. //!<
125. //!< Updated by main().
126. //!< \note See menu.h for definition of states.
127. unsigned char nextstate, inp;
128. unsigned char (*pStateFunc)(unsigned char); // Function pointer.

397. //wait a complete ADC conversion to update batt measurements
398. ADC_Wait();
399. // Run function associated with current state, get next state in return.
400. if (pStateFunc != NULL){
401. nextstate = pStateFunc(inp);
402. }
403. // Look up function for next state, if it differs from the current.
404. if (nextstate != CurrentState) {
405. CurrentState = nextstate;
406. for ( i = 0; menu_state[i].state != 0; i++) {
407. if (menu_state[i].state == CurrentState) {
408. pStateFunc = menu_state[i].pFunc;
409. }
410. }
411. }

Il ciclo inizia con la chiamata alla funzione ADC_Wait() che consente di aggiornare i parametri dello stato di carica della batteria; questa stessa funzione viene anche chiamata ripetutamente all’interno delle altre funzioni di stato per verificare come proseguire nel processo. Nell’Application note sono chiaramente descritti tutti gli stati previsti e le funzioni associate. La funzione charge(), in particolare, gestisce il processo di carica nelle diverse fasi di pre-qualifica, carica a corrente costante e carica a tensione costante in accordo allo schema discusso inizialmente.

Per gentile concessione di:
rivista firmware
STAMPA     Tags:

Leave a Reply