Play ARM7!

Già da parecchio tempo, allo scopo di soddisfare le sempre più esigenti richieste del mercato, quasi tutte le case costruttrici di semiconduttori stanno producendo microcontrollori a 32 bit. Parallelamente, le richieste di sistemi di sviluppo sempre più economici hanno reso molti di questi potenti componenti a portata di hobbista. In questo articolo, attraverso un esempio pratico, verrà illustrato come iniziare rapidamente ad utilizzare un microcontroller a 32 bit con core ARM7 e clock massimo di 60MHz per lo sviluppo delle proprie applicazioni.

LPC2000 è una famiglia di microcontrollers, prodotta oggi da NXP, basata sulla collaudata architettura ARM, una delle più diffuse architetture a livello mondiale per applicazioni embedded a basso consumo energetico come cellulari, PDA, routers, videogiochi portatili, e altro ancora. In questi articolo non entreremo nei dettagli della descrizione dell’architettura sopracitata,  alla quale sono state dedicate già parecchie pagine teoriche da parte di varie riviste, ma verranno fornite tutte le informazioni necessarie per cominciare ad utilizzarla nello sviluppo di applicazioni.  Il modulo presentato monta un microcontroller della serie LPC213x, avente core ARM7TDMI-S e dotato di un buon set di periferiche (UARTs, ADC e DAC a 10 bit, RTC, seriali sincrone e asincrone, timers, PLL, e altro ancora) nonché di una notevole quantità di memoria (fino 512KB di FLASH e 32KB di RAM). Il  datasheet completo di questo componente è reperibile, oltre che sul sito www.nxp.com, anche in svariate pagine web che forniscono informazioni riguardanti controllori a 32 bit.

Perchè  un'altra  ARM-board?

Come è classico, per cominciare ad utilizzare un certo componente… si acquista lo starter kit o la “valigia” contenente tutto l’occorrente per poter iniziare a giocare. Il modulo descritto in queste pagine vuole essere qualcosa di diverso: nonostante lo si possa impiegare come starter kit o per valutare l’LPC213x, la destinazione per la quale è stato principalmente pensato è quella di “motore” per prototipi, realizzati anche su millefori. A differenza di molte demo board, la versatilità e le dimensioni contenute di questo circuito permettono di integrarlo in parecchie applicazioni definitive, alimentate dalla rete elettrica o a batteria oppure dalla connessione al computer.

Figura 1: il modulo con ARM7.

Figura 1: il modulo con ARM7.

Descrizione del circuito

In figura 2 è possibile vedere lo schema a blocchi del modulo.

Figura 2: schema a blocchi.

Figura 2: schema a blocchi.

Questo schema permette di comprendere più facilmente lo schema elettrico, che è invece riportato in figura 3.

Figura 3: schema elettrico del dispositivo.

Figura 3: schema elettrico del dispositivo.

 

Figura 4: layout di montaggio e piste del circuito stampato.

Figura 4: layout di montaggio e piste del circuito stampato.

