Sul blog di Elettronica Open Source puoi leggere non solo tutti gli articoli Premium riservati agli abbonati Platinum 2.0 e inseriti nella rivista Firmware 2.0 (insieme ad articoli tecnici, progetti, approfondimenti sulle tecnologie emergenti, news, tutorial a puntate, e molto altro) ma anche gli articoli della Rubrica Firmware Reload. In questa Rubrica del blog abbiamo raccolto gli articoli tecnici della vecchia rivista cartacea Firmware, che contengono argomenti e temi evergreen per Professionisti, Makers, Hobbisti e Appassionati di elettronica. Nonostante l’MSP430 di Texas Instruments sia un microcontrollore piuttosto datato, ancora oggi è molto utilizzato e tiene testa ai più moderni chip presenti sul mercato. In questo articolo ne verranno illustrate le caratteristiche ed alcuni esempi applicativi.
Introduzione
La famiglia MSP430 della Texas Instruments è ormai nota a molti essendo presente nel settore dei microprocessori di piccolo taglio e basso consumo (pochi kbytes di flash, basso pin count) ormai da più di dieci anni. I dispositivi più recenti della famiglia meritano però di essere analizzati attentamente per le loro particolari caratteristiche. Sarà trattata quindi una parte degli innumerevoli dispositivi che compongono la famiglia e precisamente gli MSP430F20XX. Di questi dispositivi verrà dato solo un riassunto delle caratteristiche principali per poter passare subito all’utilizzo pratico senza dover conoscere tutta la ricca documentazione disponibile. Sarà interessante scoprire come è possibile avere la potenza elaborativa di un RISC con consumi di pochi mA (250mA per MIPS).
CARATTERISTICHE GENERALI
La famiglia MSP430 integra un core RISC a 16 bit ed una architettura di memoria von-Neumann (è possibile anche eseguire codice residente RAM). Il punto di forza della serie MSP430 sono sempre stati i bassi consumi di corrente che permettono di avere una ritenzione dati in RAM con soli 0,1mA!, funzionamento in modalità real-time-clock con soli 0,8mA e 250mA per MIPS in funzionamento normale. Le tensioni di lavoro vanno da un minimo di 1,8V ad un massimo di 3,6V. La memoria flash del codice è programmabile dallo stesso micro permettendo quindi di usarla a piacere per la memorizzazione di dati (logging), upgrade del codice operativo e parametri. La generazione del clock di sistema è possibile mediante un quarzo convenzionale oppure a basso consumo da 32kHz (quello degli orologi da polso), oppure con un efficientissimo generatore digitale di clock interno che non necessita di componenti esterni. Nel microprocessore sono state introdotte tutte le risorse HW necessarie per l’attività dell’emulatore, permettendo una gestione di tutte le risorse in-circuit via JTAG. La memoria, come già accennato, è di piccolo taglio; infatti, il più capace della famiglia possiede 2kb di flash e 128bytes di RAM. Le risorse potranno sembrare esigue, ma un assembler molto potente ed un compilatore C altrettanto efficiente permettono comunque di realizzare dei progetti interessanti. Tutte le caratteristiche descritte d’ora in poi fanno esplicito riferimento all'MSP430F2013 (salvo dove diversamente specificato) un 14 pin SMD che è il dispositivo utilizzato nella scheda demo fornita con il sistema di sviluppo.
MAPPA DELLA MEMORIA
Le risorse di memoria del 2013 sono di 2kbyte di flash per il codice, 128 byte di RAM e di 256 byte di information memory. Quest'ultima è un'area di flash, aggiornabile dal microprocessore in run time (come d’altra parte tutta la flash), che permette la personalizzazione del codice mediante la memorizzazione di parametri variabili, di quella temporanea di dati e sostituisce la tipica EEPROM esterna. Anche tutte le periferiche sono “memory-mapped” ovvero vengono lette e scritte come delle semplici locazioni di memoria. Per i dettagli sugli indirizzi delle singole aree di memoria e delle periferiche vedere la Figura 2 oppure rifarsi al foglio specifiche del microprocessore (individuabile sul sito Texas con la sigla SLAS491C). La particolarità della memoria flash è che può essere programmata dal processore stesso anche con tensioni di alimentazione del processore di soli 2.2V.
RESET, INTERRUPT E LOW POWER
Alcune delle cause di reset del microprocessore possono essere selezionate programmando opportunamente i registri di configurazione. Gli eventi che generano il reset del processore, oltre a quelli classici, possono essere: l’accesso in scrittura alla flash memory senza l’uso della security key (per prevenire accessi accidentali alla memoria di codice), il brown out ovvero l’abbassarsi temporaneo della tensione di alimentazione sotto i limiti di guardia, il watchdog ed il tentativo di fetch di codice della CPU in un indirizzo che è quello riservato alle periferiche. Queste cause di reset evidenziano come in questi piccoli microprocessori sia stata integrata una sicurezza intrinseca di funzionamento tale da permetterne l’uso anche in condizioni particolari (presenza di disturbi elettromagnetici, disturbi di alimentazione e così via). Altro modo di garantire un funzionamento sicuro del coprocessore, consentendo un’attenta gestione delle risorse. Come rappresentato nella Figura 3, esistono principalmente 4 modi di risparmio di energia che possono essere selezionati per soddisfare tutte le esigenze senza compromettere l’efficienza del dispositivo. A partire da un Active Mode che, a 2,2V di alimentazione ed una frequenza di lavoro del processore di 1MHz, porta ad un consumo di soli 200uA, si può passare ad un LPM4 (Low Power Mode 4) che porta i consumi a 0,1uA. Nelle varie modalità vengono “spenti” i vari tipi di clock e/o periferiche nonché la CPU ma rimangono attivi i segnali che permettono di “risvegliare” la CPU con appositi interrupt. La progettazione del SW di dispositivi funzionanti in modalità a basso consumo è però un argomento vasto quanto interessante e si rimanda quindi alla documentazione specifica del microprocessore che si intende utilizzare per una trattazione completa dei vari LPM.
INPUT/OUTPUT DIGITALI
La gestione dei pin di I/O di questo microprocessore non è molto diversa da quella degli altri microprocessori di questo tipo e quindi è possibile configurare ogni singolo pin per essere IN, OUT, connesso alle periferiche interne, con o senza pull-up integrato. Particolarità non comune è che qualunque pin di I/O può generare interrupt alla CPU, permettendo così all’HW esterno al microprocessore di “svegliarlo” dalla condizione di low-power solo quando realmente necessario.
TIMER E WATCHDOG
Il watchdog disponibile all’interno di questo microprocessore è simile a quelli degli altri microprocessori per funzionalità ed utilizzo ma occorre porre particolare cura nel suo utilizzo. Infatti, a causa del fatto che il clock col quale si fa funzionare il watchdog potrebbe essere tra quelli disabilitati da un low-power mode, bisogna valutare se perdere la funzionalità di watchdog o quella del low-power mode prescelto. Il modulo timer a 16 bit è invece particolarmente ricco per un microprocessore di questo taglio. Il clock del timer è infatti selezionabile tra due sorgenti interne e due sorgenti esterne e divisibile con un prescaler programmabile. Le modalità di conteggio possibili sono 3 (free run, up fino ad un limite impostabile con azzeramento, up fino al limite impostato e down fino a 0). Sono poi presenti due o tre blocchi (a seconda della configurazione prescelta) di capture/compare che permettono di effettuare operazioni di controllo ed elaborazione sul conteggio del timer e che generano interrupt per gli eventi selezionati. È possibile così generare in modo automatico forme d’onda complesse quali PWM, conteggio eventi, burst e così via. L’interrupt generato dal modulo timer è di tipo vettorizzato ovvero l’interrupt è uno solo ma nella routine di gestione o handler, un meccanismo particolarmente efficiente consente di discriminare la sorgente con poche righe di assembler.
UNIVERSAL SERIAL LINE
Il modulo gestore di linea seriale di questo microprocessore è definito universale proprio per la possibilità di adattarsi a molti standard di comunicazione. È possibile infatti configurare il modulo per gestire: una linea di tipo SPI a tre fili, una linea I2C sia master che slave, la lunghezza variabile del dato e l’ordine dei bit in linea (prima MSB o LSB). È possibile configurare la fase e la polarità del clock inviato sulla linea seriale. È addirittura possibile far funzionare il blocco seriale in I2C slave mode durante l'LPM4.
COMPARATORE
Il blocco comparatore (presente solo nei dispositivi MSP430F20X1) permette di effettuare una elaborazione di segnali analogici basati sulla comparazione del segnale analizzato con una tensione di riferimento (interna o esterna), filtrazione e misurazioni di durata del segnale. Le possibilità di configurare questo blocco comprendono: la possibilità multiplexing del segnale da portare al terminale positivo ed a quello negativo del comparatore, l’applicazione o meno di un filtro RC passa-basso sull’output del comparatore, la possibilità di portare l’uscita del comparatore all’input di cap della temperatura dello stesso. Caratteristica interessante è la possibilità di impostare automatismi sulla modalità della conversione e memorizzazione dei dati: è possibile effettuare conversioni sul singolo canale, ripetute sul singolo canale, su sequenze di canali e ripetere le sequenze solo programmando la modalità prescelta. Inoltre, anche la conservazione dei dati della conversione può essere automatizzata e programmata per fare in modo che il convertitore scriva automaticamente i dati in specifiche zone della memoria RAM. Per la conversione analogico-digitale è presente anche un altro blocco che effettua la conversione sigma-delta a 16 bit. Anche a questo convertitore è possibile portare uno degli otto canali analogici di ingresso. È possibile selezionare il riferimento di tensione interno da 1,2V o utilizzarne uno esterno e rilevare la temperatura del microprocessore. Nonostante le prestazioni di tutto rispetto di questo convertitore che prevede una frequenza d’ingresso del modulatore massima di 1,1MHz e un’alta impedenza del buffer di ingresso, è possibile selezionare una modalità di conversione “low-power” per avere un buon compromesso tra funzionalità e consumo.
PROGRAMMI DI ESEMPIO
Tutti i programmi descritti nel presente articolo sono stati sviluppati prendendo spunto da alcuni esempi presenti nei vari siti internet dedicati all’argomento e sono qui descritti a puro scopo didattico. È comunque disponibile in rete una grande varietà di esempi più completi e sofisticati, anche grazie al fatto che le versioni più vecchie di microprocessore della famiglia degli MSP430 hanno più di dieci anni. Data la brevità della maggior parte dei programmi, è possibile copiarli direttamente dalle pagine dell’articolo ed è consigliato creare un progetto per ogni esempio in modo da conservare le specifiche impostazioni dell’IDE per eventuali usi futuri. Sono stati scelti principalmente programmi che evidenziano il loro funzionamento mediante il LED montato sulla scheda target, ma è ovvio che le possibilità si moltiplicano se si annettono un interruttore collegato ad un pin di input del microprocessore oppure un dispositivo seriale (una memoria, un convertitore D/A, un altro microprocessore) collegato alla linea seriale SPI o I2C che sarà descritta in seguito. I commenti presenti in ogni riga dei listati originali (scaricabili dal sito della rivista) sono stati omessi nella versione stampata per esigenze grafiche.
OSC A BASSA FREQUENZA
E’ un programma nel quale l’uso del pin di uscita per accendere il LED è subordinato all’uso di una delle modalità di basso consumo disponibili in questo microprocessore. Una funzione banale, come quella di accendere il LED, è stata implementata generando un segnale con un duty cycle che ha una fase attiva del dieci per cento, derivata dal funzionamento del microprocessore ad una frequenza molto bassa (circa 1,5 kHz). Alla riga 1 viene definita una variabile che viene dichiarata volatile per evitare che l’ottimizzazione fatta dal compilatore possa rimuoverla e rendere il debug meno facile da seguire. Nella riga 2 viene fermato il watchdog per evitare che intervenga. Nelle righe 3, 4 e 5 vengono settate le opzioni che permettono al microprocessore di funzionare senza oscillatore esterno; nemmeno il generatore di clock DCO è attivato, bensì è utilizzato solo un oscillatore interno a basso consumo che tramite opportuni divisori fornisce la frequenza di circa 1,5 kHz. Nelle righe 6,7,8, 9 e 10 viene definita la direzione e l’uso dei pin di I/O attinenti alle porte logiche 1 e 2. Nelle righe da 11 a 17 vi è il ciclo “for” che accende il LED, attende il decremento della variabile e poi lo spegne. Attende nuovamente il decremento della variabile, che questa volta vale 10 volte il valore precedente, per generare il duty di circa 1/10. Le modifiche più semplici possono essere quelle di variare il duty cycle per rendere più visibile il lampeggio del LED e/o la frequenza di lavoro del microprocessore (Listato 1).
//****************************** // // Pin di uscita: P1.0 con una // quadra di 1/10 di duty cycle // Particolarità: funzionamento // a bassissima freq. ~ 1.5kHz // //******************************* #include <msp430x20x3.h> void main(void) { 1 volatile unsigned int i; 2 WDTCTL = WDTPW + WDTHOLD; 3 BCSCTL3 |= LFXT1S_2; 4 IFG1 &= ~OFIFG; 5 __bis_SR_register(SCG1 + SCG0); 6 BCSCTL2 |= SELM_3 + DIVM_3; 7 P1DIR = 0xFF; 8 P1OUT = 0; 9 P2DIR = 0xFF; 10 P2OUT = 0; 11 for (;;) 12 { 13 P1OUT |= 0x01; 14 for (i = 10; i > 0; i—); 15 P1OUT &= ~0x01; 16 for (i = 100; i > 0; i—); 17 } }
Listato 1 |