
Una panoramica generale sulla famiglia F2MC, i microcontrollori ad 8 bit di Fujitsu: i campi di applicazione, le modalità di indirizzamento, le istruzioni assembler speciali, i tools di sviluppo.
Modelli e campi di applicazione.
La gamma dei microcontrollori della Fujitsu spazia su più di 500 dispositivi, con differenti architetture e prestazioni. Si va dalla famiglia base ad 8 bit (F2MC-8L e F2MC-8FX), fino alla serie più evoluta a 32 bit (FRlite) caratterizzata da una tecnologia a 90nmn, passando per la famiglia intermedia a 16 bit (F2MC -16L). Le MCU della Fujitsu sono largamente utilizzate in applicazioni industriali, home ed automotive. In quest’ultimo campo di applicazione, in particolare, vengono impiegati per gestire il controllo dei display, della sicurezza, dei sensori elettronici e della trazione. Questi chip riescono soddisfare le stringenti specifiche del mercato dell’automotive, grazie anche alle interfacce on-board quali:
- CAN;
- LIN;
- IDB1394;
- FlexRay;
- Ethernet.
La Figura 1 illustra un esempio di utilizzo di questi micro per il controllo elettronico di una autovettura, videnziando come ciascuna delle suddette interfacce abbia un suo specifico impiego per svolgere tutti i sofisticati compiti che le attuali vetture devono assolvere. Si noti come tutte le diverse periferiche vengano controllate mediate un unico bus con protocollo FlexRay.
Le principali novità che bisogna evidenziare, in quella che la Fujitsu considera la quarta generazione di questi controllori, sono:
- Livelli di tensione delle porte programmabili.
- Modulazione del clock.
- Comunicazione seriale potenziata.
Infatti, a differenza di altri micro, le loro linee di input/output sono compatibili non solo con i livelli logici TTL e CMOS, ma anche con i cosiddetti “automotive level”. Inoltre, la modulazione del clock ha permesso di ridurre notevolmente le emissioni elettromagnetiche (EMI), requisito questo divenuto di grande importanza con l’aumento delle frequenze di clock. La terza caratteristica fondamentale è la presenza di una potente interfaccia di comunicazione seriale, con supporto hardware del protocollo LIN ed una velocità della porta USART che può raggiungere anche i 4Mbaud.
La famiglia F2MC ad 8 bit
Le sotto-famiglie della serie ad 8 bit
La serie dei micro ad 8 bit della Fujitsu si suddivide in due principali sotto-categorie:
- F2MC-8L (indicati con la sigla MB89xxxx), che si distinguono per il basso consumo e la ridotta tensione di alimentazione.
- F2MC-8FX (indicati con la sigla MB95xxxx), che si distinguono, oltre che per la ridotta potenza dissipata, anche per le più elevate prestazioni rispetto ai “fratelli” minori (nel seguito saranno evidenziati alcuni aspetti in cui essi si differenziano dalla serie 8L).
È importante specificare alcuni dettagli sulle sigle, al fine di districarsi al meglio tra i tanti modelli esistenti:
- MB89Pxxx, indica un dispositivo OTP, ossia programmabile una sola volta;
- MB89Txxx, indica un chip non dotato di memoria ROM;
- MB89Fxxx/ MB95Fxxx, indica un dispositivo equipaggiato di memoria Flash.
Prendendo come riferimento il modello MB95xxxx serie 100, si nota subito una discreta quantità di memoria ROM (64KB) ed una frequenza del clock di 10MHz (è utilizzabile in questo caso anche il PLL onboard con un quarzo di 32KHz); notevole risulta anche la quantità di porte disponibili (pari a 54) ed il numero di canali analogici per la conversione in digitale (ben 12 canali di acquisizione con una risoluzione di 10 bit); questo modello, in particolare, non dispone di un controller LCD, a differenza di altre serie come la 120 e 150, le quali sono dotate di controller, rispettivamente, per display 4x40 e 4x16. Anche la disponibilità di RAM risulta sufficiente per lo sviluppo di progetti di piccole e medie dimensioni (in questi modelli si arriva fino a 2KB).
Caratteristiche generali
Entrambe le sotto-categorie dei micro ad 8 bit presentano la struttura descritta in Figura 2.
Nei micro Fujitsu ad 8 bit esistono due differenti tipi di registri: quelli dedicati, che sono presenti nella CPU e quelli general-purpouse, che sono invece contenuti nell’area di memoria. Ovviamente, i primi risultano più veloci, ma in numero minore rispetto ai secondi. La Figura 3 mostra i registri del primo tipo ed il loro valore di default all’avvio del processore.
Oltre al classici registri A (Accumulatore) e PC (Program Counter), esistono anche l’accumulatore temporaneo (T) che serve ad eseguire alcune operazioni assembler in combinazione con A, il registro indice (IX) che viene utilizzato per l’omonimo tipo di indirizzamento, lo stack pointer (SP) utilizzato nelle chiamate a subroutine ed indica l’indirizzo dell’ultimo dato inserito nello stack; la Figura 4 mostra un esempio di inserimento nello stack di un dato contenuto nell’accumulatore.
Altri registri dedicati sono l’extra pointer (EP) utilizzato per indicare indirizzi di memoria ed infine il registro di stato (PS) che fornisce utili informazioni sullo stato della CPU. Tutti i registri dedicati hanno una dimensione pari a 16 bit. I registri general-purpouse sono invece utilizzati per la memorizzazione dei dati ed hanno una ampiezza di 8 bit. Essi sono organizzati in banchi di 8 registri ciascuno, per un massimo di 32 banchi. Il banco corrente viene referenziato mediante il puntatore al registro dei banchi (RP), come illustrato in Figura 5.
Sempre nella categoria dei registri per usi generali rientrano i banchi di registri diretti, che sono localizzati tra l’indirizzo di memoria 0080h e 047Fh. L’organizzazione di tali registri è riportata in Figura 6.
Modalità di indirizzamento
È interessante esaminare le diverse modalità di indirizzamento della memoria, in quanto il loro uso appropriato permette di incrementare l’efficienza di ciascuna istruzione e conseguentemente compattare l’intero codice. In particolare, si distinguono i seguenti nove modi di indirizzare la memoria (l’indirizzo è rappresentato in generale con 16 bit):
- Indirizzamento diretto, in cui è possibile indicare solo gli 8 bit meno significativi dell’indirizzo;
- Indirizzamento esteso, in cui è possibile specificare tutti i 16 bit dell’indirizzo;
- Indirizzamento diretto al bit.
- Indirizzamento indicizzato, in cui vengono sommati gli 8 bit dell’operando al registro indice (IX) ed il risultato utilizzato come indirizzo vero e proprio.
- Indirizzamento con puntatore, in cui viene utilizzato il contenuto del registro EP come indirizzo.
- Indirizzamento ai registri general-purpouse, in cui l’operando rappresenta un registro per uso generico.
- Indirizzameno immediato, in cui viene specificato l’indirizzo tramite un numero ad 8 bit.
- Indirizzamento vettoriale.
- Indirizzamento relativo, in cui la posizione di memoria puntata viene calcolata sommando un certo offset al PC.
L’area di memoria in cui vengono utilizzate tali modalità sono riportate nella Figura 7. Indirizzamento con puntatore, in cui viene utilizzato il contenuto del registro EP come indirizzo.
Istruzioni assembler speciali
Tra le principali differenze che esistono tra la serie L e quella FX, vi è la presenza, in questi ultimi processori, di alcune istruzioni assembler particolari che permettono una gestione più efficiente e compatta del codice. Esse sono di seguito elencate, riportando per ognuna una breve descrizione del loro utilizzo:
- JMP @A: si tratta di una operazione di branching incondizionato che permette di modificare il valore del PC, assegnandogli quello contenuto nell’accumulatore A.
- MOVW A,PC: è l’operazione inversa alla precedente, in quanto permette di acquisire nel registro A il valore attuale del PC.
- MULU A,T: l’istruzione permette di moltiplicare gli 8 bit meno significativi dei registri A e T; il risultato dell’operazione viene posto nell’accumulatore. Questo è un esempio in cui risulta utile la presenza dell’accumulatore temporaneo.
- DIVU A,T: l’istruzione permette di dividere i 16 bit del registro A con i 16 bit del registro T e memorizzare il risultato nell’accumulatore, mentre il resto viene inserito in T.
- XCHW A,PC: l’istruzione consente di scambiare il valore di A con quello del PC e viceversa. La Figura 8 riporta un segmento di codice assembler in cui viene effettuato un salto ad una subroutine; in questo caso risulta molto utile l’istruzione descritta combinata con la JMP @A. Infatti, con l’istruzione di scambio di A e del PC si ottiene il duplice effetto di saltare alla subroutine e salvare in A il valore del PC.
Un’altra caratteristica interessante del micro F2MC-8FX è la possibilità di effettuare trasferimenti di dati a 16 bit pur essendo il core ad 8 bit. Ciò garantisce una maggiore velocità nell’esecuzione delle operazioni.
Come mostrato in Figura 9 il dato contenuto nell’accumulatore (a 16 bit) viene memorizzato a partire dalla sua parte alta in memoria, secondo la cosiddetta notazione Little Endian.
Utilizzo degli interrupt
Come ogni micro che si rispetti, anche quelli della Fujitsu sono dotati di una gestione ad interrupt che consente di velocizzare il flusso operazioni eseguite. In particolare, essi si distinguono per la possibilità di settare ben quattro livelli di priorità. Il flusso logico delle operazioni eseguite nella chiamata di un interrupt è descritto in Figura 10.
Come si evince dalla Figura 10, quando una periferica invia una richiesta di interrupt vengono eseguite le seguenti operazioni:
- Controllo dello stato del bit di abilitazione: se questo è attivato allora l’interrupt può “scattare”.
- L’interrupt controller riceve la richiesta, valuta il livello di priorità ed il tipo di interruzione e quindi trasferisce l’informazione direttamente alla CPU.
- La CPU confronta la priorità dell’interrupt ricevuto con quello indicato nei due bit IL0 e IL1, localizzati nel registro PS (Program Status).
- Se la priorità dell’interrupt ricevuto è maggiore di quella indicata dai registri IL0 e IL1 e se il flag I è attivato allora la CPU trasferisce il controllo del programma alla routine di interrupt che ne ha fatto richiesta.
- Contemporaneamente la CPU aggiorna il valore dei registri IL0 e IL1 con il nuovo valore di priorità (se questo risulta superiore a quello precedentemente memorizzato).
La possibilità di impostare differenti livelli di priorità, consente quindi di gestire interrupt multipli (o annidati). Un classico esempio in cui ciò risulta utile è la conversione di un segnale analogico in digitale tramite l’uso dell’ADC. In questo caso si potrebbe utilizza re la routine di interrupt dell’ADC con una priorità più bassa rispetto all’interrupt del timer, il quale servirebbe a scandire le varie operazioni eseguite. La Figura 11 mostra il flusso di esecuzione del programma, interrotto prima dall’interrupt dell’ADC e poi da quello del timer. Si noti che l’operazione opposta sarebbe impossibile in quanto violerebbe la priorità impostata.
Oscillatore
Tutti i vari blocchi del micro hanno necessità, ovviamente, di utilizzare una sorgente di clock oppure un quarzo esterno, secondo le configurazioni rappresentate in Figura 12.
La Figura 12 riporta anche le caratteristiche che deve possedere la forma d’onda qualora si decida di utilizzare una sorgente di clock esterna. I valori dei vari parametri riportati in Figura 12 sono specificati in Tabella 1. Tra le altre informazioni riportate nella Tabella 1 si nota anche la presenta di un sub-clock; si tratta di un clock secondario la cui frequenza deve essere pari a 32.768KHz ed è utilizzato per generare valori di frequenza programmabili tramite il PLL on-board.
Convertitore analogico/digitale
Un altro blocco fondamentale che caratterizza la struttura interna dei micro della Fujitsu è il convertitore analogico/digitale, fondamentale per tutte le operazioni di trattamento dei segnale analogici. Uno schema a blocchi di massima è riportato in Figura 13.
Come si nota, il segnale di ingresso (AN0…ANx) attraverso un MUX arriva allo stadio SH (Sample and Hold) ed infine al comparatore. La conversione viene effettuata confrontando il segnale di ingresso con quello proveniente da un D/A (Digital to Analog), mediante il metodo delle approssimazioni successive (SAR). È importante notare che gli ingressi analogici possono essere utilizzati anche come comparatori, impostando il blocco di conversione in modalità Sense Mode (praticamente assegnando valore 1 al bit SIFM del registro ADC1) e scrivendo nel registro ADC Data il valore di soglia oltre cui far “scattare” il comparatore. Se il segnale analogico di ingresso supera tale soglia, allora il flag ADI verrà asserito, altrimenti esso rimarrà a 0. La predisposizione di una alimentazione e di una massa analogica (AVSS e AVCC) sono ormai una soluzione tipica per tutti i circuiti mixedsignal. In questa maniera si evita che il rumore generato dalla parte digitale si propaghi su tutta la catena di conversione e quindi riduca le prestazione dell’ADC (si ricordi infatti che una riduzione del rapporto segnale-rumore comporta una riduzione della risoluzione effettiva del convertitore A/D). Per la configurazione ed il controllo delle operazioni dell’ADC esistono due appositi registri ADC1 e ADC2. La Figura 14 riporta una descrizione dettagliata di tali registri. Una volta selezionato il canale su cui effettuare la conversione, esistono tre diversi modi per avviare la conversione:
- Software Trigger: la modalità viene selezionata impostando il bit EXT del registro ADC2 a 0; la conversione ha inizio quando viene settato il bit AD del registro ADC1.
- Hardware trigger (tipo 1): la modalità viene selezionata impostando ad 1 il bit EXT e a 0 il bit ADCK; la conversione avviene periodicamente tramite un clock interno derivato dal master clock.
- Hardware trigger (tipo 2): la modalità viene selezionata impostando a 1 il bit EXT ed il bit ADCK; in questo caso la conversione avviene mediate un segnale esterno.
Anche per determinare la fine della conversione esistono tre differenti metodi:
- Interrogazione periodica (polling) del bit ADMV: quando esso viene portato a 0 allora la conversione è terminata.
- Polling del bit ADI: esso ha logica inversa rispetto al bit ADMV; inoltre, deve essere resettato via software dal programmatore.
- Routine di interrupt: appena la conversione è termina, viene lanciata un routine di interrupt per la gestione del valore ottenuto.
Tools per il debug e la programmazione
Ovviamente, per mettere in pratica tutta la teoria è necessario anche disporre di strumenti semplici ed efficienti che permettano di sviluppare e testare la propria applicazione. Per quanto riguarda i chip della Fujitsu la scelta è davvero ampia, i dispositivi spaziano dai debugger ai programmatori, fino ad arrivare agli emulatori. Un esempio di questa ultima categoria è rappresentato dal C-ICE (Compact In-Circuit Emulator) che permette di effetture l’emulazione del micro della sotto-famiglia ad 8 bit F2MC-8L; un’immagine di questo tool è mostrata in Figura 15.
Tale strumento offre, non solo la possibilità di emulare i chip ad 8 bit, ma anche di effettuare un sofisticato debug, che prevede la possibilità di impostare breakpoints multilivello, eventi attivabili sul livello dei bit e supporto combinato per linguaggi ad alto e basso livello (C e assembler). La compatibilità dell’ambiente di sviluppo integrato Softune, di cui è mostrato un dettaglio in Figura 16, è garantita con tutti i sistemi operativi Microsoft.
Per quanto riguarda lo sviluppo di progetti con la sotto-famiglia F2MC-8FX è possibile utilizzare l’adattatore BGM, che consente di effettuare il debug, con una apposita scheda di valutazione, come illustrato in Figura 17.
La Figura 18 mostra, invece, la scheda di valutazione CONCERTO che rappresenta un’altra possibile soluzione per testare i chip della famiglia 8FX; tale scheda è equipaggiata con il chip MB95F108H.
Esempio di programmazione con i Fujitsu (modello MB89630)
Di seguito è riportato un esempio di programmazione dei chip Fujitsu in linguaggio c. In particolare, viene presentata la routine per la conversione A/D, scandita da un clock interno derivato del master clock (Hardware trigger) e mediante interrogazine del bit ADMV (polling di ADMV). Il codice riportato costituisce anche un’utile base per iniziare a sviluppare semplici programmi di test per questa famiglia di micro.
#include <MB89630.H> /* definisce le informazioni sul processore utilizzato */ #include <EVABIOS.H> const char InitMsg[] = "MB89630 A/D Programma test ADC\n"; const char ADCmsg[] = " A/D : "; const char LsChar[] = "° ù__"; BYTE MsADval; direct char dummy1; direct char dummy2 = 5; void main () { BYTE i; puts(InitMsg); do { ADC2 = 0x01; /* Utilizzo del clock interno */ ADC1 = 0x61; /* Canale 6, Start AD */ while (ADMV) ; /* interrogazione del bit ADMV */ putch(13); puts(ADCmsg); printHexByte(ADDH); printHexByte(ADDL); putch(' '); MsADval = ADDL >> 2; for (i=0;i<MsADval;i++) { putch('Û'); } putch(LsChar[ADDL & 0x03]); for (i=MsADval;i<63;i++) { putch('° '); } } while(1); }

E’ importante avere dei micro che soddisfano requisiti di standard/interfaccia nel mondo automotive. Oggi l’automobile e’ piu’ elettronica che meccanica, con tanti sensori impiegati e con la necessita’ di un’opportuna logica di controllo.