Come è possibile vedere dallo schema a blocchi, l’LPC213x non è l’unico microcontroller presente su questo circuito stampato. Per rendere il modulo adatto a svolgere il maggior numero possibile di compiti, è stato equipaggiato con un PIC18LF2455, un PIC con interfaccia USB 1.1. Con questo, utilizzando del firmware esistente (e reperibile in maniera gratuita presso il sito della Microchip) è possibile dotare il modulo di porta seriale USB oppure di interfaccia SD-to-USB per accedere al contenuto della memory card dal computer. Ma perché non usare un micro ARM7 con interfaccia USB? Perché in questo modo si sgrava l’ARM da compiti che richiedono risorse non proprio indifferenti e, inoltre, l’utilizzo di firmware già esistente (e collaudato) contribuisce a ridurre i tempi di sviluppo dell’applicazione! Il dip-switch SW1 permette di collegare il pin RxD/SDO di U4 (il PIC18LF2455) alla porta seriale di U2 oppure al bus SPI comune tra U2, U3, e la memory card (J3). La presenza di SW1 permette in sostanza di adattare l’hardware al firmware che si carica in U2 senza richiedere l’uso del saldatore. Le due combinazioni ammesse sono: SW1-1 ON e SW1-2 OFF (U2 andrà programmato per funzionare da interfaccia USB-to-Serial), ed SW1-1 OFF e SW1-2 ON (U2 andrà programmato per funzionare da interfaccia USB-to-SD). In quest’ultimo caso, U2 informa U3 del possibile utilizzo del bus SPI attraverso  il segnale di abilitazione nUSB_EN. Mediante il partitore composto da R2 ed R3, U3 può sentire la presenza della tensione di alimentazione sul connettore USB e, quindi, la connessione al computer. Se non si ha bisogno dell’interfaccia USB, è possibile omettere dal modulo U2 ed i  relativi componenti di contorno quali R1, R2, R3, R4, C3, C4, X3, SW1, e DL3. Sul modulo trovano posto un connettore per memory card tipo SD o MMC (che mediante adattatori può accettare in alternativa RSMMC, miniSD, e micro-SD) ed un portabatteria, destinato ad ospitare una CR2032 (la batteria al litio da 3V tipicamente usate sulle motherboard dei PC) per mantenere attivo l’RTC presente nel microcontroller U2. Avere a disposizione un RTC permette di poter assegnare l’ora e la data reale ai files che verranno eventualmente scritti sulla memory card. Sul modulo trovano posto i connettori di programmazione e debug in-circuit dei due microcontroller (J2 per il PIC, J5 per l’ARM7), un pulsante di reset (S1), un pulsante collegato a P0.14 dell’LPC213x (S2, che viene usato anche per abilitare la programmazione via seriale di questo componente), un led che segnala la presenza dell’alimentazione (DL1) e altri due (DL2, DL3) che, essendo collegati ai microcontrollori, possono essere destinati alla segnalazione di molte cose. Ad esempio è possibile usare DL3 per indicare l’accesso alla memory card dal bus USB, e DL2, con un semplice lampeggio, per far presente che l’eventuale sistema opera tivo real-time presente in U2 sta girando correttamente. I  3,3V necessari al funzionamento dei vari circuiti integrati possono essere forniti da uno stabilizzatore di tensione lineare (U5, un LM1117MPX3.3) o da un regolatore switching (U1, un LTC3440). Questi due stadi di alimentazione, che ovviamente non possono coesistere, determinano alcune caratteristiche del modulo (fare riferimento alla tabella 1).

Tabella 1: stadi di alimentazione.

Tabella 1: stadi di alimentazione.

Il pin 4 di J7 è l’ingresso di shutdown del modulo: lasciando scollegato questo pin, la resistenza R14 mantiene disattivato  il regolatore  U1 ed il modulo rimane praticamente spento. Portando su questo pin una tensione positiva compresa tra 2 e 5V, abilitiamo il regolatore che a sua volta accende il resto della circuiteria. Tale ingresso può essere usato per implementare lo spegnimento controllato del modulo qualora venga sfruttata l’alimentazione a batterie. Ulteriore possibile soluzione per alimentare il modulo consiste nell’utilizzo dei 5V forniti dalla porta USB del PC: in questo caso è necessario  collegare il pin 17 di J6 ai pin 1, 2, e 4 di J7. Sebbene  il modulo abbia a bordo la propria circuiteria di reset (l’integrato U4, ma anche il pulsante S1…), è possibile far ripartire i microcontrollers anche dall’esterno. Per far ciò è sufficiente portare il pin 7 di J7 (ingresso di reset) a massa. In tabella 2 è possibile vedere le connessioni verso il mondo esterno.

Tabella 2: pinout del modulo.

Tabella 2: pinout del modulo.

 

Tabella 3: elenco componenti

Tabella 3: elenco componenti

Le pin-strip J4, J6, e J7 sono state disposte, sul circuito stampato, su un grigliato a passo 2,54mm così da permettere l’inserimento del modulo anche su millefori. L’accesso a J4 può avvenire dal circuito stampato che ospita il modulo, montando in questa posizione una pin-strip femmina come quelle in J6 e J7, oppure da un connettore volante (vedi figura 1 e figura 11).

Montaggio

