[Einführung]
Mikrocontroller-Technologie ist eine unverzichtbare Mainstream-Technologie in der modernen Industrieautomation, Elektronik, Elektrotechnik und dem Internet der Dinge (IoT). Da unser Leben immer intelligenter wird, hat die Mikrocontroller-Technologie praktisch jeden Aspekt unseres täglichen Lebens durchdrungen, beispielsweise in intelligenten Reiskochern, intelligenten Lautsprechern und mehr.
Vor diesem Hintergrund soll die Artikelreihe „Relearning the 51 Microcontroller“ Einsteigern den Einstieg in die Mikrocontroller-Technologie erleichtern. Wir beginnen mit der einfachsten Aufgabe {{2}dem Einschalten einer einzelnen LED- und fahren nach und nach mit der Implementierung von Modulen wie Tastensteuerungen, dem LCD1602-Display, den Temperatursensoren DS18B20 und DS1302 sowie der Kommunikation zwischen zwei Mikrocontrollern fort. Wir behandeln auch Hardware-Kommunikationsprotokolle wie UART, I²C und SPI. Durch die Kombination dieser Konzepte mit C-Programmiertechniken verwenden wir reale Ingenieurprojekte, um Programmieransätze zu veranschaulichen, sodass Sie C-Zeiger und -Strukturen flexibel anwenden können, um eine modulare Programmierung zu erreichen.
Kommen wir nun zurück zum Hauptthema: Verwendung eines 51-Mikrocontrollers zur Steuerung einer LED und zur Erzeugung eines atmenden Lichteffekts.
[Wie Atemlichter funktionieren]
Schauen wir uns zunächst an, wie ein atmender Lichteffekt funktioniert.
Ein atmendes Licht wird allmählich heller und dann allmählich dunkler, wobei dieser Zyklus auf eine Art und Weise wiederholt wird, die dem Atmen ähnelt. Da die Pins eines Mikrocontrollers jedoch nur entweder eine 1 (ein) oder eine 0 (aus) ausgeben können, wie kann dann ein allmählicher Übergangseffekt erzielt werden?
Dies liegt an der Persistenz des Sehvermögens in unseren Augen. Wenn wir etwas betrachten, bleibt das von unseren Augen erzeugte Bild 0,04 Sekunden lang bestehen (diese Zahl wurde online gefunden).
Wenn wir mit 0,04 Sekunden rechnen, entspricht das 40 ms. Wenn die LED also jeweils 20 ms lang ein- und ausgeschaltet ist, erscheint sie für das menschliche Auge so, als ob sie ständig leuchtet.

Ist der Effekt, wenn eine LED 20 ms lang ein- und 20 ms lang blinkt, derselbe, als wenn sie die ganze Zeit an bleibt?
Haha, es ist definitiv anders. Wenn das Licht alle 20 Millisekunden ein- und ausgeschaltet wird, ist der Effekt, den wir sehen, schwächer als wenn es ständig eingeschaltet bleibt. Wenn wir davon ausgehen, dass die Helligkeit eines kontinuierlich leuchtenden Lichts 100 % beträgt, beträgt die Helligkeit eines Lichts, das alle 20 Millisekunden zwischen An- und Ausschalten wechselt, 50 %. Auf dieser Grundlage können wir die Helligkeit der LED anpassen.

An diesem Punkt können wir die Helligkeit der LED anpassen (indem wir die Dauer des hohen Pegels innerhalb des 40-ms-Zyklus festlegen). Dies ist das Prinzip hinter der bekannten PWM-Methode (Pulsweitenmodulation) zur Helligkeitssteuerung. Die Einstellung der Dauer des hohen Pegels entspricht der Anpassung des Arbeitszyklus (d. h. der Dauer des hohen Pegels dividiert durch den Gesamtzyklus: 20/40=50 %).
Der wichtigste Faktor ist hierbei dieser Arbeitszyklus. Wenn die Periode beispielsweise 20 ms beträgt und die LED abwechselnd 10 ms an und 10 ms aus ist, beträgt die wahrgenommene Helligkeit immer noch 50 % (d. h. das Tastverhältnis beträgt 10/20=50 %).
Sehen wir uns als Nächstes an, wie dies im Programm implementiert wird.
[Programmimplementierung]
Eine LED einschalten
Beginnen wir zunächst mit dem Einschalten einer LED und implementieren dann nach und nach einen atmenden Lichteffekt. Die Hardware, die wir verwenden werden, ist wie folgt:
| Entwicklungsboard | ZeroOne Mikrocontroller-Trainings-Entwicklungsboard |
|---|---|
| Mikrocontroller-Modell | STC89C52 |
| LED-Schnittstelle | Pin P4^4 |

Aus dem Schaltplan können wir erkennen, dass die LED mit Pin P4^4 des Mikrocontrollers verbunden ist. Wenn der Mikrocontroller eine 1 ausgibt, leuchtet die LED; Wenn eine 0 ausgegeben wird, erlischt die LED. Daher ist das Programm zum Einschalten einer LED recht einfach, wie unten gezeigt:

Das Programm zum Einschalten einer LED ist recht einfach; Ich bin sicher, jeder weiß, wie es geht.
Anpassen der LED-Helligkeit
Als Nächstes implementieren wir eine Funktion, die es uns ermöglicht, die Helligkeit (d. h. den Arbeitszyklus) wie folgt anzupassen:

Definieren Sie eine statische Variable „duty_cycle“, um den Arbeitszyklus zu speichern. Wenn „Flag“ 1 ist, erhöht sich der Arbeitszyklus schrittweise auf 255. Setzen Sie dann „Flag“ auf 0 und „Duty_Cycle“ verringert sich schrittweise von 255 auf 0. Wiederholen Sie diesen Zyklus.
Haha, an diesem Punkt könnte man meinen, dass das Atemlicht bereits funktioniert, aber das ist nicht der Fall. Wenn Sie mir nicht glauben, probieren Sie den obigen Code selbst aus.
Wo genau liegt also das Problem?
Das Problem liegt in unserem direkten Aufruf der Helligkeitseinstellungsfunktion „set_led_luminance()“. Diese Funktion benötigt 40 ms, um einen Zyklus abzuschließen, was bedeutet, dass der Arbeitszyklus während dieser 40 ms nicht geändert werden kann; Andernfalls funktioniert die Helligkeitsanpassung nicht. Werfen wir noch einmal einen Blick auf die Funktion „breath_led“. Nach jedem Aufruf von „set_led_luminance()“ zum Festlegen des Arbeitszyklus wird der Wert von „duty_cycle“ sofort geändert, ohne 40 ms warten zu müssen.
An dieser Stelle müssen wir einen Software-Timer hinzufügen, um den „duty_cycle“-Wert nach Ablauf von 40 ms zu aktualisieren. Das geänderte Programm lautet wie folgt:

Hinweis: Die Timer-Dauer muss lediglich größer als 40 ms sein (d. h. der Wert von „s_breathCounter“ muss größer als 255 sein), aber es ist am besten, sie auf ein Vielfaches des Zyklus einzustellen. Wenn unser Zyklus beispielsweise 255 ist (d. h. 256 Werte von 0 bis 255), können wir ihn auf das Doppelte dieses Werts setzen: 256 * 2 - 1=511 (d. h. 512 Werte von 0 bis 511).
Und da haben Sie es: -Unser Atemlicht ist fertig! Ist das nicht einfach? (* ̄︶ ̄)
Als nächstes folgt der heutige Bonusbereich.
Obwohl wir den atmenden Lichteffekt erreicht haben, ist der Code nicht ganz prägnant oder elegant genug-er verwendet eine Reihe von if- und else-Anweisungen. Mal sehen, ob wir es noch weiter vereinfachen können.
Vereinfachen wir zunächst diesen Abschnitt der Funktion set_led_luminance(), wie in der folgenden Abbildung dargestellt.

Bevor wir dies vereinfachen, geben wir einen kurzen Tipp zu C: die bitweise UND-Verknüpfung.

Daraus wissen wir, dass die Durchführung einer bitweisen UND-Operation mit 0 unabhängig davon, ob es 1 oder 0 ist, zu 0 führt.
Unabhängig davon, ob es 1 oder 0 ist, führt die Durchführung einer bitweisen UND-Verknüpfung mit 1 zum ursprünglichen Wert.
Der Einfachheit halber verwenden wir die hexadezimale Schreibweise (mit dem Präfix „0x“); Beispielsweise entspricht 0xff 255 in Dezimalzahl. Daher,
Wenn eine Zahl kleiner oder gleich 0xff mit 0xff UND-verknüpft wird, ist das Ergebnis die Zahl selbst, wie unten gezeigt

Was passiert, wenn Sie eine bitweise UND-Verknüpfung zwischen einer Zahl größer als 0xff und 0xff durchführen?

Das Ergebnis ist der Rest, wenn diese Zahl durch (0xff + 1) geteilt wird (d. h. das Ergebnis liegt immer noch zwischen 0 und 0xff).
Mit dieser bitweisen UND-Operation kann der obige Code vereinfacht werden

Auf diese Weise liegt der Wert von s_Counter immer im Bereich von 0x00 bis 0xff.
Ebenso kann der Software-Timer in der Funktion Breath_led oben wie folgt vereinfacht werden:

In Zeile 3 ist 0x1ff dezimal 511. Die Bedingung ist wahr, wenn der Wert von s_breathCounter (0x1ff+1) ist, oder 512, weil 512 & 0x1ff=0. Das Ausrufezeichen davor weist auf eine bitweise NICHT-Operation hin (um genau zu sein, die Bedingung ist erfüllt, wenn der Wert von „s_breathCounter“ ein Vielfaches von 512 ist; dadurch entfällt die Notwendigkeit, „s_breathCounter“ zurückzusetzen. Ich hoffe, diese Erklärung ist erfüllt klar-bitte denken Sie darüber nach). Wenn die Bedingung erfüllt ist, beginnt der Arbeitszyklus zu steigen oder zu sinken.
Aber liegt der Arbeitszyklusbereich nicht zwischen 0 und 255? Warum wird Zeile 5 auch zu 0x1ff (511)? Machen Sie sich keine Sorgen-schauen Sie sich Zeile 8 an. Wir subtrahieren erneut 0xff, sodass der Arbeitszyklusbereich weiterhin zwischen 0 und 255 liegt.
Die Zeilen 7–10 bedeuten: Wenn „duty_cycle > (0xff)“, also 256–511, entspricht das Subtrahieren von 0xff einer Erhöhung von 1 auf 255, sodass die Helligkeit allmählich zunimmt.
Wenn Duty_cycle<= 0xff, the duty_cycle increases from 0 to 255, while the set brightness is 255 - duty_cycle. This effectively decreases the brightness from 255 to 0, causing the light to gradually dim. This achieves the breathing light effect.
Haha, dachten Sie, unsere Vereinfachung sei vorbei?
Nein, nein, nein
Tatsächlich könnten die Zeilen 7 bis 10 noch weiter vereinfacht werden. Hier bietet sich die Absolutwertfunktion an.
Was? Warum die Absolutwertfunktion verwenden?
Schauen Sie sich Zeile 10 an: 0xff - Duty_cycle ist äquivalent zu Duty_cycle - 0xff und nimmt dann den absoluten Wert an. Okay, hier ist der vereinfachte Code:
Die Makrofunktion zum Ermitteln des Absolutwerts lautet wie folgt
Abschließend habe ich den gesamten vereinfachten Code unten eingefügt

Was denken Sie? Ist es nicht einfach? (* ̄︶ ̄)




