Wie unterschiedlich sind 8-Bit-Mikrocontroller von 32-Bit-Mikrocontrollern, wenn es um deren Programmierung geht

19

Richtig, wir haben derzeit 8-Bit-, 16-Bit- und 32-Bit-Mikrocontroller auf dieser Welt. Alle von ihnen werden oft verwendet. Wie unterschiedlich ist es, 8-Bit- und 16-Bit-Mikrocontroller zu programmieren? Ich meine, erfordert es eine andere Technik oder Fertigkeit? Nehmen wir zum Beispiel Mikrochip. Welche neuen Dinge muss eine Person lernen, wenn sie von 8-Bit-Mikrocontrollern zu 32-Bit-Mikrocontrollern wechseln möchte?

quantum231
quelle
Nein. Sicher gibt es unterschiedliche Bedenken, aber diese betreffen hauptsächlich die gerätespezifischen Details. Ist beispielsweise ein unausgerichteter Wortzugriff zulässig? (Auf ARM ist es nicht - noch auf x86 ist es). Diese Frage ist nicht spezifisch genug.
Chris Stratton
Wow Leute, danke für die Antworten. Es gibt also tatsächlich sehr wichtige Unterschiede, die bei der Programmierung von 32-Bit-Prozessoren gegenüber 8-Bit-Prozessoren berücksichtigt werden müssen. Hier bezog ich mich auf C, da ich denke, dass die meisten Leute sich aus Gründen, die wir alle sehr gut kennen, nicht mit Assembly zum Programmieren befassen. Vielen Dank für die ausführlichen Antworten, ich weiß das sehr zu schätzen.
quantum231
Mit den 32-Bit-UCS gibt es VIEL mehr Optionen und VIEL mehr Register, die Sie richtig machen müssen. Ich denke, es hängt davon ab, was Sie tun. Heutzutage können Sie ein Entwicklungsboard, einen Compiler, einen Debugger und eine IDE für etwa 50 US-Dollar erwerben. Früher würde das fast 1000 Dollar kosten.

Antworten:

33

Im Allgemeinen bedeutet der Wechsel von 8- auf 16- auf 32-Bit-Mikrocontroller, dass Sie weniger Ressourcen, insbesondere Speicher, und weniger Registerbreite für arithmetische und logische Operationen benötigen. Die 8-, 16- und 32-Bit-Moniker beziehen sich im Allgemeinen sowohl auf die Größe der internen und externen Datenbusse als auch auf die Größe der internen Register, die für arithmetische und logische Operationen verwendet werden (früher nur ein oder zwei sogenannte Akkumulatoren) , jetzt gibt es normalerweise Registerbanken von 16 oder 32).

E / A-Port Portgrößen folgen im Allgemeinen auch der Datenbusgröße, sodass ein 8-Bit-Mikro 8-Bit-Ports, ein 16-Bit-Mikro 16-Bit-Ports usw. hat.

Trotz eines 8-Bit-Datenbusses verfügen viele 8-Bit-Mikrocontroller über einen 16-Bit-Adressbus und können 2 ^ 16- oder 64-KByte-Speicher adressieren (was nicht bedeutet, dass sie irgendwo in der Nähe davon implementiert sind). Einige 8-Bit-Mikros, wie die Low-End-PICs, verfügen jedoch möglicherweise nur über einen sehr begrenzten RAM-Speicher (z. B. 96 Byte auf einem PIC16).

Um dieses begrenzte Adressierungsschema zu umgehen, verwenden einige 8-Bit-Mikros Paging, wobei der Inhalt eines Seitenregisters eine von mehreren zu verwendenden Speicherbänken bestimmt. Normalerweise ist ein gemeinsamer RAM verfügbar, unabhängig davon, auf was für ein Seitenregister eingestellt ist.

16-Bit-Mikrocontroller sind im Allgemeinen auf 64 KB Speicher beschränkt, können jedoch auch Paging-Techniken verwenden, um dies zu umgehen. 32-Bit-Mikrocontroller unterliegen natürlich keinen derartigen Einschränkungen und können bis zu 4 GB Arbeitsspeicher adressieren.

Zusammen mit den verschiedenen Speichergrößen ergibt sich die Stapelgröße. In den unteren Mikros kann dies in einem speziellen Speicherbereich implementiert werden und sehr klein sein (viele PIC16s haben einen 8-Level-Deep-Call-Stack). In den 16-Bit- und 32-Bit-Mikros befindet sich der Stapel normalerweise im allgemeinen RAM und ist nur durch die Größe des RAM begrenzt.

