Quanto sono diversi i microcontrollori a 8 bit dai microcontrollori a 32 bit quando si tratta di programmarli


19

Bene, quindi al momento abbiamo microcontrollori a 8, 16 e 32 bit in questo mondo. Tutti sono spesso usati. Quanto è diverso programmare i microcontrollori a 8 e 16 bit? Voglio dire, richiede tecniche o abilità diverse? Prendiamo ad esempio il microchip. Quali cose nuove deve imparare una persona se desidera passare da microcontrollori a 8 bit a microcontrollori a 32 bit?


No. Certamente ci sono diverse preoccupazioni, ma quelle sono in gran parte nel livello di dettaglio specifico del dispositivo. Ad esempio, è consentito l'accesso a parole non allineate? (Su ARM non lo è - ancora su x86 lo è). Questa domanda non è abbastanza specifica.
Chris Stratton,

Caspita, grazie per le risposte. Quindi ci sono in realtà differenze molto importanti che dobbiamo prendere in considerazione quando programmiamo processori a 32 bit contro processori a 8 bit. Qui mi riferivo a C poiché penso che la maggior parte delle persone non approfondisca l'Assemblea per la programmazione per ragioni che tutti conosciamo molto bene. Grazie per le risposte dettagliate, lo apprezzo molto.
quantum231,

Con i 32 bit uc c'è MOLTE più opzioni e MOLTI più registri che devi ottenere nel modo giusto. Immagino che dipenda da cosa stai facendo. Detto questo, in questi giorni è possibile ottenere una scheda di sviluppo, compilatore, debugger, IDE per circa $ 50. Indietro nel giorno che costerebbe vicino a $ 1000.

Risposte:


33

In generale, passare da microcontrollori da 8 a 16 a 32 bit significa che avrai meno restrizioni sulle risorse, in particolare la memoria, e la larghezza dei registri utilizzati per eseguire operazioni aritmetiche e logiche. I moniker a 8, 16 e 32 bit si riferiscono generalmente sia alla dimensione dei bus di dati interni ed esterni, sia alla dimensione dei registri interni utilizzati per le operazioni aritmetiche e logiche (in passato erano solo uno o due chiamati accumulatori , ora di solito ci sono banche di registro di 16 o 32).

Le dimensioni delle porte delle porte I / O generalmente seguiranno anche le dimensioni del bus dati, quindi un micro a 8 bit avrà porte a 8 bit, un 16 bit avrà porte a 16 bit ecc.

Nonostante disponga di un bus dati a 8 bit, molti microcontrollori a 8 bit dispongono di un bus indirizzi a 16 bit e possono indirizzare 2 ^ 16 o 64K byte di memoria (ciò non significa che siano vicini a quelli implementati). Ma alcuni micro a 8 bit, come i PIC di fascia bassa, possono avere solo uno spazio RAM molto limitato (ad esempio 96 byte su un PIC16).

Per aggirare il loro schema di indirizzamento limitato, alcuni micro a 8 bit utilizzano il paging, in cui il contenuto di un registro di pagina determina uno dei numerosi banchi di memoria da utilizzare. Di solito ci sarà un po 'di RAM comune disponibile, indipendentemente da cosa sia impostato il registro delle pagine.

I microcontrollori a 16 bit sono generalmente limitati a 64 KB di memoria, ma possono anche utilizzare tecniche di paging per aggirare il problema. I microcontrollori a 32 bit ovviamente non hanno tali restrizioni e possono indirizzare fino a 4 GB di memoria.

Insieme alle diverse dimensioni della memoria è la dimensione dello stack. Nei micro di fascia più bassa, questo può essere implementato in un'area speciale di memoria ed essere molto piccolo (molti PIC16 hanno uno stack di chiamate profonde a 8 livelli). Nei micro a 16 e 32 bit, lo stack sarà generalmente nella RAM generale e sarà limitato solo dalle dimensioni della RAM.

Ci sono anche grandi differenze nella quantità di memoria - sia programma che RAM - implementata sui vari dispositivi. I micro a 8 bit possono avere solo poche centinaia di byte di RAM e poche migliaia di byte di memoria del programma (o molto meno - ad esempio il PIC10F320 ha solo 256 parole di flash a 14 bit e 64 byte di RAM). I micro a 16 bit possono avere qualche migliaio di byte di RAM e decine di migliaia di byte di memoria del programma. I micro a 32 bit hanno spesso oltre 64 KB di RAM e forse 1/2 MB o più di memoria del programma (il PIC32MZ2048 ha 2 MB di flash e 512 KB di RAM; il PIC32MZ2064DAH176 appena rilasciato, ottimizzato per la grafica ha 2 MB di flash e un enorme 32 MB di RAM su chip).

Se si sta programmando in linguaggio assembly, i limiti delle dimensioni del registro saranno molto evidenti, ad esempio l'aggiunta di due numeri a 32 bit è un lavoro ingrato su un microcontrollore a 8 bit ma banale su uno a 32 bit. Se stai programmando in C, questo sarà in gran parte trasparente, ma ovviamente il codice compilato sottostante sarà molto più grande per l'8-bitter.

Ho detto in gran parte trasparente, perché la dimensione di vari tipi di dati C può essere diversa da una micro dimensione all'altra; per esempio, un compilatore che ha come target un micro a 8 o 16 bit può usare "int" per indicare una variabile con segno a 16 bit, e su un micro a 32 bit questa sarebbe una variabile a 32 bit. Quindi molti programmi usano #define per dire esplicitamente quale sia la dimensione desiderata, come "UINT16" per una variabile a 16 bit senza segno.

Se stai programmando in C, l'impatto maggiore sarà la dimensione delle tue variabili. Ad esempio, se sai che una variabile sarà sempre inferiore a 256 (o nell'intervallo da -128 a 127 se firmato), allora dovresti usare un 8-bit (char o char senza segno) su un micro a 8-bit (es. PIC16 ) poiché l'utilizzo di dimensioni maggiori sarà molto inefficiente. Allo stesso modo si tratta di variabili a 16 bit su un micro a 16 bit (ad esempio PIC24). Se si utilizza un micro a 32 bit (PIC32), allora non fa davvero alcuna differenza poiché il set di istruzioni MIPS ha istruzioni byte, word e double-word. Tuttavia, su alcuni micro a 32 bit, se mancano di tali istruzioni, la manipolazione di una variabile a 8 bit potrebbe essere meno efficiente di una a 32 bit a causa del mascheramento.

Come ha sottolineato il membro del forum vsz, sui sistemi in cui hai una variabile più grande della dimensione del registro predefinita (ad esempio una variabile a 16 bit su un micro a 8 bit) e quella variabile è condivisa tra due thread o tra il thread di base e un gestore di interrupt, è necessario eseguire qualsiasi operazione (inclusa la sola lettura) sulla variabile atomica , ovvero far sembrare che venga eseguita come un'istruzione. Questa è chiamata una sezione critica. Il modo standard per mitigare questo è circondare la sezione critica con una coppia di interrupt di disabilitazione / abilitazione.

Quindi, passando da sistemi a 32 bit a 16 bit o da 16 bit a 8 bit, qualsiasi operazione su variabili di questo tipo che sono ora più grandi della dimensione del registro predefinita (ma non lo erano prima) deve essere considerata critica sezione.

Un'altra differenza principale, che passa da un processore PIC a un altro, è la gestione delle periferiche. Ciò ha meno a che fare con la dimensione delle parole e più con il tipo e il numero di risorse allocate su ciascun chip. In generale, Microchip ha cercato di rendere la programmazione della stessa periferica utilizzata su chip diversi il più simile possibile (ad esempio timer0), ma ci saranno sempre differenze. L'uso delle loro librerie periferiche nasconderà queste differenze in larga misura. Un'ultima differenza è la gestione degli interrupt. Ancora una volta c'è aiuto qui dalle librerie Microchip.


Vale la pena notare che a livello di linguaggio assembly, i processori a 8 bit tendono ad avere meno registri e meno istruzioni ortogonali (AVR è un'eccezione più RISCOSA), una conseguenza dei vincoli di progettazione quando sono stati sviluppati. I processori a 32 bit tendono ad essere discendenti RISC (RX di Renesas, un moderno CISC, è un'eccezione e il ColdFire di Freescale scende da m68k).
Paul A. Clayton,

9
Per non iniziare una nuova risposta solo per questa aggiunta, penso sia importante aggiungere che la transizione da 32 bit a 16 di 16 a 8 può causare brutte sorprese poiché l'aritmetica smette di essere atomica. Se aggiungi due numeri a 16 bit su un microcontrollore a 8 bit e li usi in un interrupt, devi prenderti cura di renderli thread-safe, altrimenti potresti finire per aggiungerne solo metà prima che si attivi l'interrupt, risultando in un valore non valido nella routine del servizio di interruzione.
vsz,

2
@vsz - Buon punto, ho dimenticato quello. Generalmente si dovrebbero disabilitare gli interrupt attorno a qualsiasi accesso (inclusa la sola lettura) di qualsiasi variabile volatile che sia più grande della dimensione del registro predefinita.
Tcrosley,