Come è possibile vedere dalle foto, il modulo fa uso di un circuito stampato con piste piuttosto sottili e vicine ed è popolato da parecchia componentistica SMD. Non è stato possibile fare diversamente, poiché i microcontrollers  della serie LPC213x esistono solo in contenitori LQFP (quello qui utilizzato)  e HVQFN. Quest’ultimo, sprovvisto dei classici pin, ha delle pads sui bordi del corpo del circuito integrato, e in campo hobbystico può risultare ancora più critico da saldare dell’LQFP. Per il  montaggio sono assolutamente indispensabili un paio di pinzette sottili, un saldatore a punta fine (o ad aria calda), una lente di ingrandimento, una discreta vista, ed una buona dose di pazienza.  I componenti da montare non sono pochi, sono disposti su entrambi i lati del circuito, ed alcuni hanno passo di 0.5mm. Importante, sconsiglio vivamante  il montaggio a chi è alle prime armi o a chi non ha mai avuto a che fare con componenti SMD. Le possibilità di commettere errori durante il montaggio sono elevate, ed è possibile il danneggiamento dei componenti del circuito e della porta USB del computer. E’ necessario prestare attenzione al verso di montaggio dei condensatori elettrolitici, dei led, dei circuiti integrati, ed a non scambiare tra loro il circuito integrato U4 e i diodi (tutti aventi contenitore SOT23). E’ bene, come sempre, partire dai componenti più piccoli per finire con quelli di dimensioni più ingombranti, lasciando quindi per ultimi i componenti a montaggio tradizionale  (il quarzo, il risuonatore,  le pinstrip, ed il portabatteria). Prima di dare tensione al circuito è consigliabile ricontrollare il tutto, anche più di una volta: ricordo che un piccolo “baffo” di stagno può compromettere anche tutti i circuiti integrati montati. Conoscendo le difficoltà che presenta il montaggio, soprattutto per chi è alle prime armi con la tecnologia SMD o chi comunque non ama le pinzette, mi rendo disponibile a fornire il circuito stampato con saldati i  principali componenti a montaggio superficiale.

Figura 5: alcuni dei componenti

Figura 5: alcuni dei componenti

 

Figura 6: il circuito stampato.

Figura 6: il circuito stampato.

Trentadue bit su due strip

Superato lo scoglio dell’assemblaggio del modulo, si è a buon punto dell’opera. In figura 7 è riportato lo schema elettrico del “minimo indispensabile“ per utilizzare il modulo: data la sua semplicità,  il montaggio di questi componenti è realizzabile su millefori anche dai meno esperti. Per evitare di confondere le strip J6 e J7, la numerazione dei pin di quest’ultima è stata fatta partire da 21.

Figura 7: schema dei collegamenti per accendere il modulo.

Figura 7: schema dei collegamenti per accendere il modulo.

 

Figura 8: schermata del uVision.

Figura 8: schermata del uVision.

Tools di sviluppo

Arrivati a questo punto, possiamo spegnere il saldatore  e metterci comodi davanti al PC. Per testare il modulo è necessario procurarsi la “LPC2000 FLASH ISP Utility” (per LPC213x). Quest’ultimo è un ambiente di sviluppo integrato che include anche un pratico simulatore. Dopo averli installati, cominciamo con l’aprire un minuscolo listato di esempio. Successivamente, premendo F7, avviamo la compilazione dei sorgenti: dopo pochi istanti, nella finestra Output si vedrà il risultato della compilazione e nella directory Examples/Blinky/Obj (o quella specificata nelle opzioni di Output del progetto) verrà creato il file “Blinky.hex“. Ora entra in gioco la Flash ISP Utility, visibile in figura 9, che permette il caricamento  del file .hex nella FLASH dell’LPC213x.

Figura 9: finestra della Flash ISP Utility.

Figura 9: finestra della Flash ISP Utility.

Il  suo utilizzo è semplice: dopo aver impostato i (pochi) parametri  come quelli di figura 9, premiamo entrambi i pulsanti sul modulo e successivamente rilasciamo prima SW1 (RESET) e poi SW2 (P0.14). Quando, all’uscita dal reset, l’LPC213x trova il pin P0.14 basso, esegue un bootloader che permette l’accesso alla FLASH (e non solo…) dalla UART 0. In questa condizione, premendo il pulsante  Read Device ID sulla FLASH Utility, leggeremo l’ID del componente e la versione del bootloader contenuto nell’LPC213x che stiamo utilizzando. Specificando  il percorso del file Blinky.hex e premendo “Upload Flash”, caricheremo nella FLASH del microcontroller il listato precedentemente compilato. Al termine dell’operazione,  il led DL3 comincerà a lampeggiare. Abbiamo appena fatto girare il nostro primissimo programma su core ARM7. E’ molto conveniente poter lanciare la Flash ISP Utility direttamente  dal pulsante “Load FLASH” presente nella barra degli strumenti di compilazione del µVision3: per far ciò dovremo cliccare su menu “Project” poi “Options for target LPC2100” e, nella pagina “Utilities” della finestra che si aprirà, andrà selezionata la voce “Use external tool for Flash Programming”, specificando il nome dell’eseguibile e gli eventuali parametri diversi da quelli di default. Il  µVision3 include anche un pratico simulatore attivabile selezionando il  target “Simulator” e cliccando, nel menu, su “Debug” e poi su “Start/Stop Debug Session”. Nella sessione di debug che abbiamo appena attivato, oltre alla visualizzazione e alla possibilità di modificare  il contenuto dei registri della CPU, abbiamo modo di interagire con le periferiche attraverso delle comode finestre attivabili dal menu “Peripherals”. In figura 10 possiamo vederne alcune.