Es gibt auch große Unterschiede in der Größe des Speichers - sowohl des Programms als auch des Arbeitsspeichers -, der auf den verschiedenen Geräten implementiert ist. 8-Bit-Mikros haben möglicherweise nur ein paar hundert Bytes RAM und ein paar tausend Bytes Programmspeicher (oder viel weniger - der PIC10F320 hat beispielsweise nur 256 14-Bit-Flash-Wörter und 64 Bytes RAM). 16-Bit-Mikros verfügen möglicherweise über einige tausend Byte RAM und Zehntausende Byte Programmspeicher. 32-Bit-Mikros haben häufig mehr als 64 KB RAM und möglicherweise 1/2 MB oder mehr Programmspeicher (der PIC32MZ2048 verfügt über 2 MB Flash und 512 KB RAM; der für Grafiken optimierte PIC32MZ2064DAH176 verfügt über 2 MB Flash und satte 32 MB On-Chip-RAM).

Wenn Sie in Assemblersprache programmieren, sind die Beschränkungen der Registergröße sehr offensichtlich. Beispielsweise ist das Hinzufügen von zwei 32-Bit-Zahlen bei einem 8-Bit-Mikrocontroller eine mühsame Aufgabe, bei einem 32-Bit-Mikrocontroller jedoch eine triviale. Wenn Sie in C programmieren, ist dies weitgehend transparent, aber der zugrunde liegende kompilierte Code ist für den 8-Bitter-Code natürlich viel größer.

Ich sagte weitgehend transparent, weil die Größe der verschiedenen C-Datentypen von einer Größe Mikro zur anderen unterschiedlich sein kann; Beispielsweise kann ein Compiler, der auf ein 8- oder 16-Bit-Mikro abzielt, mit "int" eine 16-Bit-Variable mit Vorzeichen bezeichnen, und auf einem 32-Bit-Mikro wäre dies eine 32-Bit-Variable. Viele Programme verwenden daher #defines, um explizit die gewünschte Größe anzugeben, z. B. "UINT16" für eine vorzeichenlose 16-Bit-Variable.

Wenn Sie in C programmieren, ist der größte Einfluss die Größe Ihrer Variablen. Wenn Sie beispielsweise wissen, dass eine Variable immer kleiner als 256 ist (oder bei Vorzeichen im Bereich von -128 bis 127 liegt), sollten Sie ein 8-Bit-Zeichen (vorzeichenloses Zeichen oder Zeichen) auf einem 8-Bit-Mikro (z. B. PIC16) verwenden ), da die Verwendung einer größeren Größe sehr ineffizient ist. Ebenso die 16-Bit-Variablen auf einem 16-Bit-Mikro (zB PIC24). Wenn Sie ein 32-Bit-Mikro (PIC32) verwenden, spielt dies keine Rolle, da der MIPS-Befehlssatz Byte-, Wort- und Doppelwortbefehle enthält. Bei einigen 32-Bit-Mikros ist die Bearbeitung einer 8-Bit-Variablen aufgrund der Maskierung jedoch möglicherweise weniger effizient als bei einer 32-Bit-Variablen, wenn ihnen solche Anweisungen fehlen.

Wie das Forummitglied vsz ausführte, ist diese Variable auf Systemen, auf denen Sie eine Variable haben, die größer als die Standardregistergröße ist (z. B. eine 16-Bit-Variable auf einem 8-Bit-Mikro), zwischen zwei Threads oder zwischen dem Basisthread geteilt und ein Interrupt-Handler, muss man jede Operation (einschließlich nur Lesen) an der Variablen atomic ausführen , das heißt, es scheint, als würde sie als eine Anweisung ausgeführt. Dies wird als kritischer Abschnitt bezeichnet. Die Standardmethode, um dies zu verringern, besteht darin, den kritischen Abschnitt mit einem Deaktivierungs- / Aktivierungs-Interrupt-Paar zu umgeben.

Beim Übergang von 32-Bit-Systemen zu 16-Bit- oder 16-Bit- zu 8-Bit-Operationen müssen daher alle Operationen auf Variablen dieses Typs, die jetzt größer als die Standardregistergröße sind (aber noch nicht vorhanden waren), als kritisch eingestuft werden Sektion.

