Inhaltsverzeichnis:

Sie laden also den STM32duino-Bootloader in Ihre "Blaue Pille" Was nun? - Gunook
Sie laden also den STM32duino-Bootloader in Ihre "Blaue Pille" Was nun? - Gunook

Video: Sie laden also den STM32duino-Bootloader in Ihre "Blaue Pille" Was nun? - Gunook

Video: Sie laden also den STM32duino-Bootloader in Ihre
Video: Программирование STM32 Blue Pill с помощью релейной логики ПЛК LDmicro 2024, Juli
Anonim
Sie laden also den STM32duino Bootloader in Ihr
Sie laden also den STM32duino Bootloader in Ihr
Sie laden also den STM32duino Bootloader in Ihr
Sie laden also den STM32duino Bootloader in Ihr

Wenn Sie bereits meine Anleitungen gelesen haben, in denen erklärt wird, wie der STM32duino-Bootloader oder eine andere ähnliche Dokumentation geladen wird, versuchen Sie, ein Codebeispiel zu laden und … möglicherweise passiert überhaupt nichts.

Das Problem ist, dass viele, wenn nicht alle Beispiele für "Generic" STM32 nicht sofort funktionieren. Es werden geringfügige Änderungen erforderlich sein, damit Ihr STM32 "Blue Pill"-Board funktioniert.

Ich werde 4 Codebeispiele auswählen, um zu erklären, was geändert werden muss und warum. Codes sind: "BlinkWithoutDelay", "Fading", "Dimmer" und "AnalogInSerial".

Beachten Sie, dass ich nichts codiert habe. Ich gebe nur geringfügige Änderungen in Codes aus, die erstellt wurden von:

David A. Mellis und spät modifiziert von Tom Igoe, Marti Bolivar und einigen Fällen von Scott Fitzgerald

Tom Igoe und spät modifiziert von Bryan Newbold

Daher ziehe ich es vor, die Autorennamen auch in Codes, die ich ändere, beizubehalten, um den Kreationskredit zu behalten.

Schritt 1: Pins und Pins…. Warum funktioniert der Code nicht?

Pins und Pins…. Warum funktioniert Code nicht?
Pins und Pins…. Warum funktioniert Code nicht?

Werfen wir einen Blick auf die Pinbelegung von STM32 "Blue Pill". Beachten Sie, dass die Pins als PA1 oder PC2 identifiziert werden … so ähnlich.

Wenn Sie sich beispielsweise das Codebeispiel "BlinkWithoutDelay" ansehen, wird Pin als "33" deklariert…. Warum?

Ich vermute, das liegt daran, dass Mr. Marti Bolivar diesen Code für das MAPLE-Board portiert hat.

Ich denke, es war nicht seine Absicht, Code zu "Blue Pill"-Boards kompatibel zu machen.

Maple- und Maple-Mini-Board-Pins werden wie Arduino numerisch deklariert, obwohl sie Zahlen wie 33, 24 und einige wie diese verwenden.

Ich sagte, dass der Code nicht funktioniert? Mein Fehler. Code ohne Fehler kompilieren und korrekt auf "Blue Pill" hochladen, also meiner Meinung nach funktioniert es tatsächlich, aber mit einer GPIO-Ausgabe erwarten wir nicht. Möglicherweise nicht einmal verfügbar.

Es sind also nur wenige Änderungen am Code erforderlich, damit er wie erwartet funktioniert.

Schritt 2: Lassen Sie uns einige Pins "definieren"

Lasst uns
Lasst uns

Es ist eine gute Codepraxis, Ressourcen als leicht zu identifizierende oder bedeutungsvolle Variablen oder Konstanten zu deklarieren. Es wird Ihnen helfen, Code leichter zu verstehen und zu beheben.

Ich habe Arduino-Pins wie folgt deklariert:

const int ledPin = 13;

…"

Wenn Sie mich mögen, fragen Sie sich vielleicht: "Wie kann ich Pins mit Namen wie PC13 deklarieren???"

Die Antwort lautet: Verwenden Sie die C-Anweisung "#define".

Laut Pinout-Zeichnung ist PC13 also der Pin, den wir an Bord der LED in "BluePill" haben. Um es zu verwenden, würde ich wie folgt deklarieren, direkt nach der Bibliotheksdefinition (#include…) und vor allem anderen:

#define LedPin PC13

…"

Beachten Sie, dass KEIN ";" Leitungsabschluss, NOR "=" Zuweisung.

Vergleichen Sie beide Codes. Eines ist das ursprüngliche Beispiel, das von der IDE geladen wurde. Zweitens habe ich einige Anpassungen vorgenommen, um mit "BluePill" zu arbeiten.

Ich empfehle dringend, alle Pins zu deklarieren, die Sie im Code verwenden möchten. Auch diese beabsichtigen, als ADC-Eingang zu verwenden (dazu später mehr).

Dies wird Ihr Leben einfacher machen.

Schritt 3: PinMode () … Wie Sie Ihre Pins verwenden …

Bevor Sie fortfahren, lassen Sie uns die Funktion PinMode() verstehen.

Wie Arduino haben STM32-Pins mehrere Funktionen. Die einfachste Möglichkeit, das eine oder andere auszuwählen, ist die Verwendung der pinMode()-Anweisung.

Arduino hat nur 3 verfügbare Modi, INPUT, OUTPUT oder INPUT_PULLUP.

STM32 hingegen hat viele Varianten von pinMode(). Sie sind:

AUSGANG - Einfacher digitaler Ausgang: Wenn der Pin HIGH ist, wird die Spannung auf +3,3 V (Vcc) gehalten und wenn er LOW ist, wird sie auf Masse gezogen

OUTPUT_OPEN_DRAIN – Im Open-Drain-Modus zeigt der Pin „Low“an, indem er Stromfluss zur Masse akzeptiert, und „High“, indem er eine erhöhte Impedanz bereitstellt

INPUT_ANALOG - Dies ist ein spezieller Modus, wenn der Pin für analoge (nicht digitale) Lesevorgänge verwendet wird. Ermöglicht die Durchführung einer ADC-Umwandlung an der Spannung am Pin

INPUT_PULLUP – Der Zustand des Pins in diesem Modus wird auf die gleiche Weise wie bei INPUT gemeldet, aber die Pinspannung wird sanft in Richtung +3,3 V „hochgezogen“

INPUT_PULLDOWN - Der Zustand des Pins in diesem Modus wird auf die gleiche Weise wie bei INPUT gemeldet, aber die Pinspannung wird sanft in Richtung 0 V „heruntergezogen“

INPUT_FLOATING -Synonym für INPUT

PWM - Dies ist ein spezieller Modus, wenn der Pin für die PWM-Ausgabe verwendet wird (ein Sonderfall der digitalen Ausgabe)

PWM_OPEN_DRAIN -Wie PWM, außer dass anstelle von abwechselnden Zyklen von LOW und HIGH die Spannung am Pin aus abwechselnden Zyklen von LOW und Floating (getrennt) besteht

(Hinweis: extrahiert aus

Ich öffne nur diese Klammer, denn wenn Sie anfangen, Ihren eigenen Code zu erstellen, achten Sie darauf, den richtigen pinMode() für Ihre Bedürfnisse zu verwenden.

Schritt 4: AnalogWrite() versus PwmWrite()…Analogausgabe in 2 Geschmacksrichtungen

AnalogWrite() im Vergleich zu PwmWrite()…Analogausgabe in 2 Geschmacksrichtungen
AnalogWrite() im Vergleich zu PwmWrite()…Analogausgabe in 2 Geschmacksrichtungen
AnalogWrite() im Vergleich zu PwmWrite()…Analogausgabe in 2 Geschmacksrichtungen
AnalogWrite() im Vergleich zu PwmWrite()…Analogausgabe in 2 Geschmacksrichtungen

Vor der Verwendung von "Blue Pill" GPIO-Pins ist es notwendig, ihr Verhalten zu deklarieren, d.h. wie es funktioniert. Genau das macht die Funktion pinMode().

Konzentrieren wir uns nun darauf, wie ein analoger Ausgang richtig eingestellt wird. Er kann entweder als OUTPUT-Modus oder als PWM-Modus deklariert werden.

Auf die gleiche Weise können analoge Werte auf 2 Arten GPIO zugeordnet werden: analogWrite () oder pwmWrite (), ABER, analogWrite () funktioniert nur, wenn pinMode () = OUTPUT. Auf der anderen Seite funktioniert pwmWrite() nur, wenn pinMode()=PWM.

Nehmen wir zum Beispiel PA0: Es ist ein Kandidat für einen analogen/pwm-Ausgang.

analogWrite(): dies deklariert so:

….

#define ledPin PA0

pinMode (ledPin, AUSGANG);

analogWrite (ledPin, <Nummer>);

……"

wobei die Zahl zwischen 0 und 255 liegen muss, wie bei Arduino. Eigentlich ist es abwärtskompatibel zu Arduino.

pwmWrite(): deklariere so:

#define ledPin PA0

PinMode (ledPin, PWM);

pwmWrite(ledPin, <Nummer.>);

…."

Wobei die Zahl zwischen 0 und 65535 liegen muss, eine viel höhere Auflösung als bei Arduino.

In Bildern ist es möglich, zwischen 2 Codes zu vergleichen. Sie können auch den Originalcode sehen.

Schritt 5: STM32 Serielle Kommunikation

Serielle STM32-Kommunikation
Serielle STM32-Kommunikation

Sehen wir uns an, wie die USART-Schnittstellen in STM32 angeordnet sind. Ja, Schnittstellen im Plural…..

"Blue Pill" hat 3 USARTs (RX/TX 1~3), und wenn Sie einen Bootloader verwenden, der Ihnen die Verwendung von USB ermöglicht, ist es an keines davon angeschlossen.

Je nachdem, ob Sie USB verwenden oder nicht, müssen Sie den seriellen Port auf die eine oder andere Weise in Ihrem Code deklarieren.

Fall 1: Verwendung von USB:

Auf diese Weise werden Skizzen direkt über USB heruntergeladen. Es ist nicht erforderlich, den BOOT0-Jumper auf Position 1 und zurück auf 0 zu verschieben.

In diesem Fall bedeutet jedes Mal, wenn Sie "Seriell" ohne Index angeben, eine Kommunikation über USB.

Serial1 bedeutet also TX/RX 1 (Pins PA9 und PA10); Serial2 bedeutet TX/RX 2 (Pins PA2 und PA3) und Serial 3 bedeutet TX/RX 3 (Pins PA10 und PA11).

So arbeiten wir. Ich werde Änderungen in Beispielen für diese Art der Codierung vorstellen.

Eine andere Sache: "Serial USB" muss nicht initialisiert werden. Mit anderen Worten: "…Serial.begin(15200);" ist nicht nötig.

Es ist möglich, jede Serial-Funktion (Serial.read(), Serial.write() usw.) ohne Initialisierung aufzurufen.

Wenn es aus irgendeinem Grund im Code vorhanden ist, wird es vom Compiler ignoriert.

Fall 2: Verwenden des TTL-Serien-zu-USB-Adapters:

Auf diese Weise unterstützt der Bootloader keine native STM32-USB-Kommunikation, daher benötigen Sie einen USB-zu-Seriell-Adapter, der an TX/RX 1 (Pin PA9 und PA10) angeschlossen ist, um Skizzen hochzuladen.

In diesem Fall bedeutet "Seriell" ohne Index immer TX/RX1 (Port, der zum Hochladen des Codes verwendet wird). Also weiter, Serial1 bezieht sich auf TX/RX 2 (Pins PA2 und PA3) und Serial2 bezieht sich auf TX/RX 3 (Pins PA10 und PA11). Kein Serial3 verfügbar.

Schritt 6: Übergeben eines Werts an den Mikrocontroller

Einen Wert an den Mikrocontroller übergeben
Einen Wert an den Mikrocontroller übergeben

Das Dimmer-Beispiel ist eine einfache Möglichkeit, zu zeigen, wie ein Wert an den Mikrocontroller übergeben wird.

Es soll einen Wert von 0 bis 255 übergeben, um die LED-Helligkeit zu steuern.

Es wird NICHT wie erwartet in Blue Pill funktionieren, da:

  1. Um die Funktion pwmWrite() verwenden zu können, MUSS pinMode() als PWM-Modus deklariert werden.
  2. Sie werden nie eine ganze 3-stellige Zahl bekommen. Die Funktion Serial.read () erfasst nur den Pufferinhalt, der ein "BYTE" ist. Wenn Sie "100" eingeben und "Enter" drücken, werden nur die letzten "0" aus dem Puffer erfasst. Und sein Wert ist "48" (dezimaler ASCII-Wert für "0"). Wenn Sie den Wert "100" ausgeben möchten, müssen Sie "d" eingeben. Es ist also richtig zu sagen, dass ein ASCII-Symbol-Dezimalwert in LED-Helligkeit umgewandelt wird, oder??…. Nun, eine Art…
  3. Problem, Map-Werte direkt aus der Serial.read()-Funktion ist eine Trickaktion. Es ist fast sicher, unerwartete Werte zu erhalten. Ein besserer Ansatz ist es, den Inhalt des Speicherpuffers in einer temporären Variablen zu speichern und ihn DANN abzubilden.

Wie ich zuvor in Punkt 2 erkläre, ermöglichen Code, den ich einführe, die Eingabe eines ASCII-Symbols und dies steuert die LED-Helligkeit basierend auf ihrem ASCII-Dezimalwert … zum Beispiel ist "Leerzeichen" Wert 32 (tatsächlich ist das niedrigste druckbare Zeichen, das Sie eingeben können). und "}" ist möglich das höchste (Wert 126). Andere Zeichen sind nicht druckbar, so dass das Terminal es nicht versteht oder es sich möglicherweise um eine Zeichenkombination handelt (wie "~" ist eine tote Taste auf meiner Tastatur und funktioniert nicht richtig). Dies bedeutet, dass dieses zusammengesetzte Zeichen, wenn es in das Terminal eingegeben wird, das Zeichen selbst und etwas anderes sendet. Normalerweise ein nicht druckbares. Und dieser letzte Code wird erfasst. Denken Sie auch daran, dass Ihr Terminal in diesem Fall weder "Carriage Return" noch "Line Feed" senden sollte. Dies müssen Sie beachten, damit der Code korrekt funktioniert.

Wenn Sie fallen, ist es wenig verwirrend, es wird schlimmer…..

Schritt 7: Und wenn ich drei Ziffern eingeben möchte…. oder noch mehr??

Und wenn ich drei Ziffern eingeben möchte…. oder noch mehr??
Und wenn ich drei Ziffern eingeben möchte…. oder noch mehr??

Das Empfangen mehrerer Zeichen aus einer seriellen Kommunikation ist keine einfache Aufgabe.

Serieller Puffer ist ein FIFO-Byte-Haufen von Zeichen. Jedes Mal, wenn die Serial.read()-Funktion aufgerufen wird, wird das erste gesendete Zeichen vom Stapel entfernt und an einem anderen Ort gespeichert. Normalerweise eine char-Variable im Code. Beachten Sie, dass es abhängig von der Hardware normalerweise eine Zeitüberschreitung gibt, wie der Protokollpuffer Informationen speichern kann.

Wenn Sie mehr als eine Ziffer seriell eingeben möchten, müssen Sie eine Zeichenfolge Zeichen für Zeichen "zusammensetzen", wenn sie in den UART-Puffer gelangen.

Dies bedeutet, dass zyklisch jedes Pufferzeichen gelesen, in einer temporären Variablen gespeichert, an der ersten Position eines String-Arrays geladen, zur nächsten Position bewegt und von vorne begonnen wird, bis … nun, hängt von der Anwendung ab. Es gibt 2 Möglichkeiten, den Zyklus zu beenden:

  1. Verwenden eines "Endzeichens" wie "Wagenrücklauf" oder "Zeilenvorschub". Sobald das Zeichen "end Mark" gefunden wird, endet die Schleife.
  2. Alternativ kann die Anzahl der Zeichen in der String-Kette begrenzt werden, ebenso die Anzahl der interaktiven Zyklen. Wenn es die Grenze erreicht, sagen wir 4, wird die Routine von selbst beendet.

Schauen wir uns in einem einfachen Beispiel an, wie das geht:

  • Legen Sie ein "End"-Zeichen wie '\n' fest (dies bedeutet Zeilenvorschub-ASCII-Zeichen).
  • Schleife währenddessen Serial.available () ist wahr
  • Das Speichern von Serial.read() führt zu einer temporären char-Variablen. Denken Sie daran: Sobald Serial.read() den Puffer tatsächlich "liest", ist er sauber und das nächste Zeichen wird darin geladen.
  • inkrementiere eine String-Variable mit diesem Zeichen
  • Wenn das letzte Zeichen "end" ist, verlassen Sie die Schleife.

Normalerweise sieht die Routine zum Abrufen des seriellen Zeichenarrays wie ein Bild aus.

Es basierte auf einer umfangreichen Adaption des Originalcodes von Mr. David A. Mellis.

Fühlen Sie sich frei, es zu verwenden und zu testen. Denken Sie daran: Werte MÜSSEN im 3-stelligen Format eingegeben werden.

Dies ist es für den Moment. Ich werde mich nicht in zusätzliche Details der seriellen Kommunikation vertiefen. Es ist zu komplex, um es hier zu behandeln, und es verdient seine eigenen Intructables.

Ich hoffe, es hilft Ihnen bei der Verwendung von Beispielen in Blue Pill und gibt Ihnen Aufschluss darüber, wie der Code für dieses kleine Board korrekt ist.

Wir sehen uns in anderen anweisbaren.

Empfohlen: