Dieses Kapitel vermittelt grundlegendes Wissen über die Mikrocontroller-Hardware, das für die praktische Anwendung erforderlich ist. Die Leser werden in diesem Abschnitt keine übermäßig komplexe Programmlogik oder fortgeschrittene Schaltpläne mit hochmodernen optimierten Designs finden. Stattdessen zeigen die folgenden praktischen Beispiele, dass die eingebettete Programmierung weder eine exklusive Fähigkeit noch ein talentabhängiges Handwerk ist – es ist einfach der Prozess, modulare Funktionslogik über eine standardisierte Befehlssyntax zusammenzusetzen. Seien Sie versichert, dass Hardware-Design und iterative Entwicklung einem konsistenten Kernablauf folgen: „testen, anpassen, wiederholen“. Natürlich steigt die Projektkomplexität mit der Erfahrung; dieselbe puzzleartige Komponentenlogik gilt sowohl für Hobby-Prototypen als auch für industrielle professionelle Architekturentwicklung...
Während sich diese Einführungsdemos ausschließlich auf grundlegende Funktionsabläufe konzentrieren, birgt jede eingebettete Hardwareplattform eine oft unterschätzte zugrunde liegende Sicherheitsrisikoschicht, die in Anfänger-Tutorials selten behandelt wird. Der zentrale Mikrocontroller (MCU), der diese einfachen Steuerroutinen ausführt, kann später in kommerzielle Endprodukte integriert werden, wo der Schutz des ausführbaren Quellcodes vor unbefugtem Zugriff zu einer wichtigen Designpriorität wird. Viele unerfahrene Ingenieure glauben fälschlicherweise, dass der eingebaute Lockbit-Sicherungsmechanismus den externen Lesezugriff auf den internen Flash-Speicher vollständig blockieren kann, doch diese Annahme ist nicht universell zuverlässig. In realen Bedrohungsszenarien können böswillige Akteure Chip-Dekapsulationsabläufe einsetzen, um die bloßen Silizium-Die-Schichten freizulegen und eine direkte Mikrosondierung der sicherheitssteuernden Hardwaresicherungen durchzuführen. Sobald das Gehäuse entfernt ist, können Gegner einen vollständigen Speicherauszug aller Programmspeicherbereiche extrahieren und so eine vollständige Firmware-Extraktion ohne gültige Authentifizierungsnachweise durchführen. Das eingebaute EEPROM-Chipsatz, das üblicherweise Werkskalibrierungsparameter und kryptografische Sicherheitsschlüssel speichert, ist ähnlichen Schwachstellen gegenüber solchen physischen Hardware-Eindringangriffen ausgesetzt. Bestimmte Bedrohungsakteure nutzen Laborgeräte mit fokussiertem Ionenstrahl (FIB), um einzelne Sicherungsschaltkreise selektiv zu modifizieren und eine dauerhafte Entsperrung von als geschützt markierten Speicherzonen zu erzwingen. Andere Angreifer nutzen Seitenkanal-Analysemethoden, um vollständige Programmbinarys schrittweise auszulesen, ohne eine Hardware-Manipulationserkennung auszulösen. Im schlimmsten Exploit-Szenario ermöglicht ein vollständiger Auszug sowohl der Flash- als auch der EEPROM-Speicherpartitionen es Angreifern, identische Hardware-Repliken herzustellen, die voll funktionsfähige Geräteklone produzieren und den Wert des proprietären geistigen Eigentums vollständig untergraben. Aus diesem Grund müssen Entwickler bereits beim Erlernen der grundlegenden digitalen Ein-/Ausgangslogik und Timing-Steuerungsroutinen erkennen, dass dieselben Chip-Pins und Kernregister bei bösartigen Reverse-Engineering-Kampagnen ausgenutzt werden können. Die Wiederherstellung eines nicht funktionierenden eingebetteten Geräts erfordert gelegentlich die Umgehung von Sicherheitssperren durch Spannungsglitch-Injektion – eine legitime Hardware-Reparaturtechnik, die gleichzeitig einen Angriffspunkt schafft. Die Beherrschung der zugrunde liegenden Lockbit-Betriebslogik ist eine obligatorische Kompetenz sowohl für eingebettete Firmware-Entwickler als auch für dedizierte Hardwaresicherheitsanalysten. Eine große Anzahl kommerzieller eingebetteter Geräte hat aufgrund unsachgemäß konfigurierter Sicherungssicherungen vollständige Verletzungen des geistigen Eigentums erlitten, wodurch der ausführbare Code vollständig für den externen Abruf freigegeben wurde. Ein einfaches Auslesen der Chip-Konfigurationsspeicherbytes kann alle Sicherheitsrichtlinieneinstellungen offenlegen und Bedrohungsakteure direkt zum schwächsten Exploit-Vektor führen. Selbst die spätere einfache Watchdog-Timer-Demonstration kann zur Implementierung einer Hardware-Manipulationserkennungslogik umfunktioniert werden. In der realen Ingenieurspraxis müssen Entwickler ein Gleichgewicht zwischen Hardware-Funktionalität und Einbruchschutzmaßnahmen finden, um sicherzustellen, dass eine unbefugte Firmware-Extraktion technisch und finanziell undurchführbar bleibt. Die nachfolgenden praktischen Demos veranschaulichen elementare Hardware-Arbeitsabläufe, zeigen jedoch implizit, wie Kern-MCU-Peripheriegeräte wie Timer, Interrupt-Controller und serielle Kommunikationsschnittstellen zur Implementierung robuster Sicherheitshärtungs-Gegenmaßnahmen umfunktioniert werden können. Beispielsweise kann die Verwendung von Timermodulen zur Erzeugung zufälliger Timing-Offsets zeitbasierte Seitenkanalangriffe abmildern, die auf das Speicherauszug vertraulicher Geheimdaten abzielen. Darüber hinaus kann die UART-seriellen Übertragungslogik mit leichten Verschlüsselungsprotokollen umhüllt werden, um das Abhören von Rohdaten während unbefugter Leseversuche zu blockieren. LED-Multiplexing-Anzeigeschaltungen, obwohl scheinbar trivial, schaffen ein kritisches Bewusstsein für Timing-Empfindlichkeit – eine grundlegende Fähigkeit, die für die Implementierung sicherer authentifizierter Bootsequenzen erforderlich ist. Das EEPROM-Datenspeicherbeispiel behandelt direkt Workflows zur persistenten Datenwiederherstellung, ein technisches Konzept, das sich auf die sichere langfristige Aufbewahrung kryptografischer Schlüssel erstreckt. Letztendlich sollte jede Zeile eingebetteten Firmware-Codes unter der Annahme geschrieben werden, dass feindliche Akteure irgendwann vollen physischen Zugriff auf die Zielhardware erlangen könnten. Der Sicherheitssperrmechanismus dient lediglich als primäre Verteidigungsbarriere; ein umfassender Hardware-Schutz beruht auf mehrschichtigen Sicherheitsvorkehrungen, die eine Chip-Dekapsulation und Silizium-Sondierung für Angreifer wirtschaftlich undurchführbar machen. Dieses Kapitel schafft ein grundlegendes Sicherheitsbewusstsein, ohne tief in spezialisierte Reverse-Engineering-Exploit-Taktiken einzusteigen. Mit diesem doppelten Fokus auf funktionale Betriebsabläufe und eingebettete Sicherheit wenden wir uns nun der Betrachtung grundlegender Mikrocontroller-Verdrahtungsschemata und unterstützender Peripherie-Hardwarekomponenten zu.
Wie im obigen Schema dargestellt, müssen drei obligatorische Signaldomänen korrekt verdrahtet werden, um einen stabilen Mikrocontroller-Betrieb zu gewährleisten:
Dies sind extrem minimale Schaltungstopologien, aber die Hardware-Komplexität steigt drastisch für Geräte, die zur Steuerung teurer Industriemaschinen oder zur Aufrechterhaltung sicherheitskritischer Arbeitsabläufe eingesetzt werden. Dennoch reicht dieses vereinfachte Schaltungslayout für einführende Lernzwecke aus...
Obwohl diese Mikrocontroller-Variante mehrere Eingangsspannungspegel unterstützt, gibt es keinen praktischen Grund, unnötige Fehlerrisiken durch das Testen marginaler Spannungsbedingungen einzuführen. Eine 5V DC-Versorgung bleibt der am weitesten verbreitete Industriestandard. Das gezeigte Schaltbild implementiert den kostengünstigen Dreipol-Positiv-Spannungsregler LM7805, der eine konstante stabile Ausgangsspannung und ausreichende 1A-Spitzenstromkapazität liefert, um den Mikrocontroller-Kern sowie alle angeschlossenen Hilfsperipheriegeräte zu versorgen.
Für eine zuverlässige Mikrocontroller-Initialisierung muss ein logisch niedriges (0V) Signal am RS-Reset-Pin anliegen. Der den RS-Reset-Pin mit der VCC-Versorgungsschiene verbindende Taster ist nicht zwingend erforderlich, wird jedoch auf fast allen Prototypenplatinen verbaut. Dieser Taster ermöglicht eine kontrollierte erzwungene Reinitialisierung, falls die Firmware-Ausführung in einen instabilen Fehlerzustand gerät. Das Anlegen von 5V an diesen Pin löst einen vollständigen Chip-Reset aus und startet die Programmausführung von der Firmware-Eintrittsvektoradresse neu.
Obwohl der Mikrocontroller einen internen RC-Oszillator integriert, erfordert ein stabiler deterministischer Betrieb einen externen Quarzkristall mit zwei passenden Lastkondensatoren, um die Kernbetriebsfrequenz festzulegen, die direkt den Befehlsausführungsdurchsatz des Chips definiert.
Trotz der Tatsache, dass es sich um hochmoderne kompakte Rechenhardware handelt, erfüllt ein eigenständiger Mikrocontroller ohne angeschlossene Hilfsperipherie keinen praktischen Zweck. Vereinfacht gesagt, haben Spannungspegeländerungen an den Ein-/Ausgangspins des Chips keine funktionale Bedeutung, es sei denn, sie werden zur Steuerung definierter Operationen genutzt: Ein-/Ausschalten von Lasten, Datenverschiebung, visuelle Statusanzeige und mehr.
Keine Peripheriekomponente ist einfacher als mechanische Schalter und Taster; sie bieten die einfachste Methode zur Erkennung von Spannungszustandsübergängen an Mikrocontroller-Eingangspins.
Anwendungen, die absolute Eingangssignalstabilität erfordern, benötigen robustere Hardware-Gegenmaßnahmen. Eine RS-Flipflop-Schaltung ändert den logischen Ausgangszustand nur einmal beim ersten Kontaktübergang und ignoriert nachfolgende Prellimpulse vollständig. Obwohl diese Hardware-Lösung einen teureren SPDT-Schalter erfordert, eliminiert sie Prellartefakte vollständig und ermöglicht die Erkennung extrem kurzer Eingangsimpulse, die passive RC-Filter maskieren würden, da im Signalpfad keine Ladungsspeicherkondensatoren verwendet werden.
Das dargestellte Schema zielt auf die 8051-Mikrocontroller-Architektur ab. Ein Darlington-Transistorpaar verstärkt den Ansteuerstrom, um die Relaisspule zu erregen – eine obligatorische Lösung für logisch-hohe Ausgangszustände, bei denen der Mikrocontroller-Pin als hochohmiger Eingang mit minimaler Stromquellenkapazität arbeitet, was gegen die Standard-Designrichtlinien für Treiberschaltungen verstößt, aber für die spezifischen elektrischen Eigenschaften dieser Architektur erforderlich ist.
Eine antiparallele Freilaufdiode wird parallel zur Relaisspule geschaltet, um zerstörerische hochspannungsinduktive Spannungsspitzen zu unterdrücken, die beim abrupten Abschalten des Spulenstroms entstehen. Diese Klemmdiode absorbiert die induktive Spannungsspitze und schützt die umgebenden Halbleiterbauteile vor Durchbruchschäden.
Ein Segment-LED-Anzeigemodul integriert mehrere diskrete LED-Dioden in einem einzigen Kunststoffgehäuse. Es gibt zahlreiche Anzeigevarianten, die Dutzende einzelner LED-Segmente zur Darstellung alphanumerischer Symbole und Ziffern enthalten.
Die direkte Verdrahtung mehrstelliger LED-Anzeigen mit dem Mikrocontroller verbraucht große Mengen der begrenzten E/A-Pin-Ressourcen, eine kritische Hardware-Einschränkung, insbesondere wenn mehrstellige numerische Anzeigen erforderlich sind. Die Ressourcenbeschränkung wird sofort deutlich, wenn man eine zweistellige sechsstellige numerische Anzeige realisieren will, die theoretisch 96 dedizierte Ausgangspins erfordern würde, wenn sie ohne Multiplexing verdrahtet wird. Die Standard-Industrielösung für diese Hardware-Einschränkung ist das Anzeige-Multiplexing, das auf einer optischen Persistenz-vision-Illusion basiert, die den Prinzipien der Filmprojektion entspricht. Es wird nur ein einzelnes Ziffernsegment-Bank zu einem bestimmten Taktzyklus mit Strom versorgt, doch das schnelle sequenzielle Umschalten zwischen den Ziffernpositionen erzeugt die visuelle Wahrnehmung, dass alle Ziffern gleichzeitig leuchten.
Die Funktionslogik des obigen Schemas ist wie folgt: Zunächst wird ein Byte-Datenwert entsprechend der Einerstelle an einem Mikrocontroller-Port angelegt, während gleichzeitig der Transistor T1 aktiviert wird, um die Einer-Anzeigebank zu aktivieren. Nach einer kurzen festen Verzögerung wird T1 deaktiviert, der Zehner-Bytewert wird an das Portregister gesendet, und T2 aktiviert die Zehner-Anzeigebank. Diese sequenzielle Aktivierungssequenz wird kontinuierlich mit hoher Bildwiederholrate über alle Ziffernpositionen und ihre entsprechenden Treibertransistoren zyklisch wiederholt.
Die grundlegende Natur des Mikrocontrollers als binäres Rechengerät, das ausschließlich die Logikpegel 0 und 1 interpretiert, wird bei der Zifferndarstellung vollständig deutlich. Der MCU hat kein inhärentes Verständnis für Dezimalstellenwerte (Einer, Zehner, Hunderter) oder übliche menschenlesbare Ziffernformen. Alle anzuzeigenden Werte müssen wie folgt standardisiert vorverarbeitet werden:
Zunächst wird ein mehrstelliger ganzzahliger Wert mithilfe dedizierter Firmware-Routinen in isolierte Einer-, Zehner- und Hunderterstellen zerlegt. Jeder extrahierte einzelne Ziffernwert wird in separaten 8-Bit-Registerbytes gespeichert. Die Zifferndarstellung erfolgt durch eine Bitmasken-Übersetzungslogik, die rohe binäre Zahlenwerte über eine einfache Unterroutine in eindeutige Segment-Aktivierungsbitmuster umwandelt. Als veranschaulichendes Beispiel wird der rohe Binärwert 0000 1000 (entsprechend der Dezimalziffer 8) in ein Segmentmasken-Bitmuster übersetzt, das alle sieben Hauptanzeigesegmente aktiviert, während das Dezimalpunktsegment aus bleibt. Wenn die Mikrocontroller-Portverdrahtung Bit 0 auf Segment A, Bit 1 auf Segment B, Bit 2 auf Segment C usw. abbildet, ergibt sich die standardisierte Bitmasken-Nachschlagetabelle für jede Dezimalziffer wie unten gezeigt.
Über die Dezimalziffern 0 bis 9 hinaus können einige Buchstaben des lateinischen Alphabets durch angepasste Bitmasken dargestellt werden: Großbuchstaben A, C, E, J, F, U, H, L; Kleinbuchstaben b, c, d, o, r, t.
Bei gemeinkathoden-Anzeigen müssen alle logischen 1- und 0-Werte in der Nachschlagetabelle invertiert werden, und es sind NPN-Bipolartransistoren als Zifferntreiber erforderlich.
Spezielle LCD-Module sind für die direkte Anbindung an Mikrocontroller ausgelegt und können nicht von generischen Standard-Logikschaltungen angesteuert werden. Diese Module zeigen anpassbare Textzeichenfolgen auf einer kompakten Flüssigkristalltafel an.
Eine Reihe von Stiftleisten verläuft entlang einer Kante der LCD-Leiterplatte, um die Verdrahtung mit dem Mikrocontroller zu erleichtern. Das Basismodul umfasst vierzehn nummerierte Signalpins; Varianten mit integrierter Hintergrundbeleuchtung fügen zwei zusätzliche Stromversorgungspins hinzu, insgesamt sechzehn. Die vollständigen Pin-Funktionsspezifikationen sind in der folgenden Tabelle aufgeführt:
Wenn nach dem Einschalten keine Textzeichen angezeigt werden oder alle Glyphen schwach erscheinen, besteht der erste Fehlerbehebungsschritt darin, den Kontrast-Einstellpotentiometer zu kalibrieren, um die richtige Spannungseinstellung zu überprüfen. Dieselbe Fehlerbehebungsprozedur gilt, wenn der Anzeigemodus (Ein-/Zweizeilen-Darstellung) während des Betriebs neu konfiguriert wird.
Der DDRAM-Speicher enthält die ASCII-Zeichenbytewerte, die für die Bildschirmdarstellung vorgesehen sind, mit einer Kapazität von insgesamt achtzig Zeichenbytes. Einzelne Speicheradressen entsprechen direkt den diskreten Zeichenzellenpositionen auf dem physischen LCD-Panel.
Die Kernbetriebslogik ist einfach: Konfigurieren Sie den LCD-Controller so, dass er Speicheradressen automatisch erhöht (Textverschiebung nach rechts), und legen Sie dann die Startadresse für die Zieltextzeichenfolge fest (z. B. hexadezimale Adresse 00).
Nach Abschluss dieses Konfigurationsschritts werden alle über den D0–D7-Datenbus gesendeten Zeichenbytes sequenziell von links nach rechts in der üblichen Lesereihenfolge dargestellt. Bei einer auf 00 hex gesetzten Basisadresse beginnt die Textdarstellung in der linken Zeichenzelle der oberen Anzeigezeile. Wenn mehr als sechzehn Zeichenbytes gesendet werden, verbleiben alle überschüssigen Daten im DRAM-Speicher, aber nur die ersten sechzehn Positionen bleiben auf dem Bildschirm sichtbar. Ein spezieller Anzeige-Verschiebebefehl muss ausgegeben werden, um versteckte Zeichendaten in das sichtbare Panel-Fenster zu scrollen. Funktional betrachtet fungiert das LCD-Panel als festes Viewport, das horizontal über den stationären DRAM-Speicherinhalt gleitet und so den visuellen Effekt eines über den Bildschirm laufenden Textes erzeugt.
Wenn der Cursorindikator aktiviert ist, wird er an der aktuell aktiven DRAM-Adressposition angezeigt. Nach dem Schreiben eines Zeichenbytes an die aktive Adresse erhöht der Controller automatisch die Zieladresse auf die nächste Zeichenzellenposition.
Als flüchtiger Speicher werden alle DRAM-Daten beim Ausschalten der Stromversorgung dauerhaft gelöscht.
Das CGROM-Lesespeicherbank enthält die werkseitig geladene Standard-Glyphen-Nachschlagetabelle mit allen vom LCD-Panel nativ unterstützten Zeichensymbolen, wobei jede eindeutige Glyphe einer festen statischen Speicheradresse zugeordnet ist.
Die CGROM-Speicheradressenoffsets entsprechen direkt den standardmäßigen ASCII-Codierungswerten. Wenn die aktive Firmware einen Befehl zum Senden des Zeichens 'P' an den LCD-Datenbus ausführt, wird der binäre Bytewert 0101 0000 auf den D0–D7-Datenleitungen angelegt. Dieser Binärwert entspricht der ASCII-Codierung für Großbuchstaben 'P', den der LCD-Controller verwendet, um die CGROM-Speicherbank zu indizieren und die entsprechende Glyphe an der Adresse 0101 0000 darzustellen. Diese Zuordnungsregel gilt universell für lateinische Groß- und Kleinbuchstaben, jedoch nicht direkt für Dezimalziffern.
Wie im vorhergehenden Zeichentabellendiagramm ersichtlich, sind alle Adressoffsets der Dezimalziffern um einen Basisoffsetwert von 48 relativ zu ihrem numerischen Wert nach oben verschoben: Ziffer 0 entspricht Adresse 48, Ziffer 1 Adresse 49, Ziffer 2 Adresse 50 usw. Daher muss die Firmware-Logik vor der Übertragung über den LCD-Datenbus die dezimale Konstante 48 zu jedem numerischen Ziffernbyte addieren, um eine korrekte Glyphendarstellung zu gewährleisten.
Von den frühen Computerarchitekturen bis zur modernen eingebetteten Hardware interpretieren digitale Verarbeitungssysteme nur binäre Zahlenwerte und können keine menschenlesbaren alphabetischen Zeichen nativ erkennen. Alle Daten, die zwischen einem Mikrocontroller und externer Peripheriehardware ausgetauscht werden, liegen im Binärformat vor, auch wenn sie von menschlichen Bedienern visuell als Textzeichen interpretiert werden; eine Standardtastatur ist ein anschauliches Beispiel dafür. Jedes druckbare Zeichen entspricht einem eindeutigen festen Binärbitmuster. Die ASCII-Codierung ist ein standardisierter Zeichensatz, der auf dem lateinischen Alphabet basiert und eine direkte Eins-zu-eins-Korrelation zwischen druckbaren grafischen Symbolen und ihren entsprechenden binären numerischen Darstellungen definiert.
Zusätzlich zu den werkseitig vordefinierten CGROM-Glyphen unterstützt der LCD-Controller die Darstellung vollständig benutzerdefinierter grafischer Symbole in der 5×8-Pixel-Zeichenmatrix über eine dedizierte 64-Byte-flüchtige CGRAM-Speicherpartition.
Die CGRAM-Speicherregister sind 8 Bit breit, aber nur die fünf niederwertigsten Bitpositionen werden für die Pixelmusterspeicherung verwendet. Ein logisch hohes Bit (1) in jedem Register entspricht einem leuchtenden Pixelpunkt, während acht aufeinanderfolgende Register-Speicherstellen das vollständige Pixelmuster für eine einzelne benutzerdefinierte Zeichenglyphe speichern. Das folgende Diagramm verdeutlicht dieses Speicherzuordnungsprinzip:
Benutzerdefinierte Glyphenmuster werden typischerweise beim Firmware-Start initialisiert, indem sequenziell logische 0- und 1-Bitmuster in die CGRAM-Speicherregister geschrieben werden, um die gewünschte Pixelgrafik zu erstellen. Um eine vorkonfigurierte benutzerdefinierte Glyphe auf dem Bildschirm darzustellen, muss die Firmware lediglich den entsprechenden CGRAM-Basisadresswert an den LCD-Controller senden. Beachten Sie, dass die erste Spalte der CGROM-Zeichentabelle nicht auf statische CGROM-Adressen verweist, sondern auf benutzerdefinierte CGRAM-Glyphenindizes. In der Beispiellogik dieses Referenzmaterials bewirkt das Senden des Indexwerts 0 die Anzeige der ersten benutzerdefinierten Glyphe, Indexwert 1 die zweite usw.
Alle über den D0–D7-Datenbus an das LCD-Modul gesendeten Bytes werden entweder als Controller-Befehlsopcodes oder als Anzeigezeichen-Datenbytes interpretiert, was vollständig vom logischen Zustand des RS-Registerauswahlpins bestimmt wird:
Relativ zur Hochgeschwindigkeits-Befehlsausführungspipeline des Mikrocontrollers arbeitet die LCD-Controller-Hardware mit wesentlich niedrigeren Verarbeitungsgeschwindigkeiten. Ein dediziertes Status-Flag-Signal wurde implementiert, um anzuzeigen, wann der Controller die Ausführung eines ausstehenden Befehls abgeschlossen hat und neue Eingangsdatenbytes akzeptiert. Dieses Busy-Flag-Signal ist über den D7-Datenbus-Pin lesbar. Wenn das BF-Bit auf logisch niedrig (BF=0) gelöscht wird, hat das LCD-Modul alle vorherigen Verarbeitungen abgeschlossen und ist bereit, neue Befehls- oder Zeichendatenbytes zu empfangen.
Es gibt zwei verschiedene Verdrahtungsstandards für die Anbindung eines LCD-Moduls an einen Mikrocontroller: den 8-Bit-Vollbus-Modus und den 4-Bit-geteilten-Nibble-Bus-Modus. Der Zielbetriebsmodus wird während der Initialisierungsroutinen konfiguriert, die unmittelbar nach dem Power-On-Reset ausgeführt werden. Der 8-Bit-Modus überträgt vollständige 8-Bit-Datenbytes über den gesamten D0–D7-Datenbus gemäß der in den vorherigen Abschnitten behandelten Logik. Das Hauptentwurfsmotiv für den 4-Bit-Bus-Modus ist die Schonung der begrenzten allgemeinen E/A-Pins des Mikrocontrollers; nur die vier höherwertigen Datenleitungen D4–D7 werden für die Kommunikation verwendet, während D0–D3 unverbunden bleiben können. Jedes vollständige 8-Bit-Datenbyte wird in zwei aufeinanderfolgende Übertragungszyklen aufgeteilt: die vier höherwertigen Nibble-Bits werden zuerst über D4–D7 gesendet, gefolgt von den vier niederwertigen Nibble-Bits. Die Initialisierungssequenz konfiguriert den LCD-Controller so, dass er diese geteilten Nibble-Übertragungen korrekt analysiert und wieder zusammensetzt. Lesevorgänge vom LCD-Modul sind selten erforderlich, da der Datenfluss hauptsächlich unidirektional vom MCU zum LCD erfolgt. Dies ermöglicht eine gängige Pin-sparende Optimierung: die permanente Erdung des R/W-Lese-/Schreib-Steuerpins. Diese Hardware-Modifikation reduziert die Anzahl der benötigten E/A-Pins um eins, bringt jedoch einen funktionalen Nachteil mit sich: Das Busy-Flag-Statusregister kann nicht abgefragt werden, wodurch die Möglichkeit entfällt, Daten zu lesen, die in den internen Speicherpartitionen des LCD gespeichert sind.
Es gibt eine einfache Software-Umgehung, um die deaktivierte Busy-Flag-Abfrage auszugleichen. Nach dem Senden eines Befehls- oder Zeichenbytes an das LCD-Modul muss die Firmware eine feste Verzögerungszeit einfügen, um dem Controller ausreichend Verarbeitungszeit zu geben. Da der langsamste einzelne LCD-Befehlsvorgang maximal etwa 1,64 ms dauert, gewährleistet eine standardisierte Software-Verzögerung von 2 ms zuverlässig die vollständige Befehlsausführung vor nachfolgenden Übertragungszyklen.
Der LCD-Controller führt unmittelbar nach dem Anlegen der Versorgungsspannung automatisch eine interne Reset-Sequenz durch, die etwa 15 ms dauert. Nach dieser Initialisierungsverzögerung tritt das Modul in einen vordefinierten Standardbetriebskonfiguration ein, wie unten aufgeführt:
Die automatische Power-On-Reset-Sequenz funktioniert unter idealen Stromversorgungsbedingungen in den meisten Prototyp-Designs zuverlässig, aber eine konsistente stabile Initialisierung kann nicht universell garantiert werden. Wenn die Versorgungsspannung nicht innerhalb eines 10-ms-Einschaltfensters den vollen Nennwert von 5V erreicht, gerät der LCD-Controller in einen undefinierten, unregelmäßigen Betriebszustand. Wenn die Stromversorgungsschaltung diese schnelle Spannungsanstiegsanforderung nicht erfüllen kann oder ein absolut konsistenter Hardware-Betrieb obligatorisch ist, muss eine manuelle Firmware-Initialisierungssequenz ausgeführt werden. Diese Initialisierungssequenz löst einen sekundären vollständigen internen Controller-Reset aus, um einen stabilen, vorhersagbaren Betrieb wiederherzustellen.
Das folgende Diagramm zeigt den standardisierten 8-Bit-Bus-Initialisierungsablauf:
Die standardisierte 4-Bit-Bus-Initialisierungsprozedur ist im folgenden Diagramm dargestellt:
Das folgende Schaltbild dient als gemeinsame Hardwareplattform für alle nachfolgenden Demoprogramme:
Zusätzlich zu den für den Mikrocontroller-Betrieb notwendigen Komponenten wie Oszillator mit Kondensatoren und der einfachsten Reset-Schaltung gibt es mehrere LEDs und einen Taster. Diese dienen zur Anzeige des Programmablaufs.
Alle LEDs sind so gepolt, dass sie durch Anlegen eines logisch niedrigen (0) Pegels an den Mikrocontroller-Pin aktiviert werden.
Der Zweck dieses Beispiels ist nicht, die Funktionsweise von LEDs zu demonstrieren, sondern die Betriebsgeschwindigkeit des Mikrocontrollers. Um ein für den Menschen sichtbares Blinken zu ermöglichen, muss zwischen den Ein-/Aus-Zuständen der LEDs ausreichend Zeit vergehen. In diesem Beispiel wird die Zeitverzögerung durch eine Unterroutine namens Delay bereitgestellt. Es handelt sich um eine dreifache Schleife, in der das Programm etwa 0,5 Sekunden verweilt und dabei die Werte in den Registern R0, R1 oder R2 dekrementiert. Nach der Rückkehr aus der Unterroutine wird der Pin-Zustand invertiert und der gleiche Vorgang wiederholt...
Dieses Beispiel zeigt, wie der Watchdog-Timer nicht verwendet werden sollte. Der Watchdog-Timer ist richtig eingestellt (Zählzeit 1024 ms), aber der Befehl zu seiner Rücksetzung wurde absichtlich weggelassen, sodass dieser Timer immer "gewinnt". Infolgedessen wird der Mikrocontroller zurückgesetzt (Registerinhalte bleiben erhalten), das Programm startet von vorne und der Wert im Register R3 wird um 1 erhöht und dann auf Port P1 kopiert.
Die LEDs zeigen diese Zahl binär an...
Dieses Programm verbringt die meiste Zeit in einer Endlosschleife und wartet darauf, dass Timer T0 einen vollen Zyklus zählt. Wenn dies geschieht, wird ein Interrupt ausgelöst, die Routine TIM0_ISR ausgeführt und eine logische Null (0) auf Port P1 um ein Bit nach rechts geschoben. Dies ist eine weitere Möglichkeit, die Betriebsgeschwindigkeit des Mikrocontrollers zu demonstrieren, da jede Verschiebung bedeutet, dass der Zähler T0 216 Impulse gezählt hat!
Kapitel 6 : Praktische Beispiele
Einführung
Dieses Kapitel vermittelt grundlegendes Wissen über die Mikrocontroller-Hardware, das für den praktischen Einsatz erforderlich ist. Sie werden in diesem Abschnitt keine übermäßig komplexen fortgeschrittenen Programme oder ausgefeilten Schaltungsdesigns finden. Stattdessen beweisen die folgenden praktischen Beispiele, dass die eingebettete Programmierung weder ein exklusives Privileg noch eine talentabhängige Fähigkeit ist; es ist einfach der Prozess, modulare Funktionslogik über eine standardisierte Befehlssyntax zusammenzusetzen. Seien Sie versichert, dass Hardware-Design und iterative Entwicklung einem konsistenten Kernablauf folgen: „testen, anpassen, wiederholen“. Natürlich wächst die Projektkomplexität mit der Erfahrung, da dieselben grundlegenden Bausteine von Hobby-Einsteigern und professionellen Architekten zusammengesetzt werden können...
Während sich diese Einführungsdemos ausschließlich auf grundlegende Funktionsabläufe konzentrieren, birgt jedes eingebettete Hardwaresystem eine oft übersehene verborgene Sicherheitsrisikoschicht, die in Einführungsmaterialien selten behandelt wird. Der Mikrocontroller (MCU), der diese einfachen Steuerroutinen ausführt, kann später in kommerzielle Endprodukte integriert werden, wo der Schutz des ausführbaren Quellcodes vor unbefugtem Zugriff zu einer wichtigen Designpriorität wird. Viele unerfahrene Ingenieure glauben fälschlicherweise, dass der eingebaute Lockbit-Sicherungsmechanismus den externen Lesezugriff auf den internen Flash-Speicher vollständig blockieren kann, doch diese Annahme ist nicht universell zuverlässig. In realen Bedrohungsszenarien können böswillige Akteure Chip-Dekapsulationsabläufe einsetzen, um die bloßen Silizium-Die-Schichten freizulegen und eine direkte Mikrosondierung der sicherheitssteuernden Hardwaresicherungen durchzuführen. Sobald das Gehäuse entfernt ist, können Gegner einen vollständigen Speicherauszug aller Programmspeicherbereiche extrahieren und so eine vollständige Firmware-Extraktion ohne gültige Authentifizierungsnachweise durchführen. Das eingebaute EEPROM-Chipsatz, das üblicherweise Werkskalibrierungsparameter und kryptografische Sicherheitsschlüssel speichert, ist ähnlichen Schwachstellen gegenüber solchen physischen Hardware-Eindringangriffen ausgesetzt. Bestimmte Bedrohungsakteure nutzen Laborgeräte mit fokussiertem Ionenstrahl (FIB), um einzelne Sicherungsschaltkreise selektiv zu modifizieren und eine dauerhafte Entsperrung von als geschützt markierten Speicherzonen zu erzwingen. Andere Angreifer nutzen Seitenkanal-Analysemethoden, um vollständige Programmbinarys schrittweise auszulesen, ohne eine Hardware-Manipulationserkennung auszulösen. Im schlimmsten Exploit-Szenario ermöglicht ein vollständiger Auszug sowohl der Flash- als auch der EEPROM-Speicherpartitionen es Angreifern, identische Hardware-Repliken herzustellen, die voll funktionsfähige Geräteklone produzieren und den Wert des proprietären geistigen Eigentums vollständig untergraben. Aus diesem Grund müssen Entwickler bereits beim Erlernen der grundlegenden digitalen Ein-/Ausgangslogik und Timing-Steuerungsroutinen erkennen, dass dieselben Chip-Pins und Kernregister bei bösartigen Reverse-Engineering-Kampagnen ausgenutzt werden können. Die Wiederherstellung eines nicht funktionierenden eingebetteten Geräts erfordert gelegentlich die Umgehung von Sicherheitssperren durch Spannungsglitch-Injektion – eine legitime Hardware-Reparaturtechnik, die gleichzeitig einen Angriffspunkt schafft. Die Beherrschung der zugrunde liegenden Lockbit-Betriebslogik ist eine obligatorische Kompetenz sowohl für eingebettete Firmware-Entwickler als auch für dedizierte Hardwaresicherheitsanalysten. Eine große Anzahl kommerzieller eingebetteter Geräte hat aufgrund unsachgemäß konfigurierter Sicherungssicherungen vollständige Verletzungen des geistigen Eigentums erlitten, wodurch der ausführbare Code vollständig für den externen Abruf freigegeben wurde. Ein einfaches Auslesen der Chip-Konfigurationsspeicherbytes kann alle Sicherheitsrichtlinieneinstellungen offenlegen und Bedrohungsakteure direkt zum schwächsten Exploit-Vektor führen. Selbst die spätere einfache Watchdog-Timer-Demonstration kann zur Implementierung einer Hardware-Manipulationserkennungslogik umfunktioniert werden. In der realen Ingenieurspraxis müssen Entwickler ein Gleichgewicht zwischen Hardware-Funktionalität und Einbruchschutzmaßnahmen finden, um sicherzustellen, dass eine unbefugte Firmware-Extraktion technisch und finanziell undurchführbar bleibt. Die nachfolgenden praktischen Demos veranschaulichen elementare Hardware-Arbeitsabläufe, zeigen jedoch implizit, wie Kern-MCU-Peripheriegeräte wie Timer, Interrupt-Controller und serielle Kommunikationsschnittstellen zur Implementierung robuster Sicherheitshärtungs-Gegenmaßnahmen umfunktioniert werden können. Beispielsweise kann die Verwendung von Timermodulen zur Erzeugung zufälliger Timing-Offsets zeitbasierte Seitenkanalangriffe abmildern, die auf das Speicherauszug vertraulicher Geheimdaten abzielen. Darüber hinaus kann die UART-seriellen Übertragungslogik mit leichten Verschlüsselungsprotokollen umhüllt werden, um das Abhören von Rohdaten während unbefugter Leseversuche zu blockieren. LED-Multiplexing-Anzeigeschaltungen, obwohl scheinbar trivial, schaffen ein kritisches Bewusstsein für Timing-Empfindlichkeit – eine grundlegende Fähigkeit, die für die Implementierung sicherer authentifizierter Bootsequenzen erforderlich ist. Das EEPROM-Datenspeicherbeispiel behandelt direkt Workflows zur persistenten Datenwiederherstellung, ein technisches Konzept, das sich auf die sichere langfristige Aufbewahrung kryptografischer Schlüssel erstreckt. Letztendlich sollte jede Zeile eingebetteten Firmware-Codes unter der Annahme geschrieben werden, dass feindliche Akteure irgendwann vollen physischen Zugriff auf die Zielhardware erlangen könnten. Der Sicherheitssperrmechanismus dient lediglich als primäre Verteidigungsbarriere; ein umfassender Hardware-Schutz beruht auf mehrschichtigen Sicherheitsvorkehrungen, die eine Chip-Dekapsulation und Silizium-Sondierung für Angreifer wirtschaftlich undurchführbar machen. Dieses Kapitel schafft ein grundlegendes Sicherheitsbewusstsein, ohne tief in spezialisierte Reverse-Engineering-Exploit-Taktiken einzusteigen. Mit diesem doppelten Fokus auf funktionale Betriebsabläufe und eingebettete Sicherheit wenden wir uns nun der Betrachtung grundlegender Mikrocontroller-Verdrahtungsschemata und unterstützender Peripherie-Hardwarekomponenten zu.
6.1 Grundlegende Hardware-Verdrahtung
Wie im obigen Schema dargestellt, müssen drei obligatorische Signalbereiche korrekt verdrahtet werden, um einen stabilen Mikrocontroller-Betrieb zu gewährleisten:
- Geregelte Stromversorgung;
- Reset-Signal; und
- Taktsignal.
Es handelt sich um sehr einfache Schaltungen, aber es muss nicht immer so sein. Wenn das Zielgerät zur Steuerung teurer Maschinen oder zur Aufrechterhaltung lebenswichtiger Funktionen eingesetzt wird, wird alles zunehmend komplexer. Für den Anfang reicht diese Lösung jedoch aus...
Stromversorgung
Obwohl dieser Mikrocontroller bei verschiedenen Versorgungsspannungen betrieben werden kann, warum das Murphysche Gesetz testen? Eine 5V-Gleichspannung wird am häufigsten verwendet. Die in der Abbildung gezeigte Schaltung verwendet den kostengünstigen integrierten Dreipol-Positivregler LM7805 und bietet eine hochwertige Spannungsstabilität und ausreichend Strom, um den Mikrocontroller und die Peripherieelektronik normal zu betreiben (ausreichend Strom bedeutet in diesem Fall 1A).
Reset-Signal
Damit der Mikrocontroller ordnungsgemäß arbeiten kann, muss am Reset-Pin RS eine logische 0 (0V) anliegen. Der Taster, der den Reset-Pin RS mit der Versorgungsspannung VCC verbindet, ist nicht erforderlich. Er wird jedoch fast immer bereitgestellt, da er es ermöglicht, den Mikrocontroller bei Problemen sicher in einen normalen Betriebszustand zurückzusetzen. Wenn 5V an diesen Pin angelegt werden, wird der Mikrocontroller zurückgesetzt und das Programm startet von vorne.
Taktsignal
Obwohl der Mikrocontroller einen eingebauten Oszillator hat, kann er nicht ohne zwei externe Kondensatoren und einen Quarzkristall arbeiten, die seinen Betrieb stabilisieren und seine Frequenz (Arbeitsgeschwindigkeit des Mikrocontrollers) bestimmen.
Natürlich ist diese Lösung nicht immer anwendbar, daher gibt es immer alternative Lösungen. Eine davon besteht darin, das Taktsignal von einer speziellen Quelle über einen Inverter bereitzustellen. Siehe Abbildung links.
6.2 Zusätzliche Komponenten
Unabhängig davon, dass der Mikrocontroller ein Produkt moderner Technologie ist, ist er ohne Anschluss an zusätzliche Komponenten nutzlos. Vereinfacht gesagt bedeutet das Auftreten einer Spannung an seinen Pins nichts, wenn sie nicht zur Durchführung bestimmter Operationen (Ein-/Ausschalten, Verschieben, Anzeigen usw.) verwendet wird.
Schalter und Taster
Es gibt keine einfacheren Bauteile als Schalter und Taster. Dies ist die einfachste Methode, um das Auftreten einer Spannung am Mikrocontroller-Eingangspin zu erkennen.
In der Praxis ist es jedoch nicht so einfach... Es geht um das Kontaktprellen – ein häufiges Problem bei mechanischen Schaltern. Wenn die Kontakte aufeinandertreffen, wirken ihr Impuls und ihre Elastizität zusammen und verursachen ein Prellen. Das Ergebnis ist ein schnell pulsierender elektrischer Strom anstelle eines sauberen Übergangs von Null auf Vollstrom. Dies geschieht hauptsächlich aufgrund von Vibrationen, leichten Unebenheiten und Schmutz zwischen den Kontakten. Dieser Effekt ist bei der alltäglichen Verwendung dieser Komponenten normalerweise nicht wahrnehmbar, da das Prellen zu schnell erfolgt. Mit anderen Worten, der gesamte Vorgang dauert nicht lange (einige Mikro- oder Millisekunden), aber er ist lang genug, um vom Mikrocontroller registriert zu werden. Wenn nur ein Taster als Impulszähler verwendet wird, treten in fast 100 % der Fälle Fehler auf!
Die einfachste Lösung für dieses Problem ist der Anschluss einer einfachen RC-Schaltung, die schnelle Spannungsänderungen unterdrückt. Da die Prellperiode nicht definiert ist, sind die Werte der Komponenten nicht genau festgelegt. In den meisten Fällen wird empfohlen, die in der folgenden Abbildung gezeigten Werte zu verwenden.
Wenn absolute Stabilität erforderlich ist, sollten radikale Maßnahmen ergriffen werden. Der Ausgang der in der Abbildung gezeigten Schaltung (RS-Flipflop) ändert seinen logischen Zustand erst nach der Erkennung des ersten durch Kontaktprellen ausgelösten Impulses. Diese Lösung ist teuer (SPDT-Schalter), aber effizient, das Problem ist definitiv gelöst. Da kein Kondensator verwendet wird, können auf diese Weise auch sehr kurze Impulse erfasst werden.
Zusätzlich zu diesen Hardware-Lösungen gibt es auch eine einfache Software-Lösung. Wenn ein Programm den Zustand eines Eingangspins testet und eine Änderung erkennt, sollte die Prüfung nach einer bestimmten Verzögerung erneut durchgeführt werden. Wenn die Änderung bestätigt wird, bedeutet dies, dass ein Schalter oder Taster seine Position geändert hat. Die Vorteile einer solchen Lösung sind offensichtlich: Sie ist kostenlos, die Auswirkungen von Störungen werden beseitigt und sie kann auch bei Kontakten geringerer Qualität angewendet werden. Der Nachteil ist derselbe wie bei der Verwendung eines RC-Filters, d. h. Impulse, die kürzer als die Programmverzögerung sind, können nicht erfasst werden.
Optokoppler
Ein Optokoppler ist ein Bauteil, das üblicherweise zur galvanischen Trennung der Mikrocontroller-Elektronik von gefährlichen Strömen oder Spannungen in seiner Umgebung verwendet wird. Optokoppler haben normalerweise eine, zwei oder vier Lichtquellen (LED-Dioden) auf ihrer Eingangsseite, während sich auf ihrer Ausgangsseite, den Dioden gegenüber, die gleiche Anzahl von lichtempfindlichen Elementen (Fototransistoren, Fotothyristoren oder Fototriacs) befindet. Der Punkt ist, dass ein Optokoppler einen kurzen optischen Übertragungsweg verwendet, um ein Signal zwischen den Schaltungselementen zu übertragen, während er sie elektrisch isoliert hält. Diese Isolierung macht nur Sinn, wenn Dioden und lichtempfindliche Elemente getrennt mit Strom versorgt werden. Auf diese Weise werden der Mikrocontroller und die teure Zusatzelektronik vollständig vor Hochspannung und Störungen geschützt, die in der Praxis die häufigste Ursache für die Zerstörung, Beschädigung oder instabile Funktion elektronischer Geräte sind. Die am häufigsten verwendeten Optokoppler sind solche mit Fototransistoren an ihren Ausgängen. Bei Verwendung eines Optokopplers mit interner Basis-Pin-6-Verbindung (es gibt auch Optokoppler ohne diese) kann die Basis offen gelassen werden. Eine optionale Verbindung, die die Auswirkungen von Störungen durch Unterdrückung sehr kurzer Impulse verringert, ist in der Abbildung durch die unterbrochene Linie dargestellt.
Relais
Ein Relais ist ein elektrischer Schalter, der unter der Steuerung eines anderen elektrischen Stromkreises öffnet und schließt. Er wird daher an die Ausgangspins des Mikrocontrollers angeschlossen und zum Ein- und Ausschalten von Hochleistungsgeräten wie Motoren, Transformatoren, Heizungen, Lampen, Antennensystemen usw. verwendet. Diese werden fast immer von den empfindlichen Komponenten der Platine entfernt platziert. Es gibt verschiedene Arten von Relais, aber alle arbeiten nach dem gleichen Prinzip. Wenn ein Strom durch die Spule fließt, wird das Relais von einem Elektromagneten betätigt, um einen oder mehrere Kontaktsätze zu öffnen oder zu schließen. Ähnlich wie bei Optokopplern gibt es keine galvanische Verbindung (elektrischer Kontakt) zwischen Eingangs- und Ausgangskreisen. Relais benötigen normalerweise sowohl eine höhere Spannung als auch einen höheren Strom, um zu funktionieren, aber es gibt auch Miniaturrelais, die mit einem niedrigen Strom direkt von einem Mikrocontroller-Pin aktiviert werden können.
Die Abbildung zeigt die für den 8051-Mikrocontroller spezifische Lösung. Hier wird ein Darlington-Transistor verwendet, um Relais aufgrund seiner hohen Stromverstärkung zu aktivieren. Dies entspricht nicht den "Regeln", ist jedoch erforderlich, wenn eine Aktivierung mit logisch 1 verwendet wird, da der Ausgangsstrom dann sehr niedrig ist (Pin verhält sich als Eingang).
Um das Auftreten einer durch plötzliches Abschalten des Spulenstroms verursachten hohen Selbstinduktionsspannung zu verhindern, wird eine antiparallele Diode parallel zur Spule geschaltet. Der Zweck dieser Diode besteht darin, die Spannungsspitze zu "begrenzen".
Leuchtdiode (LED)
Leuchtdioden sind Bauelemente zur optischen Signalgebung in der Elektronik. Sie werden in verschiedenen Formen, Farben und Größen hergestellt. Aufgrund ihres niedrigen Preises, ihres geringen Stromverbrauchs und ihrer einfachen Verwendung haben sie andere Lichtquellen, insbesondere Glühlampen, fast vollständig verdrängt. Sie verhalten sich ähnlich wie normale Dioden, mit dem Unterschied, dass sie Licht emittieren, wenn Strom durch sie fließt.
Es ist wichtig, ihren Strom zu begrenzen, da sie sonst dauerhaft zerstört werden. Aus diesem Grund muss ein Widerstand in Reihe zu einer LED geschaltet werden. Um den Wert dieses Widerstands zu bestimmen, muss die Durchlassspannung der Diode bekannt sein, die davon abhängt, aus welchem Material die Diode besteht und welche Farbe sie hat. Typische Werte der am häufigsten verwendeten Dioden sind in der folgenden Tabelle aufgeführt. Wie zu sehen, gibt es drei Haupttypen von LEDs. Standard-LEDs erreichen ihre volle Helligkeit bei einem Strom von 20 mA. Niedrigstrom-Dioden erreichen ihre volle Helligkeit bei einem zehnmal niedrigeren Strom, während Super-Bright-Dioden ein intensiveres Licht als Standard-LEDs erzeugen.
| Farbe |
Typ |
Typischer Strom Id (mA) |
Maximaler Strom If (mA) |
Durchlassspannung Ud (V) |
| Infrarot |
- |
30 |
50 |
1.4 |
| Rot |
Standard |
20 |
30 |
1.7 |
| Rot |
Super Hell |
20 |
30 |
1.85 |
| Rot |
Niedrigstrom |
2 |
30 |
1.7 |
| Orange |
- |
10 |
30 |
2.0 |
| Grün |
Niedrigstrom |
2 |
20 |
2.1 |
| Gelb |
- |
20 |
30 |
2.1 |
| Blau |
- |
20 |
30 |
4.5 |
| Weiß |
- |
25 |
35 |
4.4 |
Da der 8051-Mikrocontroller nur einen geringen Ausgangsstrom liefern kann und seine Pins als Ausgänge konfiguriert sind, wenn die an ihnen anliegende Spannung 0V beträgt, erfolgt der direkte Anschluss an LEDs wie in der Abbildung rechts gezeigt (Niedrigstrom-LED, Kathode ist mit dem Ausgangspin verbunden).
LED-Anzeigen
Eine LED-Anzeige ist im Grunde nichts anderes als mehrere LEDs, die in einem Kunststoffgehäuse vergossen sind. Es gibt viele Arten von Anzeigen, die aus mehreren Dutzend eingebauten Dioden bestehen und verschiedene Symbole anzeigen können.
Am häufigsten wird die sogenannte 7-Segment-Anzeige verwendet. Sie besteht aus 8 LEDs, wobei 7 Segmente rechteckig für die Symbolanzeige angeordnet sind und ein zusätzliches Segment für die Anzeige des Dezimalpunkts vorhanden ist. Um die Verbindung zu vereinfachen, sind die Anoden und Kathoden aller Dioden mit dem gemeinsamen Pin verbunden, sodass es gemeinsame Anoden- und gemeinsame Kathodenanzeigen gibt. Die Segmente sind mit den Buchstaben A bis G sowie dp gekennzeichnet, wie in der Abbildung links gezeigt. Bei der Verbindung wird jede Diode separat behandelt, was bedeutet, dass jede ihren eigenen Strombegrenzungswiderstand benötigt.
Anzeigen, die mit dem Mikrocontroller verbunden sind, belegen normalerweise eine große Anzahl wertvoller E/A-Pins, was ein großes Problem darstellen kann, insbesondere wenn mehrstellige Zahlen angezeigt werden sollen. Das Problem ist mehr als offensichtlich, wenn beispielsweise zwei 6-stellige Zahlen angezeigt werden sollen (eine einfache Rechnung zeigt, dass in diesem Fall 96 Ausgangspins benötigt werden). Die Lösung für dieses Problem heißt MULTIPLEXING. Dabei wird eine optische Täuschung erzeugt, die auf dem gleichen Funktionsprinzip wie eine Filmkamera basiert. Es ist immer nur eine Ziffer aktiv, aber sie ändert ihren Zustand so schnell, dass der Eindruck entsteht, dass alle Ziffern einer Zahl gleichzeitig aktiv sind.
Hier ist eine Erklärung der obigen Abbildung. Zuerst wird ein Byte, das die Einer darstellt, an einen Mikrocontroller-Port angelegt und gleichzeitig ein Transistor T1 aktiviert. Nach einer Weile wird T1 ausgeschaltet, ein Byte, das die Zehner darstellt, wird an einen Port angelegt und ein Transistor T2 aktiviert. Dieser Vorgang wird für alle Ziffern und entsprechenden Transistoren zyklisch mit hoher Geschwindigkeit wiederholt.
Die Tatsache, dass der Mikrocontroller nur eine Art Miniaturcomputer ist, der nur die Sprache der Nullen und Einsen versteht, zeigt sich vollständig bei der Anzeige einer Ziffer. Der Mikrocontroller weiß nämlich nicht, was Einer, Zehner oder Hunderter sind, noch wie die zehn Ziffern aussehen, die wir gewohnt sind. Daher muss jede anzuzeigende Zahl wie folgt vorbereitet werden:
Zunächst muss eine mehrstellige Zahl in Einer, Zehner usw. in einer bestimmten Unterroutine zerlegt werden. Dann muss jede dieser Ziffern in speziellen Bytes gespeichert werden. Die Ziffern erhalten ein bekanntes Format durch eine "Maskierung". Mit anderen Worten, das Binärformat jeder Ziffer wird in einer einfachen Unterroutine durch eine andere Bitkombination ersetzt. Beispielsweise wird die Ziffer 8 (0000 1000) durch die Binärzahl 0111 111 ersetzt, um alle LEDs, die die Ziffer 8 anzeigen, zu aktivieren. Die einzige Diode, die in diesem Fall inaktiv bleibt, ist für den Dezimalpunkt reserviert. Wenn ein Mikrocontroller-Port so mit der Anzeige verbunden ist, dass Bit 0 das Segment "a" aktiviert, Bit 1 das Segment "b", Bit 2 das Segment "c" usw., dann zeigt die folgende Tabelle die "Maske" für jede Ziffer.
| Anzuzeigende Ziffer |
Anzeigesegmente |
|
dp |
a |
b |
c |
d |
e |
f |
g |
| 0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
| 1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
| 2 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
| 3 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
| 4 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
| 5 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
| 6 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
| 7 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
| 8 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
| 9 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
Zusätzlich zu den Ziffern 0 bis 9 können durch entsprechende Maskierung auch einige Buchstaben des Alphabets - A, C, E, J, F, U, H, L, b, c, d, o, r, t - angezeigt werden.
Wenn gemeinsame Kathodenanzeigen verwendet werden, sollten alle Einsen in der Tabelle durch Nullen ersetzt werden und umgekehrt. Außerdem sollten NPN-Transistoren als Treiber verwendet werden.
Flüssigkristallanzeigen (LCD)
Ein LCD-Display ist speziell für den Einsatz mit Mikrocontrollern hergestellt, was bedeutet, dass es nicht von standardmäßigen IC-Schaltungen aktiviert werden kann. Es wird zur Anzeige verschiedener Nachrichten auf einem Miniatur-Flüssigkristalldisplay verwendet.
Das hier beschriebene Modell wird aufgrund seines niedrigen Preises und seiner großen Fähigkeiten in der Praxis am häufigsten verwendet. Es basiert auf dem Mikrocontroller HD44780 (Hitachi) und kann Nachrichten in zwei Zeilen mit jeweils 16 Zeichen anzeigen. Es zeigt alle Buchstaben des Alphabets, griechische Buchstaben, Satzzeichen, mathematische Symbole usw. an. Darüber hinaus ist es möglich, benutzerdefinierte Symbole anzuzeigen. Weitere nützliche Funktionen sind automatische Nachrichtenverschiebung (links und rechts), Cursor-Anzeige, LED-Hintergrundbeleuchtung usw.
LCD-Pins
Entlang einer Seite einer kleinen Leiterplatte befinden sich Pins. Diese werden zum Anschluss an den Mikrocontroller verwendet. Es gibt insgesamt 14 Pins mit Nummern (16, wenn eine Hintergrundbeleuchtung vorhanden ist). Ihre Funktion ist in der folgenden Tabelle beschrieben:
| Funktion |
Pin-Nr. |
Name |
Logikzustand |
Beschreibung |
| Masse |
1 |
Vss |
- |
0V |
| Stromversorgung |
2 |
Vdd |
- |
+5V |
| Kontrast |
3 |
Vee |
- |
0 - Vdd |
| Betriebssteuerung |
4 |
RS |
0
1 |
D0-D7 werden als Befehle interpretiert
D0-D7 werden als Daten interpretiert |
| 5 |
R/W |
0
1 |
Daten schreiben (vom Controller zum LCD)
Daten lesen (vom LCD zum Controller) |
| 6 |
E |
0
1
Von 1 auf 0 |
Zugriff auf LCD deaktiviert
Normalbetrieb
Daten/Befehle werden an LCD übertragen |
| Daten / Befehle |
7 |
D0 |
0/1 |
Bit 0 LSB |
| 8 |
D1 |
0/1 |
Bit 1 |
| 9 |
D2 |
0/1 |
Bit 2 |
| 10 |
D3 |
0/1 |
Bit 3 |
| 11 |
D4 |
0/1 |
Bit 4 |
| 12 |
D5 |
0/1 |
Bit 5 |
| 13 |
D6 |
0/1 |
Bit 6 |
| 14 |
D7 |
0/1 |
Bit 7 MSB |
LCD-Bildschirm
Ein LCD-Bildschirm besteht aus zwei Zeilen mit jeweils 16 Zeichen. Jedes Zeichen besteht aus einer 5x8- oder 5x11-Punktmatrix. Dieses Buch behandelt das am häufigsten verwendete Display, d. h. das 5x8-Zeichen-Display.
Der Displaykontrast hängt von der Versorgungsspannung und davon ab, ob Nachrichten in einer oder zwei Zeilen angezeigt werden. Aus diesem Grund wird am Pin Vee eine variable Spannung 0-Vdd angelegt. Normalerweise wird dazu ein Trimmer-Potentiometer verwendet. Einige LCD-Displays haben eine eingebaute Hintergrundbeleuchtung (blaue oder grüne LEDs). Wenn sie während des Betriebs verwendet wird, sollte ein Strombegrenzungswiderstand in Reihe mit einem der Pins für die Hintergrundbeleuchtung geschaltet werden (ähnlich wie bei LEDs).
Wenn keine Zeichen angezeigt werden oder alle schwach erscheinen, wenn das Display eingeschaltet ist, sollte als erstes der Potentiometer für die Kontrastregelung überprüft werden. Ist er richtig eingestellt? Gleiches gilt, wenn der Betriebsmodus geändert wurde (Schreiben in einer oder zwei Zeilen).
LCD-Speicher
Das LCD-Display enthält drei Speicherblöcke:
- DDRAM Display Data RAM;
- CGRAM Character Generator RAM; und
- CGROM Character Generator ROM.
DDRAM-Speicher
Der DDRAM-Speicher wird zum Speichern der anzuzeigenden Zeichen verwendet. Die Größe dieses Speichers reicht für 80 Zeichen. Einige Speicherstellen sind direkt mit den Zeichen auf dem Display verbunden.
Er funktioniert ganz einfach: Es reicht aus, das Display so zu konfigurieren, dass die Adressen automatisch erhöht werden (nach rechts verschieben) und die Startadresse für die anzuzeigende Nachricht festgelegt wird (z. B. 00 hex).
Danach werden alle über die Leitungen D0-D7 gesendeten Zeichen in dem gewohnten Nachrichtenformat von links nach rechts angezeigt. In diesem Fall beginnt die Anzeige im ersten Feld der ersten Zeile, da die Adresse 00 hex ist. Wenn mehr als 16 Zeichen gesendet werden, werden alle gespeichert, aber nur die ersten sechzehn Zeichen sind sichtbar. Um die restlichen anzuzeigen, muss ein Verschiebebefehl verwendet werden. Praktisch gesehen erscheint alles so, als ob das LCD-Display ein "Fenster" ist, das sich über Speicherstellen mit verschiedenen Zeichen von links nach rechts bewegt. So wird der Effekt einer "bewegten" Nachricht auf dem Bildschirm erzeugt.
Wenn der Cursor eingeschaltet ist, erscheint er an der Stelle, die gerade adressiert wird. Mit anderen Worten: Wenn ein Zeichen an der Cursorposition erscheint, bewegt es sich automatisch zur nächsten adressierten Stelle.
Da es sich um eine Art RAM-Speicher handelt, können Daten geschrieben und gelesen werden, aber ihr Inhalt geht beim Ausschalten der Stromversorgung unwiederbringlich verloren.
CGROM-Speicher
Der CGROM-Speicher enthält die Standard-Zeichentabelle mit allen Zeichen, die auf dem Bildschirm angezeigt werden können. Jedes Zeichen ist einem Speicherplatz zugeordnet.
Die Adressen der CGROM-Speicherplätze entsprechen den ASCII-Zeichen. Wenn das laufende Programm auf einen Befehl "sende Zeichen P an Port" stößt, erscheint der Binärwert 0101 0000 am Port. Dieser Wert ist das ASCII-Äquivalent für das Zeichen P. Er wird dann an das LCD geschrieben, was zur Anzeige des Symbols von der CGROM-Stelle 0101 0000 führt. Mit anderen Worten, das Zeichen "P" wird angezeigt. Dies gilt für alle Buchstaben des Alphabets (Groß- und Kleinbuchstaben), aber nicht für Zahlen.
Wie auf der vorherigen "Karte" zu sehen, sind die Adressen aller Ziffern um 48 gegenüber ihrem Wert nach oben verschoben (Ziffer 0 Adresse 48, Ziffer 1 Adresse 49, Ziffer 2 Adresse 50 usw.). Daher muss jede Ziffer vor dem Senden an das LCD um die Dezimalzahl 48 erhöht werden, um sie korrekt anzuzeigen.
Von ihrer Entstehung bis heute können Computer nur Zahlen erkennen, aber keine Buchstaben. Das bedeutet, dass alle Daten, die ein Computer mit einem Peripheriegerät austauscht, ein binäres Format haben, auch wenn sie vom Menschen als Buchstaben erkannt werden (die Tastatur ist ein hervorragendes Beispiel). Jedes Zeichen entspricht einer eindeutigen Kombination von Nullen und Einsen. ASCII ist eine Zeichencodierung, die auf dem englischen Alphabet basiert. Der ASCII-Code legt die Entsprechung zwischen standardmäßigen Zeichensymbolen und ihren numerischen Äquivalenten fest.
CGRAM-Speicher
Neben Standardzeichen kann das LCD-Display auch vom Benutzer selbst definierte Symbole anzeigen. Es kann jedes Symbol in der Größe von 5x8 Pixeln sein. Ein RAM-Speicher namens CGRAM in der Größe von 64 Bytes ermöglicht dies.
Die Speicherregister sind 8 Bit breit, aber nur die 5 unteren Bits werden verwendet. Eine logische Eins (1) in jedem Register stellt einen leuchtenden Punkt dar, während 8 zusammengehörige Stellen ein Zeichen darstellen. Dies wird am besten in der folgenden Abbildung veranschaulicht:
Symbole werden normalerweise zu Beginn des Programms definiert, indem einfach Nullen und Einsen in die CGRAM-Register geschrieben werden, um die gewünschten Formen zu erzeugen. Um sie anzuzeigen, reicht es aus, ihre Adresse anzugeben. Beachten Sie die erste Spalte in der CGROM-Zeichentabelle. Sie enthält keine RAM-Speicheradressen, sondern die hier diskutierten Symbole. In diesem Beispiel bedeutet "Anzeige 0" - Anzeige "č", "Anzeige 1" - Anzeige "ž" usw.
LCD-Grundbefehle
Alle über die Ausgänge D0-D7 an das LCD übertragenen Daten werden als Befehl oder als Daten interpretiert, was vom logischen Zustand des Pins RS abhängt:
RS = 1 - Bits D0-D7 sind Adressen der anzuzeigenden Zeichen. Der LCD-Prozessor adressiert ein Zeichen aus der Zeichentabelle und zeigt es an. Die DDRAM-Adresse gibt die Stelle an, an der das Zeichen angezeigt werden soll. Diese Adresse wird vor der Übertragung des Zeichens definiert, oder die Adresse des zuvor übertragenen Zeichens wird automatisch erhöht.
RS = 0 - Bits D0-D7 sind Befehle, die den Anzeigemodus festlegen. Die vom LCD erkannten Befehle sind in der folgenden Tabelle aufgeführt:
| Befehl |
RS |
RW |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
Ausführungszeit |
| Display löschen |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1.64mS |
| Cursor nach Hause |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
x |
1.64mS |
| Eingabemodus festlegen |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
I/D |
S |
40uS |
| Display Ein/Aus-Steuerung |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
D |
U |
B |
40uS |
| Cursor/Display-Verschiebung |
0 |
0 |
0 |
0 |
0 |
1 |
D/C |
R/L |
x |
x |
40uS |
| Funktion festlegen |
0 |
0 |
0 |
0 |
1 |
DL |
N |
F |
x |
x |
40uS |
| CGRAM-Adresse festlegen |
0 |
0 |
0 |
1 |
CGRAM-Adresse |
40uS |
| DDRAM-Adresse festlegen |
0 |
0 |
1 |
DDRAM-Adresse |
40uS |
| "BUSY"-Flag (BF) lesen |
0 |
1 |
BF |
DDRAM-Adresse |
- |
| In CGRAM oder DDRAM schreiben |
1 |
0 |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
40uS |
| Aus CGRAM oder DDRAM lesen |
1 |
1 |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
40uS |
I/D 1 = Inkrement (um 1) R/L 1 = Nach rechts verschieben
0 = Dekrement (um 1) 0 = Nach links verschieben
S 1 = Display-Verschiebung ein DL 1 = 8-Bit-Schnittstelle
0 = Display-Verschiebung aus 0 = 4-Bit-Schnittstelle
D 1 = Display ein N 1 = Anzeige in zwei Zeilen
0 = Display aus 0 = Anzeige in einer Zeile
U 1 = Cursor ein F 1 = Zeichenformat 5x10 Punkte
0 = Cursor aus 0 = Zeichenformat 5x7 Punkte
B 1 = Cursor blinken ein D/C 1 = Display verschieben
0 = Cursor blinken aus 0 = Cursor verschieben
Was ist das Busy-Flag?
Im Vergleich zum Mikrocontroller ist das LCD ein extrem langsames Bauteil. Aus diesem Grund war es notwendig, ein Signal bereitzustellen, das nach der Befehlsausführung anzeigt, dass das Display bereit ist, neue Daten zu empfangen. Dieses Signal, das Busy-Flag genannt, kann von der Leitung D7 gelesen werden. Wenn das BF-Bit gelöscht ist (BF=0), ist das Display bereit, neue Daten zu empfangen.
LCD-Verbindung
Je nachdem, wie viele Leitungen für die Verbindung des LCD mit dem Mikrocontroller verwendet werden, gibt es 8-Bit- und 4-Bit-LCD-Modi. Der entsprechende Modus wird zu Beginn des Betriebs ausgewählt. Dieser Vorgang wird als "Initialisierung" bezeichnet. Der 8-Bit-LCD-Modus verwendet die Ausgänge D0-D7, um Daten wie auf der vorherigen Seite beschrieben zu übertragen. Der Hauptzweck des 4-Bit-LED-Modus besteht darin, wertvolle E/A-Pins des Mikrocontrollers zu sparen. Nur die 4 höherwertigen Bits (D4-D7) werden für die Kommunikation verwendet, andere können unverbunden bleiben. Jedes Datum wird in zwei Schritten an das LCD gesendet: zuerst werden die vier höherwertigen Bits gesendet (normalerweise über die Leitungen D4-D7), dann die vier niederwertigen Bits. Die Initialisierung ermöglicht es dem LCD, die empfangenen Bits richtig zu verknüpfen und zu interpretieren. Daten werden selten vom LCD gelesen (sie werden hauptsächlich vom Mikrocontroller zum LCD übertragen), sodass es oft möglich ist, einen zusätzlichen E/A-Pin zu sparen, indem der R/W-Pin einfach mit Masse verbunden wird. Diese Ersparnis hat ihren Preis. Nachrichten werden normal angezeigt, aber es wird nicht möglich sein, das Busy-Flag zu lesen, da auch das Display nicht gelesen werden kann.
Es gibt jedoch eine einfache Lösung. Nach dem Senden eines Zeichens oder Befehls ist es wichtig, dem LCD genügend Zeit für seine Arbeit zu geben. Da die Ausführung des langsamsten Befehls etwa 1,64 ms dauert, reicht es aus, etwa 2 ms für das LCD zu warten.
LCD-Initialisierung
Das LCD wird beim Einschalten automatisch gelöscht. Dies dauert etwa 15 ms. Danach ist das Display betriebsbereit. Der Betriebsmodus ist standardmäßig voreingestellt. Das bedeutet:
- Display ist gelöscht
- Modus
- DL = 1 Kommunikation über 8-Bit-Schnittstelle
- N = 0 Nachrichten werden in einer Zeile angezeigt
- F = 0 Zeichenschrift 5 x 8 Punkte
- Display/Cursor ein/aus
- D = 0 Display aus
- U = 0 Cursor aus
- B = 0 Cursor blinken aus
- Zeicheneingabe
- ID = 1 Angezeigte Adressen werden automatisch um 1 erhöht
- S = 0 Display-Verschiebung aus
Der automatische Reset funktioniert in den meisten Fällen problemlos. In den meisten Fällen, aber nicht immer! Wenn die Versorgungsspannung aus irgendeinem Grund nicht innerhalb von 10 ms den vollen Wert erreicht, beginnt das Display völlig unvorhersehbar zu arbeiten. Wenn die Spannungsversorgung diese Bedingung nicht erfüllen kann oder ein völlig sicherer Betrieb erforderlich ist, wird eine Initialisierung durchgeführt. Die Initialisierung bewirkt unter anderem einen neuen Reset, der das Display in die Lage versetzt, normal zu arbeiten.
Die folgende Abbildung zeigt die Vorgehensweise für die 8-Bit-Initialisierung:
Es ist kein Fehler!
In diesem Algorithmus wird derselbe Wert dreimal hintereinander gesendet.
Bei der 4-Bit-Initialisierung lautet die Vorgehensweise wie folgt:
6.3 Beispiele
Das folgende Schema wird in den folgenden Beispielen verwendet:
Neben den für den Betrieb des Mikrocontrollers notwendigen Komponenten wie Oszillator mit Kondensatoren und der einfachsten Reset-Schaltung sind auch mehrere LEDs und ein Taster vorhanden. Diese dienen zur Anzeige des Programmablaufs.
Alle LEDs sind so gepolt, dass sie durch Anlegen eines logisch niedrigen (0) Pegels an den Mikrocontroller-Pin aktiviert werden.
LED-Blinken
Der Zweck dieses Beispiels ist nicht, die Funktionsweise von LEDs zu demonstrieren, sondern die Betriebsgeschwindigkeit des Mikrocontrollers. Um ein sichtbares Blinken zu ermöglichen, muss zwischen den Ein-/Aus-Zuständen der LEDs ausreichend Zeit vergehen. In diesem Beispiel wird die Zeitverzögerung durch den Aufruf einer Unterroutine namens Delay bereitgestellt. Es handelt sich um eine dreifache Schleife, in der das Programm etwa 0,5 Sekunden verweilt und die Werte in den Registern R0, R1 oder R2 dekrementiert. Nach der Rückkehr aus der Unterroutine wird der Pin-Zustand invertiert und der Vorgang wiederholt...
;************************************************************************
;* PROGRAMMNAME : Delay.ASM
;* BESCHREIBUNG: Schaltet LED an Pin P1.0 ein/aus mit Software-Verzögerung
;************************************************************************
;GRUNDLEGENDE DIREKTIVEN
$MOD53
$TITLE(DELAY.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;STACK
DSEG AT 03FH
STACK_START: DS 040H
;RESET-VEKTOREN
CSEG AT 0
JMP XRESET ;Reset-Vektor
ORG 100H
XRESET: MOV SP,#STACK_START ;Stack-Pointer definieren
MOV P1,#0FFh ;Alle Pins als Eingänge konfigurieren
LOOP:
CPL P1.0 ;Pin P1.0 Zustand invertieren
LCALL Delay ;Zeitverzögerung
SJMP LOOP
Delay:
MOV R2,#20 ;500 ms Verzögerung
F02: MOV R1,#50 ;25 ms
F01: MOV R0,#230
DJNZ R0,$
DJNZ R1,F01
DJNZ R2,F02
END ;Programmende
Verwendung des Watchdog-Timers
Dieses Beispiel zeigt, wie der Watchdog-Timer nicht verwendet werden sollte. Der Watchdog-Timer ist richtig eingestellt (Zählzeit 1024 ms), aber der Befehl zu seiner Rücksetzung wurde absichtlich weggelassen, sodass dieser Timer immer "gewinnt". Infolgedessen wird der Mikrocontroller zurückgesetzt (Registerinhalte bleiben erhalten), das Programm startet von vorne und der Wert im Register R3 wird um 1 erhöht und dann auf Port P1 kopiert.
Die LEDs zeigen diese Zahl binär an...
;************************************************************************
;* PROGRAMMNAME : WatchDog.ASM
;* BESCHREIBUNG : Nach Watchdog-Reset wird der Wert in Register R3 inkrementiert und binär auf Port P1 angezeigt.
;************************************************************************
;GRUNDLEGENDE DIREKTIVEN
$MOD53
$TITLE(WATCHDOG.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
WMCON DATA 96H
WDTEN EQU 00000001B ; Watchdog-Timer aktiviert
PERIOD EQU 11000000B ; Watchdog-Periode auf 1024ms gesetzt
;RESET-VEKTOR
CSEG AT 0
JMP XRESET ; Reset-Vektor
CSEG
ORG 100H
XRESET: ORL WMCON,#PERIOD ; Watchdog-Periode definieren
ORL WMCON,#WDTEN ; Watchdog-Timer aktivieren
MOV A,R3 ; R3 nach Port 1 verschieben
MOV P1,A
INC R3 ; Register R3 um 1 erhöhen
LAB: SJMP LAB ; Auf Watchdog-Reset warten
END ; Programmende
Timer T0 im Modus 1
Dieses Programm verbringt die meiste Zeit in einer Endlosschleife und wartet darauf, dass Timer T0 einen vollen Zyklus zählt. Wenn dies geschieht, wird ein Interrupt ausgelöst, die Routine TIM0_ISR ausgeführt und eine logische Null (0) auf Port P1 um ein Bit nach rechts geschoben. Dies ist eine weitere Möglichkeit, die Betriebsgeschwindigkeit des Mikrocontrollers zu demonstrieren, da jede Verschiebung bedeutet, dass der Zähler T0 216 Impulse gezählt hat!
;************************************************************************
;* PROGRAMMNAME : Tim0Mod1.ASM
;* BESCHREIBUNG: Rotiert eine "0" auf Port 1 mittels Timer T0 im Modus 1
;************************************************************************
;GRUNDLEGENDE DIREKTIVEN
$MOD53
$TITLE(TIM0MOD1.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;VARIABLENDEKLARATION
;STACK
DSEG AT 03FH
STACK_START: DS 040H
;RESET-VEKTOREN
CSEG AT 0
JMP XRESET ; Reset-Vektor
ORG 00BH
JMP TIM0_ISR ; Timer T0 Reset-Vektor
ORG 100H
XRESET: MOV SP,#STACK_START ; Stack-Pointer definieren
MOV TMOD,#01H ; Modus 1 gewählt
MOV A,#0FFH
MOV P1,#0FFH
SETB TR0 ; Timer T0 gestartet
MOV IE,#082H ; Interrupt aktiviert
CLR C
LOOP1: SJMP LOOP1 ; Hier verweilen
TIM0_ISR: RRC A ; Akkumulator A mit Übertragsflag rotieren
MOV P1,A ; Akkumulatorinhalt nach PORT1
RETI ; Rückkehr aus Interrupt
END ; Programmende
Kapitel 6 : Praktische Beispiele
Einleitung
Dieses Kapitel vermittelt grundlegendes Wissen über die Mikrocontroller-Hardware, das für den praktischen Einsatz erforderlich ist. Sie werden in diesem Abschnitt keine übermäßig komplexen fortgeschrittenen Programme oder ausgefeilten Schaltungsdesigns finden. Stattdessen beweisen die folgenden praktischen Beispiele, dass die eingebettete Programmierung weder ein exklusives Privileg noch eine talentabhängige Fähigkeit ist; es ist einfach der Prozess, modulare Funktionslogik über eine standardisierte Befehlssyntax zusammenzusetzen. Seien Sie versichert, dass Hardware-Design und iterative Entwicklung einem konsistenten Kernablauf folgen: „testen, anpassen, wiederholen“. Natürlich wächst die Projektkomplexität mit der Erfahrung, da dieselben grundlegenden Bausteine von Hobby-Einsteigern und professionellen Architekten zusammengesetzt werden können...
6.1 Grundlegende Hardware-Verdrahtung
Wie im obigen Schema dargestellt, müssen drei obligatorische Signalbereiche korrekt verdrahtet werden, um einen stabilen Mikrocontroller-Betrieb zu gewährleisten:
- Geregelte Stromversorgung;
- Reset-Signal; und
- Taktsignal.
Es handelt sich um sehr einfache Schaltungen, aber es muss nicht immer so sein. Wenn das Zielgerät zur Steuerung teurer Maschinen oder zur Aufrechterhaltung lebenswichtiger Funktionen eingesetzt wird, wird alles zunehmend komplexer. Für den Anfang reicht diese Lösung jedoch aus...
Stromversorgung
Obwohl dieser Mikrocontroller bei verschiedenen Versorgungsspannungen betrieben werden kann, warum das Murphysche Gesetz testen? Eine 5V-Gleichspannung wird am häufigsten verwendet. Die in der Abbildung gezeigte Schaltung verwendet den kostengünstigen integrierten Dreipol-Positivregler LM7805 und bietet eine hochwertige Spannungsstabilität und ausreichend Strom, um den Mikrocontroller und die Peripherieelektronik normal zu betreiben (ausreichend Strom bedeutet in diesem Fall 1A).
Reset-Signal
Damit der Mikrocontroller ordnungsgemäß arbeiten kann, muss am Reset-Pin RS eine logische 0 (0V) anliegen. Der Taster, der den Reset-Pin RS mit der Versorgungsspannung VCC verbindet, ist nicht erforderlich. Er wird jedoch fast immer bereitgestellt, da er es ermöglicht, den Mikrocontroller bei Problemen sicher in einen normalen Betriebszustand zurückzusetzen. Wenn 5V an diesen Pin angelegt werden, wird der Mikrocontroller zurückgesetzt und das Programm startet von vorne.
Taktsignal
Obwohl der Mikrocontroller einen eingebauten Oszillator hat, kann er nicht ohne zwei externe Kondensatoren und einen Quarzkristall arbeiten, die seinen Betrieb stabilisieren und seine Frequenz (Arbeitsgeschwindigkeit des Mikrocontrollers) bestimmen.
Natürlich ist diese Lösung nicht immer anwendbar, daher gibt es immer alternative Lösungen. Eine davon besteht darin, das Taktsignal von einer speziellen Quelle über einen Inverter bereitzustellen. Siehe Abbildung links.
6.2 Zusätzliche Komponenten
Unabhängig davon, dass der Mikrocontroller ein Produkt moderner Technologie ist, ist er ohne Anschluss an zusätzliche Komponenten nutzlos. Vereinfacht gesagt bedeutet das Auftreten einer Spannung an seinen Pins nichts, wenn sie nicht zur Durchführung bestimmter Operationen (Ein-/Ausschalten, Verschieben, Anzeigen usw.) verwendet wird.
Schalter und Taster
Es gibt keine einfacheren Bauteile als Schalter und Taster. Dies ist die einfachste Methode, um das Auftreten einer Spannung am Mikrocontroller-Eingangspin zu erkennen.
In der Praxis ist es jedoch nicht so einfach... Es geht um das Kontaktprellen – ein häufiges Problem bei mechanischen Schaltern. Wenn die Kontakte aufeinandertreffen, wirken ihr Impuls und ihre Elastizität zusammen und verursachen ein Prellen. Das Ergebnis ist ein schnell pulsierender elektrischer Strom anstelle eines sauberen Übergangs von Null auf Vollstrom. Dies geschieht hauptsächlich aufgrund von Vibrationen, leichten Unebenheiten und Schmutz zwischen den Kontakten. Dieser Effekt ist bei der alltäglichen Verwendung dieser Komponenten normalerweise nicht wahrnehmbar, da das Prellen zu schnell erfolgt. Mit anderen Worten, der gesamte Vorgang dauert nicht lange (einige Mikro- oder Millisekunden), aber er ist lang genug, um vom Mikrocontroller registriert zu werden. Wenn nur ein Taster als Impulszähler verwendet wird, treten in fast 100 % der Fälle Fehler auf!
Die einfachste Lösung für dieses Problem ist der Anschluss einer einfachen RC-Schaltung, die schnelle Spannungsänderungen unterdrückt. Da die Prellperiode nicht definiert ist, sind die Werte der Komponenten nicht genau festgelegt. In den meisten Fällen wird empfohlen, die in der folgenden Abbildung gezeigten Werte zu verwenden.
Wenn absolute Stabilität erforderlich ist, sollten radikale Maßnahmen ergriffen werden. Der Ausgang der in der Abbildung gezeigten Schaltung (RS-Flipflop) ändert seinen logischen Zustand erst nach der Erkennung des ersten durch Kontaktprellen ausgelösten Impulses. Diese Lösung ist teuer (SPDT-Schalter), aber effizient, das Problem ist definitiv gelöst. Da kein Kondensator verwendet wird, können auf diese Weise auch sehr kurze Impulse erfasst werden.
Zusätzlich zu diesen Hardware-Lösungen gibt es auch eine einfache Software-Lösung. Wenn ein Programm den Zustand eines Eingangspins testet und eine Änderung erkennt, sollte die Prüfung nach einer bestimmten Verzögerung erneut durchgeführt werden. Wenn die Änderung bestätigt wird, bedeutet dies, dass ein Schalter oder Taster seine Position geändert hat. Die Vorteile einer solchen Lösung sind offensichtlich: Sie ist kostenlos, die Auswirkungen von Störungen werden beseitigt und sie kann auch bei Kontakten geringerer Qualität angewendet werden. Der Nachteil ist derselbe wie bei der Verwendung eines RC-Filters, d. h. Impulse, die kürzer als die Programmverzögerung sind, können nicht erfasst werden.
Optokoppler
Ein Optokoppler ist ein Bauteil, das üblicherweise zur galvanischen Trennung der Mikrocontroller-Elektronik von gefährlichen Strömen oder Spannungen in seiner Umgebung verwendet wird. Optokoppler haben normalerweise eine, zwei oder vier Lichtquellen (LED-Dioden) auf ihrer Eingangsseite, während sich auf ihrer Ausgangsseite, den Dioden gegenüber, die gleiche Anzahl von lichtempfindlichen Elementen (Fototransistoren, Fotothyristoren oder Fototriacs) befindet. Der Punkt ist, dass ein Optokoppler einen kurzen optischen Übertragungsweg verwendet, um ein Signal zwischen den Schaltungselementen zu übertragen, während er sie elektrisch isoliert hält. Diese Isolierung macht nur Sinn, wenn Dioden und lichtempfindliche Elemente getrennt mit Strom versorgt werden. Auf diese Weise werden der Mikrocontroller und die teure Zusatzelektronik vollständig vor Hochspannung und Störungen geschützt, die in der Praxis die häufigste Ursache für die Zerstörung, Beschädigung oder instabile Funktion elektronischer Geräte sind. Die am häufigsten verwendeten Optokoppler sind solche mit Fototransistoren an ihren Ausgängen. Bei Verwendung eines Optokopplers mit interner Basis-Pin-6-Verbindung (es gibt auch Optokoppler ohne diese) kann die Basis offen gelassen werden. Eine optionale Verbindung, die die Auswirkungen von Störungen durch Unterdrückung sehr kurzer Impulse verringert, ist in der Abbildung durch die unterbrochene Linie dargestellt.
Relais
Ein Relais ist ein elektrischer Schalter, der unter der Steuerung eines anderen elektrischen Stromkreises öffnet und schließt. Er wird daher an die Ausgangspins des Mikrocontrollers angeschlossen und zum Ein- und Ausschalten von Hochleistungsgeräten wie Motoren, Transformatoren, Heizungen, Lampen, Antennensystemen usw. verwendet. Diese werden fast immer von den empfindlichen Komponenten der Platine entfernt platziert. Es gibt verschiedene Arten von Relais, aber alle arbeiten nach dem gleichen Prinzip. Wenn ein Strom durch die Spule fließt, wird das Relais von einem Elektromagneten betätigt, um einen oder mehrere Kontaktsätze zu öffnen oder zu schließen. Ähnlich wie bei Optokopplern gibt es keine galvanische Verbindung (elektrischer Kontakt) zwischen Eingangs- und Ausgangskreisen. Relais benötigen normalerweise sowohl eine höhere Spannung als auch einen höheren Strom, um zu funktionieren, aber es gibt auch Miniaturrelais, die mit einem niedrigen Strom direkt von einem Mikrocontroller-Pin aktiviert werden können.
Die Abbildung zeigt die für den 8051-Mikrocontroller spezifische Lösung. Hier wird ein Darlington-Transistor verwendet, um Relais aufgrund seiner hohen Stromverstärkung zu aktivieren. Dies entspricht nicht den "Regeln", ist jedoch erforderlich, wenn eine Aktivierung mit logisch 1 verwendet wird, da der Ausgangsstrom dann sehr niedrig ist (Pin verhält sich als Eingang).
Um das Auftreten einer durch plötzliches Abschalten des Spulenstroms verursachten hohen Selbstinduktionsspannung zu verhindern, wird eine antiparallele Diode parallel zur Spule geschaltet. Der Zweck dieser Diode besteht darin, die Spannungsspitze zu "begrenzen".
Leuchtdiode (LED)
Leuchtdioden sind Bauelemente zur optischen Signalgebung in der Elektronik. Sie werden in verschiedenen Formen, Farben und Größen hergestellt. Aufgrund ihres niedrigen Preises, ihres geringen Stromverbrauchs und ihrer einfachen Verwendung haben sie andere Lichtquellen, insbesondere Glühlampen, fast vollständig verdrängt. Sie verhalten sich ähnlich wie normale Dioden, mit dem Unterschied, dass sie Licht emittieren, wenn Strom durch sie fließt.
Es ist wichtig, ihren Strom zu begrenzen, da sie sonst dauerhaft zerstört werden. Aus diesem Grund muss ein Widerstand in Reihe zu einer LED geschaltet werden. Um den Wert dieses Widerstands zu bestimmen, muss die Durchlassspannung der Diode bekannt sein, die davon abhängt, aus welchem Material die Diode besteht und welche Farbe sie hat. Typische Werte der am häufigsten verwendeten Dioden sind in der folgenden Tabelle aufgeführt. Wie zu sehen, gibt es drei Haupttypen von LEDs. Standard-LEDs erreichen ihre volle Helligkeit bei einem Strom von 20 mA. Niedrigstrom-Dioden erreichen ihre volle Helligkeit bei einem zehnmal niedrigeren Strom, während Super-Bright-Dioden ein intensiveres Licht als Standard-LEDs erzeugen.
| Farbe |
Typ |
Typischer Strom Id (mA) |
Maximaler Strom If (mA) |
Durchlassspannung Ud (V) |
| Infrarot |
- |
30 |
50 |
1.4 |
| Rot |
Standard |
20 |
30 |
1.7 |
| Rot |
Super Hell |
20 |
30 |
1.85 |
| Rot |
Niedrigstrom |
2 |
30 |
1.7 |
| Orange |
- |
10 |
30 |
2.0 |
| Grün |
Niedrigstrom |
2 |
20 |
2.1 |
| Gelb |
- |
20 |
30 |
2.1 |
| Blau |
- |
20 |
30 |
4.5 |
| Weiß |
- |
25 |
35 |
4.4 |
Da der 8051-Mikrocontroller nur einen geringen Ausgangsstrom liefern kann und seine Pins als Ausgänge konfiguriert sind, wenn die an ihnen anliegende Spannung 0V beträgt, erfolgt der direkte Anschluss an LEDs wie in der Abbildung rechts gezeigt (Niedrigstrom-LED, Kathode ist mit dem Ausgangspin verbunden).
LED-Anzeigen
Eine LED-Anzeige ist im Grunde nichts anderes als mehrere LEDs, die in einem Kunststoffgehäuse vergossen sind. Es gibt viele Arten von Anzeigen, die aus mehreren Dutzend eingebauten Dioden bestehen und verschiedene Symbole anzeigen können.
Am häufigsten wird die sogenannte 7-Segment-Anzeige verwendet. Sie besteht aus 8 LEDs, wobei 7 Segmente rechteckig für die Symbolanzeige angeordnet sind und ein zusätzliches Segment für die Anzeige des Dezimalpunkts vorhanden ist. Um die Verbindung zu vereinfachen, sind die Anoden und Kathoden aller Dioden mit dem gemeinsamen Pin verbunden, sodass es gemeinsame Anoden- und gemeinsame Kathodenanzeigen gibt. Die Segmente sind mit den Buchstaben A bis G sowie dp gekennzeichnet, wie in der Abbildung links gezeigt. Bei der Verbindung wird jede Diode separat behandelt, was bedeutet, dass jede ihren eigenen Strombegrenzungswiderstand benötigt.
Anzeigen, die mit dem Mikrocontroller verbunden sind, belegen normalerweise eine große Anzahl wertvoller E/A-Pins, was ein großes Problem darstellen kann, insbesondere wenn mehrstellige Zahlen angezeigt werden sollen. Das Problem ist mehr als offensichtlich, wenn beispielsweise zwei 6-stellige Zahlen angezeigt werden sollen (eine einfache Rechnung zeigt, dass in diesem Fall 96 Ausgangspins benötigt werden). Die Lösung für dieses Problem heißt MULTIPLEXING. Dabei wird eine optische Täuschung erzeugt, die auf dem gleichen Funktionsprinzip wie eine Filmkamera basiert. Es ist immer nur eine Ziffer aktiv, aber sie ändert ihren Zustand so schnell, dass der Eindruck entsteht, dass alle Ziffern einer Zahl gleichzeitig aktiv sind.
Hier ist eine Erklärung der obigen Abbildung. Zuerst wird ein Byte, das die Einer darstellt, an einen Mikrocontroller-Port angelegt und gleichzeitig ein Transistor T1 aktiviert. Nach einer Weile wird T1 ausgeschaltet, ein Byte, das die Zehner darstellt, wird an einen Port angelegt und ein Transistor T2 aktiviert. Dieser Vorgang wird für alle Ziffern und entsprechenden Transistoren zyklisch mit hoher Geschwindigkeit wiederholt.
Die Tatsache, dass der Mikrocontroller nur eine Art Miniaturcomputer ist, der nur die Sprache der Nullen und Einsen versteht, zeigt sich vollständig bei der Anzeige einer Ziffer. Der Mikrocontroller weiß nämlich nicht, was Einer, Zehner oder Hunderter sind, noch wie die zehn Ziffern aussehen, die wir gewohnt sind. Daher muss jede anzuzeigende Zahl wie folgt vorbereitet werden:
Zunächst muss eine mehrstellige Zahl in Einer, Zehner usw. in einer bestimmten Unterroutine zerlegt werden. Dann muss jede dieser Ziffern in speziellen Bytes gespeichert werden. Die Ziffern erhalten ein bekanntes Format durch eine "Maskierung". Mit anderen Worten, das Binärformat jeder Ziffer wird in einer einfachen Unterroutine durch eine andere Bitkombination ersetzt. Beispielsweise wird die Ziffer 8 (0000 1000) durch die Binärzahl 0111 111 ersetzt, um alle LEDs, die die Ziffer 8 anzeigen, zu aktivieren. Die einzige Diode, die in diesem Fall inaktiv bleibt, ist für den Dezimalpunkt reserviert. Wenn ein Mikrocontroller-Port so mit der Anzeige verbunden ist, dass Bit 0 das Segment "a" aktiviert, Bit 1 das Segment "b", Bit 2 das Segment "c" usw., dann zeigt die folgende Tabelle die "Maske" für jede Ziffer.
| Anzuzeigende Ziffer |
Anzeigesegmente |
|
dp |
a |
b |
c |
d |
e |
f |
g |
| 0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
| 1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
| 2 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
| 3 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
| 4 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
| 5 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
| 6 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
| 7 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
| 8 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
| 9 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
Zusätzlich zu den Ziffern 0 bis 9 können durch entsprechende Maskierung auch einige Buchstaben des Alphabets - A, C, E, J, F, U, H, L, b, c, d, o, r, t - angezeigt werden.
Wenn gemeinsame Kathodenanzeigen verwendet werden, sollten alle Einsen in der Tabelle durch Nullen ersetzt werden und umgekehrt. Außerdem sollten NPN-Transistoren als Treiber verwendet werden.
Flüssigkristallanzeigen (LCD)
Ein LCD-Display ist speziell für den Einsatz mit Mikrocontrollern hergestellt, was bedeutet, dass es nicht von standardmäßigen IC-Schaltungen aktiviert werden kann. Es wird zur Anzeige verschiedener Nachrichten auf einem Miniatur-Flüssigkristalldisplay verwendet.
Das hier beschriebene Modell wird aufgrund seines niedrigen Preises und seiner großen Fähigkeiten in der Praxis am häufigsten verwendet. Es basiert auf dem Mikrocontroller HD44780 (Hitachi) und kann Nachrichten in zwei Zeilen mit jeweils 16 Zeichen anzeigen. Es zeigt alle Buchstaben des Alphabets, griechische Buchstaben, Satzzeichen, mathematische Symbole usw. an. Darüber hinaus ist es möglich, benutzerdefinierte Symbole anzuzeigen. Weitere nützliche Funktionen sind automatische Nachrichtenverschiebung (links und rechts), Cursor-Anzeige, LED-Hintergrundbeleuchtung usw.
LCD-Pins
Entlang einer Seite einer kleinen Leiterplatte befinden sich Pins. Diese werden zum Anschluss an den Mikrocontroller verwendet. Es gibt insgesamt 14 Pins mit Nummern (16, wenn eine Hintergrundbeleuchtung vorhanden ist). Ihre Funktion ist in der folgenden Tabelle beschrieben:
| Funktion |
Pin-Nr. |
Name |
Logikzustand |
Beschreibung |
| Masse |
1 |
Vss |
- |
0V |
| Stromversorgung |
2 |
Vdd |
- |
+5V |
| Kontrast |
3 |
Vee |
- |
0 - Vdd |
| Betriebssteuerung |
4 |
RS |
0
1 |
D0-D7 werden als Befehle interpretiert
D0-D7 werden als Daten interpretiert |
| 5 |
R/W |
0
1 |
Daten schreiben (vom Controller zum LCD)
Daten lesen (vom LCD zum Controller) |
| 6 |
E |
0
1
Von 1 auf 0 |
Zugriff auf LCD deaktiviert
Normalbetrieb
Daten/Befehle werden an LCD übertragen |
| Daten / Befehle |
7 |
D0 |
0/1 |
Bit 0 LSB |
| 8 |
D1 |
0/1 |
Bit 1 |
| 9 |
D2 |
0/1 |
Bit 2 |
| 10 |
D3 |
0/1 |
Bit 3 |
| 11 |
D4 |
0/1 |
Bit 4 |
| 12 |
D5 |
0/1 |
Bit 5 |
| 13 |
D6 |
0/1 |
Bit 6 |
| 14 |
D7 |
0/1 |
Bit 7 MSB |
LCD-Bildschirm
Ein LCD-Bildschirm besteht aus zwei Zeilen mit jeweils 16 Zeichen. Jedes Zeichen besteht aus einer 5x8- oder 5x11-Punktmatrix. Dieses Buch behandelt das am häufigsten verwendete Display, d. h. das 5x8-Zeichen-Display.
Der Displaykontrast hängt von der Versorgungsspannung und davon ab, ob Nachrichten in einer oder zwei Zeilen angezeigt werden. Aus diesem Grund wird am Pin Vee eine variable Spannung 0-Vdd angelegt. Normalerweise wird dazu ein Trimmer-Potentiometer verwendet. Einige LCD-Displays haben eine eingebaute Hintergrundbeleuchtung (blaue oder grüne LEDs). Wenn sie während des Betriebs verwendet wird, sollte ein Strombegrenzungswiderstand in Reihe mit einem der Pins für die Hintergrundbeleuchtung geschaltet werden (ähnlich wie bei LEDs).
Wenn keine Zeichen angezeigt werden oder alle schwach erscheinen, wenn das Display eingeschaltet ist, sollte als erstes der Potentiometer für die Kontrastregelung überprüft werden. Ist er richtig eingestellt? Gleiches gilt, wenn der Betriebsmodus geändert wurde (Schreiben in einer oder zwei Zeilen).
LCD-Speicher
Das LCD-Display enthält drei Speicherblöcke:
- DDRAM Display Data RAM;
- CGRAM Character Generator RAM; und
- CGROM Character Generator ROM.
DDRAM-Speicher
Der DDRAM-Speicher wird zum Speichern der anzuzeigenden Zeichen verwendet. Die Größe dieses Speichers reicht für 80 Zeichen. Einige Speicherstellen sind direkt mit den Zeichen auf dem Display verbunden.
Er funktioniert ganz einfach: Es reicht aus, das Display so zu konfigurieren, dass die Adressen automatisch erhöht werden (nach rechts verschieben) und die Startadresse für die anzuzeigende Nachricht festgelegt wird (z. B. 00 hex).
Danach werden alle über die Leitungen D0-D7 gesendeten Zeichen in dem gewohnten Nachrichtenformat von links nach rechts angezeigt. In diesem Fall beginnt die Anzeige im ersten Feld der ersten Zeile, da die Adresse 00 hex ist. Wenn mehr als 16 Zeichen gesendet werden, werden alle gespeichert, aber nur die ersten sechzehn Zeichen sind sichtbar. Um die restlichen anzuzeigen, muss ein Verschiebebefehl verwendet werden. Praktisch gesehen erscheint alles so, als ob das LCD-Display ein "Fenster" ist, das sich über Speicherstellen mit verschiedenen Zeichen von links nach rechts bewegt. So wird der Effekt einer "bewegten" Nachricht auf dem Bildschirm erzeugt.
Wenn der Cursor eingeschaltet ist, erscheint er an der Stelle, die gerade adressiert wird. Mit anderen Worten: Wenn ein Zeichen an der Cursorposition erscheint, bewegt es sich automatisch zur nächsten adressierten Stelle.
Da es sich um eine Art RAM-Speicher handelt, können Daten geschrieben und gelesen werden, aber ihr Inhalt geht beim Ausschalten der Stromversorgung unwiederbringlich verloren.
CGROM-Speicher
Der CGROM-Speicher enthält die Standard-Zeichentabelle mit allen Zeichen, die auf dem Bildschirm angezeigt werden können. Jedes Zeichen ist einem Speicherplatz zugeordnet.
Die Adressen der CGROM-Speicherplätze entsprechen den ASCII-Zeichen. Wenn das laufende Programm auf einen Befehl "sende Zeichen P an Port" stößt, erscheint der Binärwert 0101 0000 am Port. Dieser Wert ist das ASCII-Äquivalent für das Zeichen P. Er wird dann an das LCD geschrieben, was zur Anzeige des Symbols von der CGROM-Stelle 0101 0000 führt. Mit anderen Worten, das Zeichen "P" wird angezeigt. Dies gilt für alle Buchstaben des Alphabets (Groß- und Kleinbuchstaben), aber nicht für Zahlen.
Wie auf der vorherigen "Karte" zu sehen, sind die Adressen aller Ziffern um 48 gegenüber ihrem Wert nach oben verschoben (Ziffer 0 Adresse 48, Ziffer 1 Adresse 49, Ziffer 2 Adresse 50 usw.). Daher muss jede Ziffer vor dem Senden an das LCD um die Dezimalzahl 48 erhöht werden, um sie korrekt anzuzeigen.
Von ihrer Entstehung bis heute können Computer nur Zahlen erkennen, aber keine Buchstaben. Das bedeutet, dass alle Daten, die ein Computer mit einem Peripheriegerät austauscht, ein binäres Format haben, auch wenn sie vom Menschen als Buchstaben erkannt werden (die Tastatur ist ein hervorragendes Beispiel). Jedes Zeichen entspricht einer eindeutigen Kombination von Nullen und Einsen. ASCII ist eine Zeichencodierung, die auf dem englischen Alphabet basiert. Der ASCII-Code legt die Entsprechung zwischen standardmäßigen Zeichensymbolen und ihren numerischen Äquivalenten fest.
CGRAM-Speicher
Neben Standardzeichen kann das LCD-Display auch vom Benutzer selbst definierte Symbole anzeigen. Es kann jedes Symbol in der Größe von 5x8 Pixeln sein. Ein RAM-Speicher namens CGRAM in der Größe von 64 Bytes ermöglicht dies.
Die Speicherregister sind 8 Bit breit, aber nur die 5 unteren Bits werden verwendet. Eine logische Eins (1) in jedem Register stellt einen leuchtenden Punkt dar, während 8 zusammengehörige Stellen ein Zeichen darstellen. Dies wird am besten in der folgenden Abbildung veranschaulicht:
Symbole werden normalerweise zu Beginn des Programms definiert, indem einfach Nullen und Einsen in die CGRAM-Register geschrieben werden, um die gewünschten Formen zu erzeugen. Um sie anzuzeigen, reicht es aus, ihre Adresse anzugeben. Beachten Sie die erste Spalte in der CGROM-Zeichentabelle. Sie enthält keine RAM-Speicheradressen, sondern die hier diskutierten Symbole. In diesem Beispiel bedeutet "Anzeige 0" - Anzeige "č", "Anzeige 1" - Anzeige "ž" usw.
LCD-Grundbefehle
Alle über die Ausgänge D0-D7 an das LCD übertragenen Daten werden als Befehl oder als Daten interpretiert, was vom logischen Zustand des Pins RS abhängt:
RS = 1 - Bits D0-D7 sind Adressen der anzuzeigenden Zeichen. Der LCD-Prozessor adressiert ein Zeichen aus der Zeichentabelle und zeigt es an. Die DDRAM-Adresse gibt die Stelle an, an der das Zeichen angezeigt werden soll. Diese Adresse wird vor der Übertragung des Zeichens definiert, oder die Adresse des zuvor übertragenen Zeichens wird automatisch erhöht.
RS = 0 - Bits D0-D7 sind Befehle, die den Anzeigemodus festlegen. Die vom LCD erkannten Befehle sind in der folgenden Tabelle aufgeführt:
| Befehl |
RS |
RW |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
Ausführungszeit |
| Display löschen |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1.64mS |
| Cursor nach Hause |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
x |
1.64mS |
| Eingabemodus festlegen |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
I/D |
S |
40uS |
| Display Ein/Aus-Steuerung |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
D |
U |
B |
40uS |
| Cursor/Display-Verschiebung |
0 |
0 |
0 |
0 |
0 |
1 |
D/C |
R/L |
x |
x |
40uS |
| Funktion festlegen |
0 |
0 |
0 |
0 |
1 |
DL |
N |
F |
x |
x |
40uS |
| CGRAM-Adresse festlegen |
0 |
0 |
0 |
1 |
CGRAM-Adresse |
40uS |
| DDRAM-Adresse festlegen |
0 |
0 |
1 |
DDRAM-Adresse |
40uS |
| "BUSY"-Flag (BF) lesen |
0 |
1 |
BF |
DDRAM-Adresse |
- |
| In CGRAM oder DDRAM schreiben |
1 |
0 |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
40uS |
| Aus CGRAM oder DDRAM lesen |
1 |
1 |
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
40uS |
I/D 1 = Inkrement (um 1) R/L 1 = Nach rechts verschieben
0 = Dekrement (um 1) 0 = Nach links verschieben
S 1 = Display-Verschiebung ein DL 1 = 8-Bit-Schnittstelle
0 = Display-Verschiebung aus 0 = 4-Bit-Schnittstelle
D 1 = Display ein N 1 = Anzeige in zwei Zeilen
0 = Display aus 0 = Anzeige in einer Zeile
U 1 = Cursor ein F 1 = Zeichenformat 5x10 Punkte
0 = Cursor aus 0 = Zeichenformat 5x7 Punkte
B 1 = Cursor blinken ein D/C 1 = Display verschieben
0 = Cursor blinken aus 0 = Cursor verschieben
Was ist das Busy-Flag?
Im Vergleich zum Mikrocontroller ist das LCD ein extrem langsames Bauteil. Aus diesem Grund war es notwendig, ein Signal bereitzustellen, das nach der Befehlsausführung anzeigt, dass das Display bereit ist, neue Daten zu empfangen. Dieses Signal, das Busy-Flag genannt, kann von der Leitung D7 gelesen werden. Wenn das BF-Bit gelöscht ist (BF=0), ist das Display bereit, neue Daten zu empfangen.
LCD-Verbindung
Je nachdem, wie viele Leitungen für die Verbindung des LCD mit dem Mikrocontroller verwendet werden, gibt es 8-Bit- und 4-Bit-LCD-Modi. Der entsprechende Modus wird zu Beginn des Betriebs ausgewählt. Dieser Vorgang wird als "Initialisierung" bezeichnet. Der 8-Bit-LCD-Modus verwendet die Ausgänge D0-D7, um Daten wie auf der vorherigen Seite beschrieben zu übertragen. Der Hauptzweck des 4-Bit-LED-Modus besteht darin, wertvolle E/A-Pins des Mikrocontrollers zu sparen. Nur die 4 höherwertigen Bits (D4-D7) werden für die Kommunikation verwendet, andere können unverbunden bleiben. Jedes Datum wird in zwei Schritten an das LCD gesendet: zuerst werden die vier höherwertigen Bits gesendet (normalerweise über die Leitungen D4-D7), dann die vier niederwertigen Bits. Die Initialisierung ermöglicht es dem LCD, die empfangenen Bits richtig zu verknüpfen und zu interpretieren. Daten werden selten vom LCD gelesen (sie werden hauptsächlich vom Mikrocontroller zum LCD übertragen), sodass es oft möglich ist, einen zusätzlichen E/A-Pin zu sparen, indem der R/W-Pin einfach mit Masse verbunden wird. Diese Ersparnis hat ihren Preis. Nachrichten werden normal angezeigt, aber es wird nicht möglich sein, das Busy-Flag zu lesen, da auch das Display nicht gelesen werden kann.
Es gibt jedoch eine einfache Lösung. Nach dem Senden eines Zeichens oder Befehls ist es wichtig, dem LCD genügend Zeit für seine Arbeit zu geben. Da die Ausführung des langsamsten Befehls etwa 1,64 ms dauert, reicht es aus, etwa 2 ms für das LCD zu warten.
LCD-Initialisierung
Das LCD wird beim Einschalten automatisch gelöscht. Dies dauert etwa 15 ms. Danach ist das Display betriebsbereit. Der Betriebsmodus ist standardmäßig voreingestellt. Das bedeutet:
- Display ist gelöscht
- Modus
- DL = 1 Kommunikation über 8-Bit-Schnittstelle
- N = 0 Nachrichten werden in einer Zeile angezeigt
- F = 0 Zeichenschrift 5 x 8 Punkte
- Display/Cursor ein/aus
- D = 0 Display aus
- U = 0 Cursor aus
- B = 0 Cursor blinken aus
- Zeicheneingabe
- ID = 1 Angezeigte Adressen werden automatisch um 1 erhöht
- S = 0 Display-Verschiebung aus
Der automatische Reset funktioniert in den meisten Fällen problemlos. In den meisten Fällen, aber nicht immer! Wenn die Versorgungsspannung aus irgendeinem Grund nicht innerhalb von 10 ms den vollen Wert erreicht, beginnt das Display völlig unvorhersehbar zu arbeiten. Wenn die Spannungsversorgung diese Bedingung nicht erfüllen kann oder ein völlig sicherer Betrieb erforderlich ist, wird eine Initialisierung durchgeführt. Die Initialisierung bewirkt unter anderem einen neuen Reset, der das Display in die Lage versetzt, normal zu arbeiten.
Die folgende Abbildung zeigt die Vorgehensweise für die 8-Bit-Initialisierung:
Es ist kein Fehler!
In diesem Algorithmus wird derselbe Wert dreimal hintereinander gesendet.
Bei der 4-Bit-Initialisierung lautet die Vorgehensweise wie folgt:
6.3 Beispiele
Das folgende Schema wird in den folgenden Beispielen verwendet:
Neben den für den Betrieb des Mikrocontrollers notwendigen Komponenten wie Oszillator mit Kondensatoren und der einfachsten Reset-Schaltung sind auch mehrere LEDs und ein Taster vorhanden. Diese dienen zur Anzeige des Programmablaufs.
Alle LEDs sind so gepolt, dass sie durch Anlegen eines logisch niedrigen (0) Pegels an den Mikrocontroller-Pin aktiviert werden.
LED-Blinken
Der Zweck dieses Beispiels ist nicht, die Funktionsweise von LEDs zu demonstrieren, sondern die Betriebsgeschwindigkeit des Mikrocontrollers. Um ein sichtbares Blinken zu ermöglichen, muss zwischen den Ein-/Aus-Zuständen der LEDs ausreichend Zeit vergehen. In diesem Beispiel wird die Zeitverzögerung durch den Aufruf einer Unterroutine namens Delay bereitgestellt. Es handelt sich um eine dreifache Schleife, in der das Programm etwa 0,5 Sekunden verweilt und die Werte in den Registern R0, R1 oder R2 dekrementiert. Nach der Rückkehr aus der Unterroutine wird der Pin-Zustand invertiert und der Vorgang wiederholt...
;************************************************************************
;* PROGRAMMNAME : Delay.ASM
;* BESCHREIBUNG: Schaltet LED an Pin P1.0 ein/aus mit Software-Verzögerung
;************************************************************************
;GRUNDLEGENDE DIREKTIVEN
$MOD53
$TITLE(DELAY.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;STACK
DSEG AT 03FH
STACK_START: DS 040H
;RESET-VEKTOREN
CSEG AT 0
JMP XRESET ;Reset-Vektor
ORG 100H
XRESET: MOV SP,#STACK_START ;Stack-Pointer definieren
MOV P1,#0FFh ;Alle Pins als Eingänge konfigurieren
LOOP:
CPL P1.0 ;Pin P1.0 Zustand invertieren
LCALL Delay ;Zeitverzögerung
SJMP LOOP
Delay:
MOV R2,#20 ;500 ms Verzögerung
F02: MOV R1,#50 ;25 ms
F01: MOV R0,#230
DJNZ R0,$
DJNZ R1,F01
DJNZ R2,F02
END ;Programmende
Verwendung des Watchdog-Timers
Dieses Beispiel zeigt, wie der Watchdog-Timer nicht verwendet werden sollte. Der Watchdog-Timer ist richtig eingestellt (Zählzeit 1024 ms), aber der Befehl zu seiner Rücksetzung wurde absichtlich weggelassen, sodass dieser Timer immer "gewinnt". Infolgedessen wird der Mikrocontroller zurückgesetzt (Registerinhalte bleiben erhalten), das Programm startet von vorne und der Wert im Register R3 wird um 1 erhöht und dann auf Port P1 kopiert.
Die LEDs zeigen diese Zahl binär an...
;************************************************************************
;* PROGRAMMNAME : WatchDog.ASM
;* BESCHREIBUNG : Nach Watchdog-Reset wird der Wert in Register R3 inkrementiert und binär auf Port P1 angezeigt.
;************************************************************************
;GRUNDLEGENDE DIREKTIVEN
$MOD53
$TITLE(WATCHDOG.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
WMCON DATA 96H
WDTEN EQU 00000001B ; Watchdog-Timer aktiviert
PERIOD EQU 11000000B ; Watchdog-Periode auf 1024ms gesetzt
;RESET-VEKTOR
CSEG AT 0
JMP XRESET ; Reset-Vektor
CSEG
ORG 100H
XRESET: ORL WMCON,#PERIOD ; Watchdog-Periode definieren
ORL WMCON,#WDTEN ; Watchdog-Timer aktivieren
MOV A,R3 ; R3 nach Port 1 verschieben
MOV P1,A
INC R3 ; Register R3 um 1 erhöhen
LAB: SJMP LAB ; Auf Watchdog-Reset warten
END ; Programmende
Timer T0 im Modus 1
Dieses Programm verbringt die meiste Zeit in einer Endlosschleife und wartet darauf, dass Timer T0 einen vollen Zyklus zählt. Wenn dies geschieht, wird ein Interrupt ausgelöst, die Routine TIM0_ISR ausgeführt und eine logische Null (0) auf Port P1 um ein Bit nach rechts geschoben. Dies ist eine weitere Möglichkeit, die Betriebsgeschwindigkeit des Mikrocontrollers zu demonstrieren, da jede Verschiebung bedeutet, dass der Zähler T0 216 Impulse gezählt hat!
;************************************************************************
;* PROGRAMMNAME : Tim0Mod1.ASM
;* BESCHREIBUNG: Rotiert eine "0" auf Port 1 mittels Timer T0 im Modus 1
;************************************************************************
;GRUNDLEGENDE DIREKTIVEN
$MOD53
$TITLE(TIM0MOD1.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;VARIABLENDEKLARATION
;STACK
DSEG AT 03FH
STACK_START: DS 040H
;RESET-VEKTOREN
CSEG AT 0
JMP XRESET ; Reset-Vektor
ORG 00BH
JMP TIM0_ISR ; Timer T0 Reset-Vektor
ORG 100H
XRESET: MOV SP,#STACK_START ; Stack-Pointer definieren
MOV TMOD,#01H ; Modus 1 gewählt
MOV A,#0FFH
MOV P1,#0FFH
SETB TR0 ; Timer T0 gestartet
MOV IE,#082H ; Interrupt aktiviert
CLR C
LOOP1: SJMP LOOP1 ; Hier verweilen
TIM0_ISR: RRC A ; Akkumulator A mit Übertragsflag rotieren
MOV P1,A ; Akkumulatorinhalt nach PORT1
RETI ; Rückkehr aus Interrupt
END ; Programmende