Ein weiterer Hauptunterschied von einem PIC-Prozessor zum anderen ist der Umgang mit Peripheriegeräten. Dies hat weniger mit der Wortgröße als vielmehr mit der Art und Anzahl der Ressourcen zu tun, die auf jedem Chip zugewiesen sind. Im Allgemeinen hat Microchip versucht, die Programmierung des gleichen Peripheriegeräts, das auf verschiedenen Chips verwendet wird, so ähnlich wie möglich zu gestalten (z. B. timer0), es wird jedoch immer Unterschiede geben. Durch die Verwendung ihrer Peripheriebibliotheken werden diese Unterschiede weitgehend ausgeblendet. Ein letzter Unterschied ist die Behandlung von Interrupts. Auch hier gibt es Hilfe aus den Microchip-Bibliotheken.

Tcrosley
quelle
Es kann erwähnenswert sein, dass 8-Bit-Prozessoren auf Assemblersprachenebene tendenziell weniger Register und weniger orthogonale Anweisungen haben (AVR ist eine eher RISCy-Ausnahme), was eine Folge von Designbeschränkungen bei ihrer Entwicklung ist. 32-Bit-Prozessoren sind in der Regel RISC-Abkömmlinge (Renesas 'RX, ein modernes CISC, ist eine Ausnahme, und Freescales ColdFire stammt von m68k ab).
Paul A. Clayton
9
Um nicht nur für diesen Zusatz eine neue Antwort zu beginnen, ist es meiner Meinung nach wichtig hinzuzufügen, dass der Übergang von 32 Bit auf 16 von 16 auf 8 böse Überraschungen verursachen kann, da die Arithmetik nicht mehr atomar ist. Wenn Sie zwei 16-Bit-Nummern zu einem 8-Bit-Mikrocontroller hinzufügen und diese in einem Interrupt verwenden, müssen Sie darauf achten, dass sie threadsicher sind. Andernfalls fügen Sie möglicherweise nur die Hälfte davon hinzu, bevor der Interrupt ausgelöst wird Ein ungültiger Wert in Ihrer Interrupt-Serviceroutine.
vsz
2
@vsz - Guter Punkt, habe das vergessen. Im Allgemeinen sollte man Interrupts um jeden Zugriff (einschließlich nur Lesen) jeder flüchtigen Variablen deaktivieren, die größer als die Standardregistergröße ist.
Tcrosley
1
Stimmt es, dass 32-Bit-UC normalerweise 32-Bit-E / A-Schnittstellen hat? Ich denke, dass es sowieso häufiger nur serielle Kommunikation ist.
Clabacchio
1
@clabacchio Meine Erfahrung ist, dass alle E / A-Port- Register als 32-Bit definiert sind, aber manchmal sind die oberen 16 Bit 16-31 nicht belegt, sodass ein paralleler Port immer noch 16 physische Pins hat. In anderen Fällen werden wie bei einem RTCC-Register alle 32 Bits verwendet.
Tcrosley
8

Ein gemeinsamer Unterschied zwischen 8-Bit- und 32-Bit-Mikrocontrollern besteht darin, dass 8-Bit-Mikrocontroller häufig über einen Speicher- und E / A-Speicherbereich verfügen, auf den unabhängig vom Ausführungskontext in einem einzigen Befehl zugegriffen werden kann, während 32-Bit-Mikrocontroller häufig zugreifen erfordern eine Mehrfachbefehlssequenz. Beispielsweise kann bei einem typischen 8-Bit-Mikrocontroller (HC05, 8051, PIC-18F usw.) der Zustand eines Portbits unter Verwendung eines einzelnen Befehls geändert werden. Auf einem typischen ARM (32-Bit) wäre, wenn der Registerinhalt anfangs unbekannt wäre, eine Befehlssequenz mit vier Befehlen erforderlich:

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

In den meisten Projekten verbringt der Controller die meiste Zeit mit anderen Aufgaben als dem Setzen oder Löschen einzelner E / A-Bits. Daher spielt es oft keine Rolle, dass Vorgänge wie das Löschen eines Port-Pins mehr Anweisungen erfordern. Andererseits wird es Zeiten geben, in denen Code viele Port-Manipulationen ausführen muss, und die Fähigkeit, solche Dinge mit einer einzigen Anweisung auszuführen, kann sich als sehr wertvoll erweisen.

Auf der anderen Seite sind 32-Bit-Controller ausnahmslos so konzipiert, dass sie effizient auf viele Arten von Datenstrukturen zugreifen können, die im Speicher gespeichert werden können. Im Vergleich dazu greifen viele 8-Bit-Controller sehr ineffizient auf Datenstrukturen zu, die nicht statisch zugeordnet sind. Ein 32-Bit-Controller kann in einem Befehl einen Array-Zugriff ausführen, der ein halbes Dutzend oder mehr Befehle in einem typischen 8-Bit-Controller erfordern würde.

Superkatze
quelle
Ich nehme an, Sie meinten "Bit-Bang". Erwähnenswert ist, dass ARM Bitbandbereiche unterstützt (bei denen Wortoperationen Einzelbitoperationen sind) und die anwendungsspezifische MCU-Erweiterung für MIPS Atomically Set / Clear Bit innerhalb von Byte-Befehlen (ASET / ACLR) bereitstellt.
Paul A. Clayton
@ PaulA.Clayton: Ich habe mir die MIPS in den letzten 20 Jahren nicht wirklich angesehen. Was die Bit-Band-Regionen angeht, so habe ich nie eine Möglichkeit gefunden, sie in vernünftig aussehendem Code zu verwenden, und selbst wenn ich sie verwenden könnte, würden sie nur einen Befehl speichern, es sei denn, man verwendet einen wahnsinnigen Programmierfehler Sie könnten zwei speichern [R0 mit einer geraden oder ungeraden Adresse laden, je nachdem, ob das Bit gesetzt oder gelöscht werden soll, und den Versatz im Speicherbefehl entsprechend anpassen, um dies zu kompensieren]. Übrigens, haben Sie eine Idee, warum die Bitbandregion Wortadressen verwendet?
Supercat
@supercat: Mit der Wortadressierung können Sie über Pointer Subscripting ( region_base[offset]) von C oder C ++ auf die Bitband-Regionen zugreifen
Ben Voigt,
@BenVoigt Und warum könnte man das nicht mit Byteadressierung machen? (Vielleicht wäre ein möglicher Grund, die Erwartung / Hoffnung, dass Zwei-Bit- und Vier-Bit-Operationen unterstützt würden, zu beseitigen.)
Paul A. Clayton
@BenVoigt: Das Skalieren der Bitnummer um den Faktor 4 kostet oft einen zusätzlichen Befehl. Eigentlich hätte ich lieber ein paar Bereiche als einen Bitband-Bereich gesehen, die einen festen Versatz relativ zu "normalen" Speicherzugriffen aufweisen, aber angeben, dass in einen Bereich geschrieben werden soll Wenn möglich, werden nur Bits "gesetzt", und beim Schreiben in die anderen werden nur Bits "gelöscht". Wenn der Bus getrennte Steuerbits "Write-ones-enable" und "Write-zero-enable" hätte, könnte man die Dinge erreichen, die Bit-banding erlaubt, aber in vielen Fällen das Lesen-Modifizieren-Schreiben vermeiden.
Supercat
6

Der größte praktische Unterschied ist der Umfang der Dokumentation, um wirklich den gesamten Chip vollständig zu verstehen. Es gibt 8-Bit-Mikrocontroller mit fast 1000 Seiten Dokumentation. Vergleichen Sie das mit ungefähr 200-300 Seiten für eine 8-Bit-CPU aus den 1980er Jahren und den beliebten Peripherie-Chips, mit denen sie verwendet werden würde. Für ein peripheres 32-Bit-Gerät müssen Sie 2000 bis 10.000 Seiten Dokumentation durchgehen, um das Teil zu verstehen. Die Teile mit moderner 3D-Grafik stehen auf 20.000 Seiten Dokumentation.

Nach meiner Erfahrung dauert es ungefähr zehnmal so lange, bis alles bekannt ist, was über einen bestimmten modernen 32-Bit-Controller bekannt ist, wie es für einen modernen 8-Bit-Teil der Fall wäre. Mit "alles" meine ich, dass Sie wissen, wie Sie alle Peripheriegeräte verwenden, auch auf unkonventionelle Weise, und die Maschinensprache, den Assembler, den die Plattform verwendet, sowie andere Tools, die ABI (s) usw. kennen.

Es ist überhaupt nicht unvorstellbar, dass viele, viele Entwürfe mit teilweisem Verständnis ausgeführt werden. Manchmal ist es belanglos, manchmal nicht. Das Wechseln der Plattform muss mit dem Bewusstsein erfolgen, dass die Produktivität kurz- und mittelfristig einen Preis hat, den Sie für wahrgenommene Produktivitätssteigerungen durch eine leistungsfähigere Architektur zahlen. Tun Sie Ihre Due Diligence.

Setzen Sie Monica wieder ein
quelle
3

Ich persönlich würde mir nicht allzu viele Gedanken darüber machen, ein Upgrade (8-Bit-> 32-Bit) der gleichen Familie durchzuführen, und Sie erhöhen die technischen Daten auf ganzer Linie. Im Allgemeinen tue ich mit den Datentypen nichts, was nicht der Norm entspricht, da es schwierig sein kann, sie auf dem Laufenden zu halten.

Das Herabstufen eines Gerätecodes ist eine andere Geschichte.

Nick Tullos
quelle
3
Die Größe der Datentypen wird vom Compiler und nicht von der Prozessorarchitektur bestimmt. Ein 8-Bit-Prozessor kann 32-Bit-Ints haben, obwohl mehrere Anweisungen erforderlich sind, um sie zu bearbeiten.
Joe Hass
guter Kommentar - Ich habe die erste Zeile wegen der Korrektur entfernt.
Nick Tullos
@JoeHass: Ein Compiler für einen 8-Bit - Prozessor könnte definieren int32 Bits sein, oder sogar 64 für diese Angelegenheit, aber ich bin mir nicht bewusst von bestehenden 8-Bit - Compiler , die tatsächlich tun definieren int, dass sie größer als 16 Bit oder fördern 16-Bit-Werte für alles Größere.
Supercat
-1

32-Bit-MCUs verbrauchen für eine viel mehr Strom. Und benötigen mehr Support-Schaltungen.

Man geht nicht wirklich von 8-Bit zu 32-Bit über ... Sie werden weiterhin beide verwenden, oft zusammen. Unter dem Strich sollten Sie alles verwenden (und lernen), was für den Job angemessen ist. Lerne ARM, weil es jetzt die eingebettete Welt erschüttert und es auch weiterhin tun wird. Lernen Sie auch AVR oder PIC, weil sie großartige Board-Controller sind.

Sie werden wahrscheinlich sowieso so viel Stress beim Umstieg von AVRs auf ARMs haben wie bei ARM auf x86. Die Größe des Busses macht eigentlich keinen großen Unterschied. Die gesamte erweiterte Hardware funktioniert jedoch. Der Übergang von Standard-Interrupts zu einem vektorisierten Interrupt-Array mit 6 Prioritätsstufen ist viel schwieriger, als herauszufinden, wie man bis zu vier Milliarden zählt.

Hugo
quelle
4
Ich weiß nicht, ob es richtig ist, zu behaupten, dass 32-Bit-MCUs von Natur aus mehr Strom verbrauchen. Mindestens ein Unternehmen ( Energy Micro ) verfügt über eine komplette Produktlinie von Ultra-Low-Power-MCUs, die alle auf 32-Bit-ARM-Core basieren.
Connor Wolf
3
Ich habe gerade eine stm32l1-Schaltung ausgearbeitet, die 7 Jahre lang auf einem cr2032 laufen sollte
Scott Seidman,
2
Können Sie den Kommentar rechtfertigen, dass eine 32-Bit-MCU mehr "Support-Schaltkreise" benötigt? Ich denke, Sie äußern hier mehrere ungerechtfertigte Meinungen.
Joe Hass
1
Außerdem macht der Kommentar zu vektorisierten Interrupts wenig Sinn, da Sie in 8-Bit-Mikrocontrollern (siehe Atmel xmega-MCUs mit 3 Prioritätsstufen) mehrere Prioritätsstufen erhalten können und es unerheblich ist, vektorisierte Interrupts zu verwenden, wenn jedes Hardwaregerät über eine solche verfügt eigene unabhängige Vektoren sowieso.
Connor Wolf
2
Ich verwende einen 32-Bit-Cortex-M0-Prozessor zur Steuerung eines intelligenten Batterieladegeräts für ein Elektrofahrzeug. Es wird eine einzelne 3,3-V-Versorgung verwendet. Es hat einen internen Oszillator und eine PLL, so dass ich nicht einmal einen Kristall brauche. Ich verwende ein 28-poliges DIP-Paket, kann aber einen Cortex-M0 in einem 8-poligen DIP erhalten, wenn ich möchte. Wie kann das komplexer sein als ein typischer PIC oder AVR?
Joe Hass