Spis treści:
Im vorherigen Tutorial haben wir uns darauf konzentriert, unser erstes Projekt von Grund auf vorzubereiten, um drei LEDs zu steuern. Damit haben Sie die ersten Funktionen gelernt, um die RPI-Leitungen des Pico W zu steuern und den Betrieb des ausgeführten Programms zu verwalten. Außerdem haben Sie die erste Art von Schleife in der Sprache C kennengelernt, sowie die so genannten blockierenden Funktionen und welche Gefahren sie mit sich bringen. Der Schwerpunkt dieses Artikels liegt auf eher theoretischen Fragen im Zusammenhang mit der Sprache C. Er führt Sie in weitere Arten von Schleifen, bedingten Anweisungen und Variablen ein. Natürlich werden wir trotz des eher theoretischen Themas alle Programmierkonstrukte in die Praxis umsetzen.
Kaufen Sie ein Set, um das Programmieren mit dem Raspberry Pi Pico W zu erlernen, und nutzen Sie die Vorteile des Kurses, der im Botland Blog verfügbar ist!
Im Set enthalten: Raspberry Pi Pico W-Modul, Kontaktplatte, Leitungen, LEDs, Widerstände, Tasten, Fotowiderstände, digitale Licht-, Temperatur-, Feuchtigkeits- und Drucksensoren, OLED-Display und ein USB-microUSB-Kabel.
Inhaltsverzeichnis:
- Raspberry Pi Pico – #1 – Einstieg
- Raspberry Pi Pico – #2 – ein paar Worte zur Programmierung
- Raspberry Pi Pico – #3 – erstes Programm
- Raspberry Pi Pico – #4 – wir beginnen mit der Programmierung
- Raspberry Pi Pico – #5 – Schleifen, Variablen und bedingte Anweisungen
- Raspberry Pi Pico – #6 – PWM, ADC und Kommunikation mit dem Computer
- Raspberry Pi Pico – #7 – Codekorrekturen und eigene Funktionen
- Raspberry Pi Pico – #8 – Unterbrechungen und Alarme
- Raspberry Pi Pico – #9 – Indikatorentheorie und Timer
- Raspberry Pi Pico – #10 – Arrays, Strukturen und Zustandsautomaten
Vor dem Start sollte das Team zusammengestellt werden
Wer das Programmieren anhand von realen Projekten erlernen möchte, braucht natürlich die richtige Ausrüstung, aber keine Sorge – Sie müssen jetzt nicht von einem Artikel zum nächsten springen und eine Liste der benötigten elektronischen Komponenten erstellen. Im Botland-Shop ist ein fertiges Set erhältlich, das alle notwendigen Komponenten enthält, um die in der Tutorial-Reihe beschriebenen Projekte mit dem Raspberry Pi Pico durchzuführen.
In dem fertigen Set von Elementen finden Sie:
- Raspberry Pi Pico W,
- MicroUSB-Kabel,
- Kontaktplatte,
- Ein Set von Anschlusskabeln in drei Ausführungen,
- Ein Set von LEDs in drei Farben,
- Ein Set der in der Elektronik am häufigsten verwendeten Widerstände,
- Tact Switch-Tasten,
- Fotowiderstände,
- Digitaler Lichtsensor,
- Digitaler Feuchtigkeits-, Temperatur- und Drucksensor,
- OLED-Display.
Schaltungserweiterung und neues Design
Es ist natürlich, dass in komplexeren Projekten Mikrocontroller nicht nur die Peripheriegeräte steuert, sondern auch auf externe Signale reagieren können. Eine der einfachsten Möglichkeiten, diese Art von Signal zu erzeugen, wäre der Anschluss einer kleinen Taste an den RPI Pico W. In den folgenden Codes verlassen wir uns wie bisher auf die angeschlossenen LEDs und den zusätzlichen Switch, der mit dem GP16-Pin verbunden ist. Wenn die Taste gedrückt wird, wird der Pin des RP2040 mit GND verbunden, also sollte sein zweites Beinchen mit GND verbunden werden.
Zusätzlich zu einer leicht veränderten Schaltung ist auch ein neues Projekt erforderlich. Wir erstellen es genauso wie das aus dem vierten Artikel und der einzige Unterschied ist der Name – loops_and_if. Denken Sie daran, die Codedatei auf die gleiche Weise zu benennen und CMakeLists zu erstellen.
Wie zuvor sind beide generierten Dateien leer. Wir werden uns gleich mit dem Code befassen, aber es lohnt sich schon jetzt, die Make-Datei zu vervollständigen. Ihre Struktur bleibt vorerst unverändert. Sie können also versuchen, sie selbst zu schreiben, indem Sie sich an der Version aus dem vorherigen Projekt orientieren und dabei die Korrektheit der Namen im Auge behalten. Schließlich können Sie sie mit meiner Datei vergleichen, deren Code Sie in der Abbildung oben sehen können. Schließlich müssen Sie das Projekt auch in der Datei CMakeLists.txt hinzufügen, die den gesamten Ordner pico-examples behandelt; auch hier ist die Vorgehensweise identisch mit der des vorherigen Materials.
Es ist eine gute Idee, das Erstellen neuer Projekte ein paar Mal zu üben, und Sie können versuchen, Ihre eigenen, vorerst leeren Projekte hinzuzufügen. In Zukunft werde ich nicht mehr erwähnen, wie das ganze Verfahren abläuft, es sei denn, es gibt irgendwelche Änderungen.
Bedingte if-Anweisung, d.h. Reaktion auf einen Schalter
#include "pico/stdlib.h"
#define GREEN_LED 0 //assigning names to specific values
#define SW_PIN 16
int main() {
gpio_init(SW_PIN); //initialization and setting of pin mode
gpio_init(GREEN_LED);
gpio_set_dir(SW_PIN, GPIO_IN);
gpio_set_dir(GREEN_LED, GPIO_OUT);
gpio_pull_up(SW_PIN); //SW_PIN pull-up to power supply
while (true) {
bool state = gpio_get(SW_PIN); //SW_PIN value reading
if (state == true) //check the state of the state variable
{
gpio_put(GREEN_LED, 1);
}
else //if the state variable has a value other than true
{
gpio_put(GREEN_LED, 0);
}
}
}
Programme in der Sprache C sind nicht nur Anweisungen, die nacheinander ausgeführt werden. Ein sehr häufiger Fall ist, dass wir möchten, dass nur ein bestimmter Teil des Codes ausgeführt wird, abhängig von externen Faktoren. Wir können diese Art von Situation in diesem Beispiel üben, indem wir zum ersten Mal eine bedingte Anweisung verwenden, deren Aufgabe es ist, auf der Grundlage des Signals der Taste zu entscheiden, ob die LED leuchtet oder nicht. In diesem Beispiel werden wir versuchen, die Leuchtdiode entsprechend dem Zustand von GP16 anzusteuern, d.h. wenn dort eine hohe Spannung anliegt, leuchtet die Diode auf und bei fehlender Spannung leuchtet die Diode nicht auf.
Erinnern Sie sich einen Moment an den Code, den wir bei einem früheren Projekt geschrieben haben. Er funktionierte zwar, aber ehrlich gesagt, sah er nicht besonders gut aus. Wenn wir die Leitung, an die eine der Dioden angeschlossen ist, ändern wollten, müssten wir mehrere Codezeilen manuell bearbeiten. Im Falle von noch mehr Änderungen am Programm lohnt es sich also, den Code etwas anders zu schreiben, um spätere Änderungen zu erleichtern. Die Lösung ist hier die Detektive #define. Dank ihr müssen wir nicht mehr in allen Funktionen die numerische Bezeichnung einer bestimmten Leitung verwenden. Von nun an wird GP0 als GREEN_LED dargestellt, während GP16, an dem die Taste angeschlossen ist, SW_PIN heißt. Wenn wir die Anschlussbelegung eines Peripheriegeräts ändern möchten, müssen wir nur die Nummer neben der #define-Direktive ändern.
Der Beginn der Hauptfunktion main ist uns bereits bekannt, hier geht es um die Initialisierung und die Einstellung des Modus der verwendeten Leitungen. Beachten Sie jedoch, dass wir jetzt nicht mehr ihre digitalen Bezeichnungen verwenden müssen. Dies ist dank des oben erwähnten #define-Befehls möglich. Beachten Sie auch den Modus SW_PIN, denn dieses Mal wird diese Leitung der Eingang für das von der Taste kommende Signal sein. Wir müssen die Beschreibung GPIO_IN verwenden. Neu in diesem Codeschnipsel ist die Anweisung gpio_pull_up. Damit wird der GP16 intern auf die Versorgungsspannung gezogen.
Da der Anschluss des RP2040 als Signaleingang dient, müssen wir den Zustand bestimmen, in dem es sich befindet, wenn es frei ist. Wenn die Taste nicht gedrückt wird, erreicht den RPI Pico W kein Signal, sondern der Eingang befindet sich in einem Übergangszustand. Wir wissen nicht, was von ihm gelesen wird und wie das Programm darauf reagieren wird, also müssen wir den Standardzustand dieses Pins bestimmen. Unsere Taste schließt den Eingang mit Masse kurz, also werden wir ihn per Software auf die Versorgungsspannung hochziehen, so dass er sich im High-Zustand befindet, wenn die Taste nicht gedrückt wird. Dafür wird der gpio_pull_up Befehl verwendet. Wenn wir einen Pull-Down-Befehl gegen Masse verwenden wollten, würden wir den gpio_pull_down-Befehl verwenden.
Ein interessanter Aspekt des Hochziehens von Signalen auf bestimmte Zustände ist die Art und Weise, wie dieser Prozess im Mikrocontroller implementiert ist. In der Elektronik geschieht dies mit Widerständen von entsprechendem Wert, aber im RP2040 und in anderen Mikrocontrollern werden MOS-Transistoren verwendet, deren Drain-Source-Übergang als ein solcher Widerstand fungiert.
Kehren wir jedoch zu unserem Code zurück. In der unendlichen while-Schleife, die Sie beim letzten Mal kennen gelernt haben, befindet sich ein geheimnisvoller Befehl, der mit dem Schlüsselwort bool beginnt. Diese Anweisung weist der Variablen state den Zustand des Signals SW_PIN zu. In der Sprache C werden Variablen sehr häufig verwendet und können als universelle Boxen für Daten beschrieben werden, die logische Zustände, Zahlen oder Zeichen sein können. Was eine Variable ist, wird durch das ihr vorangestellte Schlüsselwort bestimmt. In diesem Fall ist ein bool eine Variable, die den logischen Zustand true oder false annehmen kann. Wenn eine Variable dank des Zuweisungsoperators “=” referenziert wird, nimmt sie sofort den von der Funktion gpio_get gelesenen Zustand an. Wenn diese Anweisung ausgeführt wird, enthält die Statusvariable also den gespeicherten Status des SW_PIN-Pins. Wenn die Taste gedrückt wurde und dieser Pin mit Masse kurzgeschlossen war, wird false in die Variable geschrieben. Andernfalls nimmt die Variable den Zustand true an.
Die Variablen, die wir in dem Code verwenden können, sind recht zahlreich. Die meisten von ihnen beziehen sich auf numerische Daten, aber es gibt auch einige, in denen wir alphanumerische Zeichen und logische Zustände speichern können. Obwohl es wichtig ist, sich daran zu erinnern, dass aus technischer Sicht für den Mikrocontroller jede Variable eigentlich eine identische Folge von Einsen und Nullen ist. In unseren Codes werden wir hauptsächlich Variablen verwenden, die ganze Zahlen mit oder ohne Vorzeichen zulassen, wofür int und uint verwendet werden. Jede Variable kann 8, 16, 32 oder 64 Bits haben. Je mehr Bits, desto größer ist der Zahlenbereich, den die Variable abdeckt. Aber mehr Bits bedeuten auch mehr Speicherplatz, und dieser ist begrenzt, so dass es sinnvoll ist, so wenige Variablen wie möglich zu wählen.
- int8_t – 8-Bit Ganzzahl-Variable (-128, +127),
- int16_t – 16-Bit Ganzzahl-Variable (-16384, 16383),
- int32_t – 32-Bit Ganzzahl-Variable (-2^31, 2^31-1),
- int64_t – 64-Bit Ganzzahl-Variable (-2^63, 2^63-1),
- uint8_t – eine 8-Bit Ganzzahl-Variable ohne Vorzeichen (0, 255),
- uint16_t – 16-Bit Ganzzahl-Variable ohne Vorzeichen (0.65535),
- uint32_t – 32-Bit Ganzzahl-Variable ohne Vorzeichen (0, 2^32-1),
- uint64_t – eine 64-Bit Ganzzahl-Variable ohne Vorzeichen (0, 2^64-1).
Neben den Variablen für ganze Zahlen können wir auch zwischen dem bereits bekannten bool, char, in dem Zeichen gespeichert werden, und den Typen zum Speichern von Gleitkommazahlen – float und double – unterscheiden.
- bool – eine 8-Bit Variable für logische Zustände (true oder false),
- char – 8-Bit Variable für Zeichen (-128, +127),
- float – 32-Bit Variable für Fließkommazahlen (2^-38, 2^38-1),
- double – 64-Bit Variable für Fließkommazahlen (2^-308, 2^308-1).
if (state == true)
{
gpio_put(GREEN_LED, 1);
}
else
{
gpio_put(GREEN_LED, 0);
}
Lassen Sie uns nun das Wesentliche des oben eingefügten Codes untersuchen, nämlich die bedingte if-Anweisung. Wie ich bereits erwähnt habe, ist es damit möglich, je nach Situation nur einen bestimmten Teil des Codes auszuführen. In diesem Fall hängt “if” von den Variablen “state” ab. Sie wird dank des Operators “==” mit dem logischen Zustand true verglichen. Wenn die Variable diesen Status hat, wird der in den geschweiften Klammern stehende Befehl ausgeführt, d.h. die grüne LED wird aktiviert. Andernfalls, d.h. wenn state den Wert false hat, wird der Code in Klammern nach dem Schlüsselwort else ausgeführt. In dieser Situation wird der Pin, der der GREEN_LED zugewiesen ist, in einen Low-Zustand versetzt. So konstruieren wir die einfachste Bedingung im Code. Wenn die von der if-Anweisung beschriebene Bedingung, was auch immer sie sein mag, wahr ist, wird der Code innerhalb dieser Anweisung ausgeführt. In jedem anderen Fall führt der Mikrocontroller den Code aus, der nach dem Schlüsselwort else geschrieben wurde.
if (state == true)
{
gpio_put(GREEN_LED, 1);
}
Es ist wichtig zu wissen, dass in bedingten Anweisungen der else-Teil nicht zwingend erforderlich ist. Der Code kann möglichst nur aus einem einzigen if bestehen, in dem wir eine Bedingung prüfen, aber andere Fälle interessieren uns nicht. Im Beispielcode ist eine solche Situation jedoch unerwünscht. Wir möchten, dass der Code auf beide Zustände der Taste reagiert, also müssen wir beide Fälle beschreiben. Natürlich können weitere Bedingungen oder sogar Schleifen in bedingte Funktionen eingefügt werden, die Sie später in diesem Material kennenlernen werden.
Sobald wir wissen, wie der oben beschriebene Code funktioniert, können wir uns mit dem Startet. Nachdem Sie die .uf2-Datei in den Flash-Speicher hochgeladen haben, sollten Sie einen ähnlichen Effekt wie im Video sehen. Die LED leuchtet die ganze Zeit und geht nur aus, wenn die Taste gedrückt wird. Das mag ein wenig unintuitiv erscheinen, aber das Programm funktioniert einwandfrei. Wir wollten, dass der Zustand des GP16 sozusagen an die LED übertragen wird, und genau das passiert. Wenn die Taste nicht gedrückt wird, ist der Eingang des RP2040 frei und dank des Software-Pull-Ups auf einen High-Zustand ist dies der Zustand, der vom Programm gelesen wird. Wenn die Taste gedrückt wird, wird der Eingang mit Masse kurzgeschlossen, wodurch die Zustandsvariable in den falschen Zustand versetzt wird und die LED dann nicht leuchtet.
Sie könnten versuchen, die Funktionsweise des Programms umzukehren, so dass die Diode aktiviert wird, wenn die Taste gedrückt wird. Ich werde nur andeuten, dass dies auf zwei Arten geschehen kann, indem Sie den Code innerhalb der if- und else-Anweisung ändern oder indem Sie die Bedingung selbst ändern, auf die die if-Anweisung reagiert.
While- und do-Schleifen
#include "pico/stdlib.h"
#define GREEN_LED 0 //assigning names to specific values
#define SW_PIN 16
#define TIME 500
int main() {
gpio_init(SW_PIN); //initialization and setting of pin mode
gpio_init(GREEN_LED);
gpio_set_dir(SW_PIN, GPIO_IN);
gpio_set_dir(GREEN_LED, GPIO_OUT);
gpio_pull_up(SW_PIN); //SW_PIN pull-up to power supply
sleep_us(100); //stabilization of SW_PIN state
while (true) {
bool state = gpio_get(SW_PIN); //SW_PIN value reading
gpio_put(GREEN_LED, 0); //GP0 defaults to zero
while (state == false) //while loop with condition
{
gpio_put(GREEN_LED, 1);
sleep_ms(TIME);
gpio_put(GREEN_LED, 0);
sleep_ms(TIME);
}
}
}
Im zweiten Beispiel sehen wir uns die while-Schleife und die do while-Schleife an. Diesmal werden sie jedoch von einer Bedingung abhängen. Wir möchten, dass der Code innerhalb der Schleife nur dann ausgeführt wird, wenn die Taste gedrückt wird. Mit anderen Worten: Der Mikrocontroller wartet auf ein externes Signal, und nur wenn es empfangen wird, wird der Code aus der Schleife ausgeführt.
Der Programmcode ist dem Beispiel mit der bedingten Anweisung bemerkenswert ähnlich, aber es ging nicht ohne einige Änderungen. Die erste besteht darin, eine weitere Konstante TIME hinzuzufügen, deren Wert 500 ist. Wir werden ihn im Folgenden als Argument der Funktion sleep_ms verwenden, so dass wir diesen Wert nicht jedes Mal ausschreiben müssen. Die zweite Änderung ist das Hinzufügen des Befehls sleep_us(100) vor dem Eintritt in die while-Endlosschleife. Ich werde die Bedeutung dieses Befehls später erklären.
Im Hauptteil des Programms lesen wir den Status des SW_PIN ab und schalten die LED aus, damit der GP0-Pin immer einen niedrigen Status hat, bevor wir die nächste Schleife starten. Die nächste while-Schleife hängt vom Zustand der Variablen state ab, auch hier vergleichen wir sie mit Null. Wenn die Bedingung erfüllt ist, wird der Code in Klammern ausgeführt, der die einfache Aufgabe des Blinkens der LED ausführt. Wichtig ist, dass das Programm nach der ersten Ausführung des Codes aus der Schleife an den Anfang der Schleife zurückkehrt und die Bedingung erneut überprüft. Ändert sich also der Wert von “state” während der Ausführung des Programms innerhalb von “while”, wird die Schleife nicht erneut ausgeführt. Es ist wichtig, sich hier daran zu erinnern, dass sich der Wert der Variablen ändern muss, nicht der Zustand des SW_PIN-Eingangs. Solange wir ihn nicht erneut lesen, bleibt der Wert der Variablen unverändert.
Nachdem Sie das Programm ausgeführt haben, sollten Sie einen Effekt feststellen, der mit dem im Video identisch ist. Wenn die Taste gedrückt wird, beginnt die LED, sich synchron ein- und auszuschalten.
Ebenfalls zu erklären ist die bereits erwähnte Funktion sleep_us, die das Programm für 100μs pausiert, bevor die unendliche Haupt-While-Schleife läuft. Ihre Funktion besteht genau darin, das Programm anzuhalten, bis der Zustand der Leitung, an die der Knopf angeschlossen ist, nicht mehr stabil ist. Sie können versuchen, diesen Befehl zu kommentieren, indem Sie “//” verwenden und das Programm ausführen. Es kann dann passieren, dass beim Anschließen des USB-Kabels die LED sofort zu blinken beginnt, d.h. die Variable state hat sofort den Wert false angenommen, obwohl die Taste nicht gedrückt wurde. Das liegt daran, dass das Programm so schnell ausgeführt wird, dass die Zeit zwischen dem Lesen des SW_PIN-Status und dem Hochziehen auf einen High-Status zu kurz ist. Deshalb müssen wir eine Weile warten, bis das Signal am GP16 stabil ist.
Sie fragen sich vielleicht, ob es möglich ist, aus dieser Schleife herauszukommen, ob die LED nur einmal blinken und dann auf Null zurückkehren kann. Natürlich gibts es diese Möglichkeit und wir können dies auf zwei Arten tun.
while (state == false) //while loop with condition
{
gpio_put(GREEN_LED, 1);
sleep_ms(TIME);
gpio_put(GREEN_LED, 0);
sleep_ms(TIME);
state = true;
}
Wie ich bereits erwähnt habe, wird die Bedingung der Schleife jedes Mal überprüft, wenn der darin enthaltene Code ausgeführt wird. Bis jetzt konnten wir die Taste loslassen, aber der Wert state blieb unverändert, weil die Schleife nie die Ausführung von Codes außerhalb der Schleife zuließ. Die eingestellte Variable führte zu einer Schleife im Programm. Daher können wir versuchen, aus der Schleife herauszukommen, indem wir den Wert state innerhalb der Schleife ändern, und das ist die Anweisung, die ich in diesem Beispiel eingebaut habe. Sie setzt den state auf true und wenn die Schleife zum Start zurückkehrt, ist die Bedingung nicht mehr erfüllt. Wir kehren also zur Haupt-Endlosschleife while zurück und das Programm wartet darauf, dass die Taste erneut gedrückt wird.
while (state == false) //while loop with condition
{
gpio_put(GREEN_LED, 1);
sleep_ms(TIME);
gpio_put(GREEN_LED, 0);
sleep_ms(TIME);
break;
}
Anstatt den Wert der Variablen zu ändern, können Sie auch die Funktion break verwenden, deren Zweck genau darin besteht, den gerade ausgeführten Code zu unterbrechen. Wenn die Funktion angetroffen wird, beendet der Mikrocontroller sofort die Ausführung der Schleife und kehrt zur Funktion main zurück, unabhängig vom Wert der Variablen state. Neben der break-Anweisung ist auch der Befehl continue erwähnenswert, mit dem Sie an den Anfang der Schleife zurückkehren können. Mit anderen Worten, wenn wir sie direkt nach gpio_put(GREEN_LED, 1) platzieren, würde das Programm eine Schleife über diese Funktion laufen lassen, und dabei die bereits eingeschaltete LED einschalten.
do {
gpio_put(GREEN_LED, 1);
sleep_ms(TIME);
gpio_put(GREEN_LED, 0);
sleep_ms(TIME);
} while (state == false);
In der Sprache C können wir auch die while-Schleife verwenden, die dem bereits bekannten while ähnlich ist, mit dem Unterschied, dass hier die Schleifenbedingung am Ende steht. Dadurch wird sichergestellt, dass der Mikrocontroller den in der Schleife geschriebenen Code immer mindestens einmal ausführt. Erst nachdem er ausgeführt wurde, wird die Bedingung überprüft. Ist sie erfüllt, wird die Schleife erneut ausgeführt, andernfalls wird das Programm fortgesetzt. Beachten Sie, dass im Falle der Konstruktion do while ein Semikolon am Ende der Bedingung steht, damit der Compiler weiß, wo das Ende dieses Befehls liegt. In einer Situation, in der die Bedingung am Anfang stand, war dieses Zeichen überflüssig, denn direkt danach stieß der Compiler auf die Öffnung der geschweiften Klammer, die genau die Information über das Ende des Datensatzes und die Öffnung des Codeblocks, der Teil der Schleife war, darstellte.
Die for-Schleife
#include "pico/stdlib.h"
#define GREEN_LED 0 //assigning names to specific values
#define TIME 500
int main() {
gpio_init(GREEN_LED); //initialization and setting of pin mode
gpio_set_dir(GREEN_LED, GPIO_OUT);
for (uint8_t i = 0; i < 10; i++) //for loop
{
gpio_put(GREEN_LED, 1);
sleep_ms(TIME);
gpio_put(GREEN_LED, 0);
sleep_ms(TIME);
}
}
Die letzte Schleife, die ich Ihnen heute zeigen möchte, ist die for-Schleife. Das Programm, das wir durchführen werden, ist den vorherigen Beispielen sehr ähnlich. Wir initialisieren einen einzelnen Eingang für die grüne LED, die dank einer for-Schleife so oft blinkt, wie wir angeben.
Die Struktur der for-Funktion ist im Vergleich zu den vorherigen Schleifen etwas anders. Wir können das Innere der Klammer in drei Teile unterteilen, die durch Semikolons voneinander getrennt sind. Zunächst müssen wir eine Variable zur Steuerung der Schleife deklarieren. In diesem Fall ist es uint8_t mit dem Namen ‘i’ und dem Anfangswert Null. Eine gängige Faustregel ist die Verwendung von Variablen mit den Namen ‘i’ und ‘j’ in for-Schleifen. Als nächstes wird eine Bedingung eingefügt, die entscheidet, ob die Schleife weiter ausgeführt werden kann. In diesem Beispiel soll geprüft werden, ob ‘i’ kleiner als zehn ist. Bisher haben wir nur einen der Operatoren für den Vergleich einer Variablen mit einem anderen Wert kennen gelernt. Es war “==”, aber wir können nicht nur prüfen, ob etwas gleich ist, sondern auch, ob es kleiner (<), größer (>), kleiner oder gleich (<=) und größer oder gleich (>=) ist. Das mysteriöse i++ steht am Ende, das Äquivalent zur Notation i+1. Das bedeutet, dass nach jeder Ausführung der Schleife der Wert der Variablen ‘i’ um eins erhöht wird. Nichts hindert Sie daran, hier eine beliebige Operation zu platzieren. Sie können den Wert von ‘i’ um 4 – i+4 erhöhen oder um eins verringern. Die analoge Notation i– kann dann verwendet werden.
Lassen Sie uns nun die Schleife als Ganzes betrachten. Wenn das Programm diesen Wert erreicht, wird eine Variable ‘i’ mit einem Wert von Null erstellt und eine Bedingung überprüft, um festzustellen, ob der Wert kleiner als 10 ist. Sie ist richtig, deshalb wird der Code innerhalb der Schleife ausgeführt, d.h. die Diode wird für eine halbe Sekunde aktiviert. Nach dieser Operation kehren wir an den Anfang der Schleife zurück und erhöhen den Wert von ‘i’ um eins. Es ist immer noch weniger als 10, daher leuchtet die LED ein zweites Mal auf. Das Programm läuft und schaltet die Diode aus, bis der Wert von ‘i’ 10 erreicht. Dann ist die Bedingung nicht erfüllt und das Programm verlässt die Schleife.
Nachdem Sie den Code ausgeführt haben, sollten Sie einen Effekt wie den im Video sehen. Der LED-Blinkzyklus wird zehnmal ausgeführt, danach endet das Programm.
Wie geht man mit Problemen um?
Ich möchte in diesem Artikel ein weiteres Thema ansprechen, nämlich die Problemlösung. Für erfahrene Entwickler mag dies eine triviale Angelegenheit sein, aber die große Anzahl von Themen in Foren wie “es funktioniert nicht, Hilfe” ist meiner Meinung nach Grund genug, dieses Thema anzusprechen.
Es ist klar, dass beim Schreiben von Codes Fehler auftreten können. Eine häufige Situation, die hier als Beispiel angeführt werden kann, ist das Fehlen eines Semikolons am Ende einer Funktion. Ein Programm, bei dem diese Art von Fehler aufgetreten ist, kann nicht kompiliert werden, d.h. es funktioniert nicht. Bei diesem und vielen anderen Fehlern lohnt sich ein Blick in den Abschnitt PROBLEMS, wo Ihnen die Entwicklungsumgebung in der Regel recht genau sagt, was falsch ist. Ein solches Beispiel sehen Sie auf dem Bild oben. Ich habe das Semikolon bei der ersten sleep_ms Anweisung entfernt und nach dem Speichern des Codes ist ein einziger Fehler im Abschnitt Problems sichtbar. Schauen wir uns das mal genauer an – expected a ‘;’ C/C++(65) [Ln 15, Col 13]. Das Programm weist uns direkt darauf hin, dass das Semikolon wahrscheinlich im Code fehlt und wir das Problem in Zeile 15 des Codes suchen sollen, da dort der Fehler entdeckt wurde. Wenn wir an dieser Stelle nachsehen, stellen wir tatsächlich fest, dass in der Zeile darüber ein Semikolon fehlt und dass das Programm bei der Analyse des Codes das Ende der Anweisung an dieser Stelle nicht bemerkt hat.
Ein ähnliches Beispiel wie das Fehlen eines Semikolons, ist auch eine unbekannte Variable für VSC. Wenn wir das uint8_t aus der Klammer der for-Schleife entfernen, meldet uns das Programm, dass ihm die Variable ‘i’ unbekannt ist, was darauf hindeuten kann, dass sie nicht richtig deklariert wurde. Jede Variable muss einen Typ haben. Die Umgebung hat also korrekt erkannt, dass der Fehler in Zeile 11 aufgetreten ist, und hier sollten wir nach der Ursache für die Probleme suchen.
Die Kunst des Programmierens ist eigentlich die Kunst, Fehler zu beheben. Wenn Sie die Grundlagen so weit gelernt haben, dass Sie anfangen können, Codes zu schreiben, stoßen Sie hin und wieder auf verschiedene Fehler und Probleme. Ganz zu schweigen davon, dass bei der professionellen Programmierung die meiste Zeit mit der Fehlersuche und der Suche nach optimalen Lösungen verbracht wird. Deshalb ist es immer eine gute Idee, den Fehlercode zu überprüfen, der in der Entwicklungsumgebung angezeigt wird. Die dortigen Informationen sind in der Regel genau und selbst wenn sie Ihnen nicht direkt sagen, wo der Fehler liegt, hält Sie nichts davon ab, die Meldung in eine Suchmaschine einzugeben. In den meisten Fällen finden Sie auf den ersten Seiten im Internet die richtige Lösung. Die Suche nach Informationen und das Lösen von Problemen auf der Grundlage dieser Informationen ist meiner Meinung nach eine der wichtigsten Tätigkeiten, auf denen das Programmieren beruht. Darüber hinaus sollten Sie auch Foren im Auge behalten, die eine Gemeinschaft von Code-Enthusiasten zusammenbringen. Wenn etwas nicht funktioniert und Sie keine Idee für eine Lösung haben, können Sie die Frage genau dort stellen. Gleichzeitig sollten die Fragen so detailliert wie möglich sein, beschreiben, was Sie tun möchten, den Code hochladen und berichten, wie Sie versucht haben, das Problem zu lösen.
Ein paar Worte zum Schluss...
Im heutigen Material haben Sie so etwas wie Variablen und bedingte Anweisungen kennengelernt, und wir haben auch drei Arten von Schleifen in der Sprache C angewendet. Außerdem habe ich Ihnen etwas über Fehler erzählt und darauf hingewiesen, dass es beim Programmieren sehr stark um Problemlösungen geht, bei denen es eine äußerst nützliche Fähigkeit ist, selbst nach Informationen zu suchen. Im nächsten Artikel werden wir uns einige Mikrocontroller-Funktionen genauer ansehen, die sich unter den Begriffen PWM und ADC verbergen, und versuchen, die Kommunikation mit dem Computer herzustellen.
Quellen:
- https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf
- https://datasheets.raspberrypi.com/picow/pico-w-datasheet.pdf
- https://www.raspberrypi.com/products/rp2040/
- https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html
Wie hilfreich war dieser Beitrag?
Klicke auf die Sterne um zu bewerten!
Durchschnittliche Bewertung 4.7 / 5. Stimmenzahl: 13
Bisher keine Bewertungen! Sei der Erste, der diesen Beitrag bewertet.