1
È vero che uC a 32 bit di solito ha interfacce I / O a 32 bit? Penso che comunque sia più comunemente solo comunicazione seriale.
clabacchio

1
@clabacchio La mia esperienza è che tutti i registri delle porte I / O sono definiti a 32 bit, ma a volte i 16 bit superiori 16-31 non sono utilizzati, quindi una porta parallela è ancora 16 pin fisici. In altri casi, come un registro RTCC, vengono utilizzati tutti i 32 bit.
Tcrosley,

8

Una differenza comune tra i microcontrollori a 8 e 32 bit è che quelli a 8 bit hanno spesso un intervallo di memoria e spazio I / O a cui è possibile accedere in una singola istruzione, indipendentemente dal contesto di esecuzione, mentre i microcontrollori a 32 bit spesso richiede una sequenza multiistruzione. Ad esempio, su un tipico microcontrollore a 8 bit (HC05, 8051, PIC-18F, ecc.) Si può cambiare lo stato di un bit di porta usando una singola istruzione. Su un tipico ARM (32 bit), se il contenuto del registro fosse inizialmente sconosciuto, sarebbe necessaria una sequenza di istruzioni di quattro istruzioni:

    ldr  r0,=GPIOA
    ldrh r1,[r0+GPIO_DDR]
    ior  r1,#64
    strh r1,[r0+GPIO_DDR]

Nella maggior parte dei progetti, il controller impiegherà la maggior parte del tempo a fare cose diverse dall'impostazione o dalla cancellazione di singoli bit I / O, quindi il fatto che operazioni come la cancellazione di un pin della porta richiedano più istruzioni spesso non ha importanza. D'altra parte, ci sono momenti in cui il codice dovrà "manipolare" un sacco di manipolazioni delle porte e la capacità di fare tali cose con una singola istruzione può rivelarsi piuttosto preziosa.

D'altro canto, i controller a 32 bit sono invariabilmente progettati per accedere in modo efficiente a molti tipi di strutture dati che possono essere archiviate in memoria. Molti controller a 8 bit, al confronto, sono molto inefficienti nell'accedere alle strutture di dati che non sono allocate staticamente. Un controller a 32 bit può eseguire in una istruzione un accesso all'array che richiederebbe una mezza dozzina o più istruzioni su un tipico controller a 8 bit.


Presumo che volevi dire "bit bang". Vale la pena notare che ARM supporta le aree bit band (in cui le operazioni a parola sono operazioni a bit singolo) e l'estensione specifica dell'applicazione MCU per MIPS fornisce Atom / Set di bit atomici all'interno delle istruzioni Byte (ASET / ACLR).
Paul A. Clayton,

@ PaulA.Clayton: non ho mai guardato al MIPS negli ultimi 20 anni; per quanto riguarda le regioni in bit-band, non ho mai trovato un modo per usarle in un codice dall'aspetto ragionevole, e anche se potessi usarle salverebbero solo un'istruzione a meno che non si usassero alcuni insanati trucchi di programmazione, nel qual caso potrebbero salvarne due [caricare R0 con un indirizzo pari o dispari in base alla necessità di impostare o cancellare il bit e regolare l'offset sull'istruzione di memorizzazione come appropriato per compensare]. A proposito, hai idea del perché la regione della bit-band usi gli indirizzi di parole?
supercat,

@supercat: l'indirizzamento delle parole ti consente di accedere alle regioni della bit-band da C o C ++ tramite la sottoscrizione del puntatore ( region_base[offset])
Ben Voigt,

@BenVoigt E perché non si può farlo con l'indirizzamento dei byte? (Forse una possibile ragione sarebbe quella di rimuovere l'aspettativa / speranza che le operazioni a due e quattro bit sarebbero supportate.)
Paul A. Clayton,

@BenVoigt: dover ridimensionare il numero di bit di un fattore 4 avrà spesso un costo aggiuntivo. In realtà, quello che mi sarebbe piaciuto vedere, piuttosto che un'area bit-band, sarebbe un insieme di un paio di aree che si troverebbero con un offset fisso rispetto agli accessi "normali" alla memoria, ma specifica che scrive su un'area se possibile solo "imposta" i bit e le scritture sull'altro "cancellano" solo i bit. Se il bus avesse bit di controllo "write-one-enable" e "write-zeroes-enable" separati, si potrebbe ottenere ciò che il bit-banding consente, ma in molti casi evitare read-edit-write.
supercat,

6

La più grande differenza pratica è la quantità di documentazione, davvero, per comprendere interamente l'intero chip. Esistono microcontrollori a 8 bit disponibili con quasi 1000 pagine di documentazione. Confrontalo con circa 200-300 pagine per una CPU a 8 bit degli anni '80 e i popolari chip periferici con cui verrebbe utilizzato. Un dispositivo a 32 bit ricco di periferiche richiederà di consultare 2000-10.000 pagine di documentazione per comprendere la parte. Le parti con un moderno bordo grafico 3D su 20k pagine di documentazione.

Nella mia esperienza, ci vuole circa 10 volte più tempo per sapere tutto quello che c'è da sapere su un dato controller moderno a 32 bit come farebbe per una parte moderna a 8 bit. Con "tutto" intendo che sai come usare tutte le periferiche, anche in modi non convenzionali, e conosci il linguaggio macchina, l'assemblatore che la piattaforma usa e altri strumenti, gli ABI, ecc.

Non è affatto inconcepibile che molti, molti progetti vengano realizzati con una comprensione parziale. A volte è insignificante, a volte no. Il passaggio da una piattaforma all'altra deve essere fatto con la consapevolezza che ci sarà un prezzo di produttività a breve e medio termine da pagare per i guadagni di produttività percepiti da un'architettura più potente. Fai la tua dovuta diligenza.


3

Personalmente non mi preoccuperei troppo di aggiornare (8bit-> 32bit) uC della stessa famiglia e stai aumentando le specifiche su tutta la linea. In genere, non faccio nulla fuori dalla norma con i tipi di dati poiché può essere difficile da mantenere lungo la strada.

Il downgrade di un codice dispositivo è una storia diversa.


3
La dimensione dei tipi di dati è determinata dal compilatore, non dall'architettura del processore. Un processore a 8 bit può avere ints a 32 bit, anche se saranno necessarie più istruzioni per manipolarli.
Joe Hass,

buon commento- ho rimosso la prima riga a causa della correzione.
Nick Tullos,

@JoeHass: Un compilatore per un processore a 8 bit potrebbe definire intsia 32 bit, o anche 64 per questo, ma sono al corrente di compilatori 8 bit esistenti che in realtà non definiscono intessere maggiore di 16 bit, o promuovere Valori di 16 bit per qualsiasi cosa più grande.
supercat,

-1

Gli MCU a 32 bit consumano molta più energia per uno. E richiedono più circuiti di supporto.

Uno non passa davvero a 32 bit da 8 bit ... Continuerai a usarli entrambi, spesso insieme. La linea di fondo è che dovresti usare (e imparare) tutto ciò che è appropriato per il lavoro. Impara ARM perché ben fa oscillare il mondo incorporato in questo momento e continuerà a farlo. Impara anche AVR o PIC perché sono fantastici controller di scheda.

Probabilmente sperimenterai la stessa angoscia che passa da AVR a ARM come faresti da ARM a x86, la dimensione del bus in realtà non fa molta differenza. Tuttavia, tutto l'hardware extra avanzato lo fa. Passare dagli interrupt standard a un array di interrupt vettoriale con 6 livelli di priorità sarà molto più difficile che capire come contare fino a quattro miliardi.


4
Non so se sia corretto affermare che le MCU a 32 bit siano intrinsecamente più assetate di energia. Almeno un'intera linea di prodotti dell'azienda ( microenergia ) è costituita da MCU a bassissima potenza e sono tutte basate su core ARM a 32 bit.
Connor Wolf,

3
Ho appena creato un circuito stm32l1 che dovrebbe funzionare per 7 anni su un cr2032
Scott Seidman,

2
Potete giustificare il commento che una MCU a 32 bit necessita di più "circuiti di supporto"? Penso che tu stia esprimendo diverse opinioni ingiustificate qui.
Joe Hass,

1
Inoltre, il tuo commento interruzioni vettoriali non ha molto senso, dal momento che puoi ottenere più livelli di priorità nei microcontrollori a 8 bit (vedi MCU Atmel xmega, che hanno 3 livelli di priorità) e avere interruzioni vettoriali è irrilevante quando ogni dispositivo hardware ha possedere comunque vettori indipendenti.
Connor Wolf,

2
Sto usando un processore Cortex-M0 a 32 bit per controllare un caricabatterie intelligente per un veicolo elettrico. Utilizza una singola alimentazione a 3,3 V. Ha un oscillatore interno e PLL, quindi non ho nemmeno bisogno di un cristallo. Sto usando un pacchetto DIP a 28 pin ma posso ottenere un Cortex-M0 in un DIP a 8 pin se lo desidero. Come può essere più complesso di un tipico PIC o AVR?
Joe Hass,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.