Figura 10: finestre del simulatore.

Figura 10: finestre del simulatore.

Mediante un apposito debugger (l’ULINK della Keil, oppure uno dei tanti modelli compatibili) collegato al connettore J5 del modulo, è possibile non solo la programmazione ma anche il debug in-circuit tramite le stesse finestre di figura 10. Tutte queste possibilità fanno del µVision3 uno degli ambienti di sviluppo più comodi e completi. Comunque, esistono molti altri software per lo sviluppo di software per l’ARM, come ad esempio il CrossWorks della Rowley (ambiente di sviluppo) oppure il WinARM,  compilatore basato sul pacchetto GNU.

Possibili  applicazioni

Per applicazioni che possono essere considerate gravose, come ad esempio la gestione di grosse quantità di dati oppure l’esecuzione di calcoli matematici complessi, è indispensabile avere qualche “cavallo” in più rispetto a quelli messi a disposizione dai classici micro ad 8 bit. Ad esempio, vi siete mai chiesti quanti byte può occupare una schermata del vostro cellulare? Se lo schermo è a colori, supponiamo 4096 colori, ossia 12 bit per pixel, e la sua risoluzione è di 160x160 pixel, ogni schermata richiede 160 x 160 x 12 = 307200 bit, diciamo 38400 bytes di spazio per essere memorizzata. Praticamente più della metà della memoria dati indirizzabile da un oramai datato 8051. E la velocità di refresh? Se vogliamo vedere sul display un piccolo filmato, supponiamo con una velocità di 5 frames al secondo, dovremo inviare al display 38400 x 5 = 192000 byte ogni secondo, magari dopo averli letti da una memoria ed opportunamente elaborati. Leggendo questi numeri, chi ha un po’ di esperienza con i microcontrollori avrà intuito che per gestire un display a colori, anche se di piccole dimensioni, convenga dimenticare i micro ad 8 bit. Con i 512Kbyte di memoria FLASH ed i 60MHz massimi di funzionamento di un LPC2138, invece, disegnare immagini animate su un display a colori da 160 x 160 pixel diventa una realtà fattibile anche in campo hobbystico. Per dimostrare le potenzialità di un ARM7 a 60MHz, e in parte anche per stuzzicare la vostra voglia di fare, si riporta in figura 11 lo schema a blocchi di un sistema di sorveglianza che cattura una immagine ogni minuto e la salva sulla memory card (formattata con filesystem FAT) assegnandole data e ora corrente.

Figura 11: schema a blocchi di un sistema di sorveglianza.

Figura 11: schema a blocchi di un sistema di sorveglianza.

In figura 12 la foto di un modulo (montato parzialmente, la parte di interfaccia USB è stata omessa) che esegue la ricerca di immagini in formato bitmap aventi dimensioni di 160 x 160 pixel sulla memory card e le visualizza su un piccolo LCD a colori, con cadenza programmabile, un po’ come una minuscola cornice digitale.

Figura 12: pilotaggio di un piccolo LCD a colori.

Figura 12: pilotaggio di un piccolo LCD a colori.

E’ possibile collegare anche display a colori più grossi, allo scopo di realizzare ad esempio tastiere su schermo o applicazioni che non richiedano prestazioni grafiche elevate. Nelle righe precedenti si è parlato di FAT. Essendo l’ARM una architettura ampiamente diffusa, è facile trovare in rete schemi applicativi, librerie e programmi in C ed assembler in grado di svolgere  i compiti (anche complessi) più comunemente richiesti. Per scrivere un file su una memory card, insomma, non è necessario scrivere un listato di migliaia di righe: è sufficiente fare qualche ricerca su Internet per trovare vari listati che gestiscono questo filesystem. Idem se volessimo implementare uno stack TCP/IP (magari per realizzare un discreto web server in poche ore) oppure per trasmettere e ricevere dati attraverso un bus CAN. E se volessimo fare qualcosa di più complesso, come può essere la realizzazione di un player mp3? Non dovremo più acquistare il costoso decoder mp3 da affiancare al micro ad 8 bit! L’ARM7 a 60MHz è abbastanza potente da riuscire a decodificare bitstream mp3 in tempo reale. Quasi difficile da credere, anche il grosso del software necessario per far ciò è disponibile gratuitamente in rete: la libreria software per scompattare gli mp3 si chiama MadLib, per la documentazione e le necessarie informazioni riguardanti il suo utilizzo si rimanda all’application note AN10583 di NXP (link: www.nxp.com/acrobat_download/applicationnotes/AN10583_1.pdf ).

 

 

 

Scarica subito una copia gratis

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend