
0. Bevor Sie den Artikel lesen
Dieser Artikel hat folgende Ziele:
- zeigen, wie man speziell mit diesem Board arbeitet;
- Zeigen Sie den Ansatz, mit dem Sie ein blinkendes LED-Programm schreiben können, das sich ausschließlich auf Dokumentation und Logik stützt.
- Präsentieren Sie das Material in einer Sprache, die für eine Person verständlich ist, die mit Mikrocontrollern nur wenig vertraut ist.
Der Code wird sich hinsichtlich der Verwendung zusätzlicher Dateien als minimalistisch herausstellen. Wir werden keine einzige Datei einschließen, außer denjenigen, die zum Erstellen einer leeren, aber gültigen Firmware erforderlich sind. Das heißt, basierend auf dem Firmware-Code, der funktioniert, aber nichts Nützliches tut.
Wir benötigen folgende Dokumentation:
- Datenblatt STM32F030x4 (Ich verwende das Dokument vom Januar 2017 DocID024849 Rev 3);
- RM0360 Referenzhandbuch STM32F030x4 / x6 / x8 / xC (Ich verwende das Dokument vom April 2017 DocID025023 Rev 4);
- Leiterplatte.
Sie können diese Dokumente aus der
Cloud herunterladen.
Der Timer im Artikel wird
nicht berücksichtigt und ist
nicht am Code beteiligt.
Der ST-LINK-Programmierer wurde
nicht verwendet. Für die Arbeit mit der Karte wurde ein USB-COM-Adapter (RS232 basierend auf PL2303HX) verwendet, der einen COM-Anschluss emuliert.
Alles wurde auf einer virtuellen Windows XP Professional 2002 SP3-Maschine gesammelt, die über VirtualBox Version 5.2.22r126460 auf einem Windows X-Host ausgeführt wird.
1. Installieren des Treibers für den USB-COM-Adapter
Windows ist keine Hilfe, Download von der offiziellen Website
Prolific (der erste Link zur Anfrage "produktiver Treiber" in Google) Treiber USB zu UART / Seriell / Drucker
PL2303 Windows-Treiber (Sie benötigen den
Standardtreiber ). Oder Sie können aus meiner
Cloud herunterladen.
Installieren Sie den Treiber, starten Sie ihn neu und sehen Sie den neuen COM-Anschluss.
Screenshot mit dem Namen des Installationsprogramms und dem neuen COM-Port Die Porteinstellungen wurden standardmäßig beibehalten. Sie können die COM-Portnummer nach eigenem Ermessen ändern. Nach meiner Erfahrung habe ich nur einmal in meinem Leben gesehen, dass ein Programm nur die ersten 4 COM-Anschlüsse sah. Wenn ich mich nicht irre, war es eine Art Bluetooth-Terminal unter Windows.
2. Füllen Sie die Firmware auf und von der Platine
2.0 Dienstprogramm zum Herunterladen für die Arbeit mit dem Board
Wir laden das
Dienstprogramm FLASHER-STM32 von der
STM- Website herunter (in der Beschreibung heißt es STM32 Flash Loader Demonstrator (UM0462)). Sie müssen sich dafür registrieren, aber es ist nicht beängstigend. Am Ende werden wir das Zip-Archiv mit dem Installationsprogramm löschen. Weiter-> Weiter-> Weiter ... und alles ist installiert. Der Einfachheit halber erstelle ich im Arbeitsordner eine Verknüpfung zu dieser Anwendung.
Hier ist das Dienstprogramm (Screenshot der Website) Standardmäßig der Pfad zum Dienstprogramm
C: Programme \ STMicroelectronics \ Software \ Flash Loader Demo \ STMFlashLoader Demo.exe .
2.1 BOOT-Nuance
Auf dem Board befindet sich ein BOOT-Jumper.
- Wenn der Jumper geschlossen ist , lädt der Mikrocontroller Anweisungen aus seinem Speicher (d. H. Ein von einem Programmierer geschriebenes Programm).
- Wenn der Jumper geöffnet ist , empfängt der Mikrocontroller Informationen über die RX- und TX-Leitungen, d. H. Es wird vom COM-Port (in meinem Fall vom Adapter) geflasht.
2.2 Konfigurieren des Dienstprogramms

Führen Sie diese Anwendung aus, sie ist tatsächlich die einfachste (enthält ein Minimum an Einstellungen). Wählen Sie im ersten Fenster Folgendes aus:
- Schnittstelle (ich habe COM-3);
- die Geschwindigkeit, mit der der Computer und der Mikrocontroller kommunizieren (IMHO, 9600 Normalwert);
- die Anzahl der Datenbits (aus irgendeinem Grund ist dieses Fenster für mich nicht verfügbar, aber bisher ist dies nicht wichtig);
- Parität (ich habe keine Parität, d. h. keine);
- Echo (ich habe AUS);
- Wartezeit (ich habe 10 Sekunden).
Klicken Sie auf Weiter. Wenn alles in Ordnung ist, sehen wir grünes Licht und "Ziel ist lesbar". Wenn wir ein rotes Licht sehen, konnte der Computer keine Verbindung herstellen.
Das Ziel ist lesbar, wenn der Mikrocontroller erfolgreich erkannt wurde Die Reihenfolge der Schritte, die immer helfen:
- Zunächst müssen Sie überprüfen, ob der BOOT-Jumper auf der Platine geschlossen ist.
- Zweitens schalten Sie in jedem Fall die Stromversorgung des Mikrocontrollers und vorzugsweise der TX- und RX-Leitungen aus, die vom Adapter zur Platine kommen (Sie können die Erdung nicht trennen).
- Drittens drücken Sie im Programm Zurück zum Ende, d. H. auf die erste Seite oder schließen oder sogar neu starten (im Allgemeinen friert es manchmal ein). Es ist wichtig, immer von der ersten Seite vor jeder Verbindung zur Karte über dieses Programm zu beginnen.
- Viertens, nehmen Sie die Drähte vom Adapter zur Platine und versuchen Sie erneut, eine Verbindung im Programm herzustellen (siehe auf der ersten Seite!).
Wenn alles andere fehlschlägt, können Sie versuchen, alles auszuschalten, den Computer neu zu starten und erneut eine Verbindung zur Karte herzustellen.
Weil Ich arbeite über eine virtuelle Maschine, muss den USB-COM-Adapter mehrmals neu anschließen, damit er von der virtuellen Maschine erkannt wird, und die Host-Maschine hat keine Zeit, defekte Treiber zu installieren.
Eine andere Option, die ich beim Schreiben dieses Artikels gefunden habe, ist das Drücken eines Knopfes auf der Platine, anstatt ständig an Drähten zu ziehen. Sie müssen jedoch in jedem Fall den BOOT-Jumper schließen und öffnen. Diese Option funktioniert, weil die Schaltfläche an den Fuß des externen
NRST- Resets gebracht wird.
Wählen Sie im nächsten Fenster das Ziel des Zielgeräts aus. Übrigens kann man hier manchmal das linke Gerät im Allgemeinen sehen (vielleicht einen Fehler), zum Beispiel anstelle von STM32 siehe STM8 - irgendwo, wo ein Fehler aufgetreten ist, ist das Behandlungsverfahren oben beschrieben. Daher können Sie in diesem Schritt nicht schnell auf Weiter klicken, sondern immer darauf achten, dass das gewünschte Gerät in Ziel ausgewählt ist.
Wie kann man feststellen, welches Gerät wir haben? - Wir schauen uns den Chip an und schreiben alles neu, was darauf geschrieben steht. Wir öffnen das
Datenblatt auf unserem Chip. Der Abschnitt
Bestellinformationen beschreibt, welcher Brief für was verantwortlich ist. In meinem Fall ist es:


Ich wähle meinen Chip (16K) in Target aus und gehe weiter. Es stehen 4 Aktionen mit einem Chip zur Auswahl:
- Speicher löschen (ganz oder einen bestimmten Bereich auswählen);
- Schreiben Sie Firmware auf das Gerät.
- Firmware vom Gerät lesen;
- Aktivieren / Deaktivieren des Schreib- oder Leseschutzes.
2.3 Firmware von der Karte lesen
Als ich das Board zum ersten Mal angeschlossen habe, habe ich beschlossen, die ursprüngliche Firmware beizubehalten, eine Art Backup - wir werden es jetzt tun. Es muss angegeben werden, wo diese Firmware gespeichert werden soll und welche Speicherseiten gespeichert werden sollen. Es wird auch vorgeschlagen, ein
Hex- ,
Bin- oder
S19- Dateiformat zur
Auswahl zu verwenden .
Wählen Sie die zu lesenden Speicherseiten aus Wenn Sie nur Firmware auf die Karte hochladen oder die Firmware von der Karte lesen, gibt es keinen Unterschied zwischen diesen Dateiformaten. Das Folgende ist eine Fortschrittsseite, auf der der Prozess manchmal für eine lange Zeit zu 99% einfriert (nicht unbedingt zu 99), aber nach einigen Sekunden angeblich erfolgreich abgeschlossen wird - tatsächlich hat die Karte danach nicht das Verhalten ausgegeben, das der geladenen Firmware entsprechen würde. Einfach ausgedrückt, Sie müssen alles wieder anschließen und die Firmware neu füllen. Daran ist nichts Kritisches.
Die Firmware-Datei wurde gespeichert und kann in Zukunft auf das Board hochgeladen werden.
Wenn jedoch ein Leseschutz installiert ist, kann die Firmware nicht gelesen werden.
2.4 Karte blinken lassen
Füllen Sie nun die Firmware-Datei aus, deren Quellcode unten angegeben ist. Mit Blick auf die Zukunft werde ich sagen, dass wir Bin- und
Hex- Dateien hochladen werden, weil Die Entwicklungsumgebung wird sie ausstellen. Zusätzliche Einstellungen für
s19- und
hex- Dateien sind identisch. Im Gegensatz zu ihnen können Sie in der
Bin- Datei die Adresse auswählen, von der aus die Firmware aufgezeichnet wird. Standardmäßig ist sie im Dienstprogramm 8000000 (für uns geeignet).
Vorbereitung für die Aufnahme Vor der Aufnahme können Sie den Flash-Speicher des Mikrocontrollers löschen, indem Sie eine von drei Optionen auswählen:
- Löschen Sie die erforderlichen Seiten (löschen Sie die erforderlichen Speicherbereiche).
- Kein Löschen (ohne Reinigung);
- Globales Löschen (vollständige Bereinigung).
Beim Reinigen werden Nullen in den Speicher geschrieben.
Es gibt noch optionale Bytes, aber bisher können Sie sie nicht berühren. Klicken Sie auf Weiter, warten Sie, bis der Vorgang abgeschlossen ist, und Sie sind fertig.
Wenn Sie meine Firmware aufzeichnen möchten, finden Sie sie in der Cloud, der Datei
blink.bin . Bei Verwendung dieser Firmware sollte die eingebaute LED, die vom PA4-Fuß blinkt, blinken.
3. Code schreiben
3.0 Installieren der CooCox CoIDE-Entwicklungsumgebung
Sie können die IDE von der
SoftPedia.com- Website herunterladen, bevor Sie sie von der STM-Website und von der IDE-Website selbst herunterladen können. Da die IDEs jedoch nicht mehr unterstützt werden, ist dies unmöglich geworden. Es ist nicht kritisch, dass die IDE nicht mehr unterstützt wird, nein, weil Für das Schreiben von Code ist der Compiler die Hauptsache. Ich habe beide Versionen heruntergeladen, verwende aber Version 1.7.8.
Der erste Start der Umgebung ist hier gut beschrieben, Weiter-> Weiter-> Weiter ... und nichts Kompliziertes. Ich möchte nur hinzufügen, dass es besser ist, zuerst ein Projekt zu erstellen und dann alles andere.
Wenn Sie jedoch die Registerkarte Repository verloren haben, finden Sie sie im Menü
Ansicht -> Repository .
Sie können hier Tools (Compiler) für die Umgebung herunterladen oder Google nach "gnu tools for arm" fragen. Ich habe eine Option heruntergeladen, die am Ende sha1.exe hat.
3.1 Quellframework
Also, das Projekt wurde erstellt, der Chip wurde ausgewählt, jetzt werden wir dem Projekt den Mindestsatz an Quellen hinzufügen, ohne den es überhaupt nicht leben kann.
So sollte das Projekt aussehen, wenn es gerade erstellt wird, d. H. Es gibt nur die Hauptdatei main.c und nichts weiter Wählen Sie CMSIS BOOT und die Umgebung
wählt automatisch
M0 Cmsis Core aus , weil Abhängigkeiten erfordern dies.
Jetzt erhalten wir die minimale Anzahl von Quellen Bauen Sie das Projekt zusammen (Build-Symbol oder F7-Taste). Aus mir unbekannten Gründen wurde die Hex-Datei nicht erfasst (in der Konsole befindet sich eine Warnung). Ich habe die IDE und den Compiler mehrmals neu installiert, das Projekt neu erstellt, aber aus irgendeinem Grund ein solches Ergebnis auf der virtuellen Maschine; Auf einem anderen Computer (nicht virtuell, aber real) ist alles eins zu eins und die Ausgabe funktioniert hex. Zum Glück gibt es bin.
Das Projekt wurde erfolgreich zusammengestellt Ich rate Ihnen, auf die Dateigröße zu achten, sie wird am Ende der Ausgabe in der Konsole angezeigt oder Sie können sie mit Standardmitteln anzeigen (hier können Sie übrigens sehen, dass hex leer ist). Gleichzeitig zeigt dieser Screenshot, dass sich die Firmware-Dateien im Projektordner befinden, dann Debug / bin / Obwohl der Code nichts bewirkt, lade ich ihn auf das Board hoch, um sicherzustellen, dass Sie ihn hochladen können (was beispielsweise vom Dienstprogramm nicht abgelehnt wird). Ich rate dem Leser, dies zu tun. Wenn es nicht funktioniert, versuchen Sie es immer wieder und schreiben Sie Kommentare.
3.2 Fingeralgorithmus
Zunächst skizzieren wir einen Algorithmus, wie der Mikrocontroller aus menschlicher Sicht eine LED blinkt. Und dafür eine kleine Überlegung.
Jedes Gerät arbeitet aufgrund der gespeicherten Energie. Beispielsweise können einige Motoren mit unterschiedlichen Kraftstoffarten betrieben werden. Dazu muss der Motor jedoch an die Kraftstoffart angepasst werden, mit der wir ihn versorgen werden. Ebenso muss der Mikrocontroller für die Energiequelle angepasst (abgestimmt) werden - dies ist der
erste Block des Algorithmus.
Wir argumentieren weiter. Der Desktop-Computer verfügt über einen Monitor, Lautsprecher, Tastatur, Maus ... und Sie können sehen, dass einige Geräte Informationen für uns bereitstellen, und mithilfe anderer stellen wir Informationen für den Computer bereit, aber alle sind mit einer Box verbunden, die allen gemeinsam ist (der Systemeinheit). Sie können davon ausgehen, dass der Mikrocontroller Informationen empfangen und geben kann, was bedeutet, dass seine Beine ein Signal empfangen oder ein Signal ausgeben können - dies ist der
nächste Block des Algorithmus.
Als nächstes muss der Mikrocontroller die LED einschalten, eine Weile warten, die LED ausschalten, eine Weile warten und sie einschalten - warten - ausschalten ...
Infolgedessen sieht der Algorithmus ungefähr so aus

Der Zweck dieses Flussdiagramms besteht darin, klar zu zeigen, was der Algorithmus tut. Zuallererst ist das Schema für sich selbst geschrieben, so dass jeder frei ist, es zu schreiben / zu zeichnen, wie er will (für sich selbst). Ich glaube, dass das Schema darauf abzielen sollte, so einfach, lesbar und intuitiv wie möglich zu sein und ein hohes Maß an Abstraktion zu erreichen.
In Übereinstimmung mit diesem Algorithmus werden wir Code schreiben.
3.3 Arbeiten mit Dokumentation
Ich empfehle, diesen Teil des Artikels mit der geöffneten Datei
stm32f0xx.h , die sich im Ordner
cmsis_boot unseres Projekts befindet, und der geöffneten Dokumentation zu
lesen .
3.3.1 Taktquelle auswählen
Zunächst müssen Sie den Mikrocontroller mit Strom versorgen. Der Mikrocontroller empfängt 5 Volt vom Adapter (gemessen mit einem Multimeter), aber es stellt sich die Frage, bei welcher Frequenz der Mikrocontroller arbeitet, da bekannt ist, dass die Elektronik bei verschiedenen Frequenzen arbeitet. Öffnen Sie zunächst das
Datenblatt . Im Inhalt sehen Sie zwei Abschnitte, die für die Bedeutung relevant sind:
Energieverwaltung ,
Uhren und Start . Der erste betrifft die Modi Spannung und Niedrigleistung. Der zweite Abschnitt verbirgt, woran wir gerade interessiert sind. Bereits im ersten Satz heißt es: „Der interne RC-8-MHz-Oszillator wird beim Zurücksetzen als Standard-CPU-Takt ausgewählt.“ Dies bedeutet, dass
nach dem Zurücksetzen des MC standardmäßig die interne 8-MHz-RC-Kette als
Haupttaktquelle ausgewählt wird.
Als nächstes kommt ein unverständliches Uhrbaumschema, das wir etwas später betrachten werden.
Genau genommen können Sie sich auf den Satz "Standardmäßig nach dem Zurücksetzen des MK ..." verlassen und diesen Teil des Artikels diagonal lesen.
Jetzt müssen Sie sich von der Platine ablenken lassen und nach der internen LED suchen. Ich weiß, dass die Dioden in den Schaltungen mit
D1 ,
D2 ... bezeichnet sind, d.h.
D == Diode , auf meiner Platine in der Nähe des Widerstands
R7 befindet sich die Diode
D1 .
Vielleicht können Sie nach sorgfältiger Prüfung der Platine feststellen, an welchem Bein die Diode angeschlossen ist, aber ich werde mich der Platine zuwenden. Leider stimmen die Elemente der Platine an ihrer Position nicht genau mit den Elementen in der Schaltung überein. aber ich bin froh, dass ich ein solches Schema im Internet gefunden habe (sonst konnte ich lange Zeit nichts finden).

Im Diagramm sehen wir, dass die Kathode der Diode über den Jumper
J2 mit Masse verbunden ist und die Anode über einen Widerstand mit Pin
PA4 verbunden ist.
PA4 bedeutet den 4. Ausgang von Port
A , was bedeutet, dass zum Zünden und Ausschalten der LED der Ausgang von
PA4 mit Spannung versorgt werden muss.
Als nächstes müssen Sie bestimmen, wie Spannung an diesen Ausgang angelegt wird. Für mich war dies überhaupt nicht intuitiv, und ich habe die Dokumentation lange Zeit hin und her gepflügt, bis ich auf das
Blockdiagramm im Abschnitt
Beschreibung ganz am Anfang des Datenblattes stieß. Und darin sah ich die geschätzte Spur
PA [15: 0] <=> GPIO-Port A <=> AHB-Decoder <=> Busmatrix <=> Cortex-M0 , d.h. Port
A ist ein universeller E / A-Port und mit dem
AHB- Bus verbunden.
Blockdiagramm(Bild ist anklickbar)

Ich stelle fest, dass es in der Elektronik üblich ist, die Ausgänge des Mikrocontrollers in Ports zu unterteilen, und normalerweise hat der Port 16 Ausgänge. Das Diagramm zeigt, dass die Ports
A ,
B und
C nur 16 haben, die Ports
D und
F jedoch weniger (weniger als 16 Pins können mehr sein - nein).
Kehren wir zum Taktbaumschema zurück und suchen die von
AHB signierte Ausgabe. Wir werden herausfinden, mit welcher Frequenz dieser Ausgang funktioniert. Zum
AHB gehört das
HCLK- Signal, das den
HPRE- Teiler verlässt. Dieser Teiler empfängt das
SYSCLK- Signal von der Schalter-
SW . Welches der Signale am
SW- Eingang verwendet wird, wenn
SYSCLK programmgesteuert eingestellt wird - dann setzen wir dies im Code. Die Auswahl wird angeboten:
- HSI - ein Signal von einem internen Hochfrequenzgenerator, das von einem 8-MHz-Quarzresonator erzeugt wird, den ich vor der Arbeit mit dieser Platine gelötet habe;
- PLLCLK - Signal vom Frequenzvervielfacher PLLMUL ;
- HSE - Signal von einem externen Hochfrequenzgenerator.
Jede Option ist für unsere Aufgabe geeignet. Ich schlage vor, die einfachste und kostengünstigste
auszuwählen -
HSI .
Wir gehen in das
Referenzhandbuch und öffnen Abschnitt
7 Reset und Clock Control (RCC) , insbesondere
7.2.6 Auswahl der Systemuhr , wo wir erneut auf einen ähnlichen Wortlaut im Datenblatt stoßen: „Nach einem System-Reset wird der
HSI- Oszillator als System ausgewählt Uhr "- d.h. Wir müssen nicht einmal etwas tun, MK wird mit
HSI beginnen .
Um sicherzustellen, dass MK wirklich von dieser Quelle aus funktioniert, werde ich dies explizit in das Programm schreiben. Scrollen Sie zu den Registern, die für das Zurücksetzen und Takten verantwortlich sind (Abschnitt
7.4 RCC-Register ). Das erste in der Dokumentation beschriebene
Register ist das Taktsteuerregister (RCC_CR) ; Unten finden Sie eine Beschreibung der Bits, die für was verantwortlich sind.
Wir interessieren uns für das
HSION- Nullbit, das für das Einschalten des Resonators verantwortlich ist (
0 - aus,
1 - ein).
Daher muss eine in das
RCC_CR- Register geschrieben werden. (Nullbit ist Eins oder 2
0 = 1).
Jetzt finden wir in der Datei
stm32f0xx.h die Definition von
RCC (
#define RCC ).
Wie Sie sehen können, ist dies die Struktur in
RCC_BASE . Adresse
0x40021000 Wenn Sie alle
Definitionen erweitern , finden Sie dieselbe Adresse im
Referenzhandbuch in Abschnitt
2.2.2 Speicherzuordnungs- und Registergrenzadressen sowie im Datenblatt in Abschnitt
5 Speicherzuordnung (
AHB- Bereich).
Um eine Einheit zur Aktivierung von
HSI in das
CR- Register des
RCC- Blocks zu schreiben, benötigen Sie eine Codezeile
RCC->CR |= 0x1;
3.3.2 Beine einstellen
Das Senden eines Signals an den Mikrocontroller-Zweig zum Zünden der LED und zum Stoppen des Signals, damit die LED erlischt, sind einfache Aktionen. Daher bezieht sich dies auf die
GPIO- Funktionen (Allzweck-Eingangs- / Ausgangsanschlüsse).
Standardmäßig sind die MK-Beine nicht verbunden, d.h. Die Ausgabe ist Unsicherheit. Es ist erforderlich, einen Anschluss anzuschließen, dessen Schenkel die LED mit Strom versorgt. Zuvor haben wir festgestellt, dass die
GPIO- Ports mit dem
AHB- Bus verbunden sind. Sie müssen diesen Bus taktisieren. Wenn wir weiter durch Abschnitt
7.4 RCC-Register (Reset- und Steuersteuerregister)
blättern , finden wir Abschnitt
7.4.6 AHB-Peripherietakt-Aktivierungsregister (
RCC_AHBENR ,
AHB -
Bustakt-Aktivierungsregister ). Zuvor habe ich festgestellt, dass meine LED mit dem
PA4-Zweig verbunden ist.
Dementsprechend muss ich eine Einheit in das 17. Bit des Registers schreiben, um Port
A anheften zu können
.AHB-Peripherietakt-Aktivierungsregister Dementsprechend sollte der Code sein
RCC->AHBENR |= (1 << 17);
oder, was das gleiche ist
RCC->AHBENR |= 0x20000;
entweder mit der
#define Datei
stm32f0xx.h schreiben
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
Wir haben Port
A mit Strom versorgt. Jetzt müssen wir MK darüber informieren, dass
PA4 beim
Beenden funktioniert. Wir lesen Abschnitt
8 Allzweck-E / A (GPIO) . In der Einleitung des Abschnitts heißt es bereits: "Jeder universelle E / A-Port verfügt über vier 32-Bit-Konfigurationsregister (
GPIOx_MODER ,
GPIOx_OTYPER ,
GPIOx_OSPEEDR und
GPIOx_PUPDR ), zwei 32-Bit-Datenregister (
GPIOx_IDR und
GPIOx_ODR ) ..." -
für jedes GPIO Es gibt 4 Tuning-Register und 2 Datenregister im Port - das ist es, was wir brauchen (konfigurieren Sie Port
A oder besser
PA4- Ausgang und senden Sie regelmäßig
0 und
1 an ihn ). Zum besseren Verständnis (Theorie) des Geschehens können Sie diesen Abschnitt lesen, aber ich scrolle nach unten zu Abschnitt
8.4 GPIO-Register und konfiguriere den Port gemäß den Beschreibungen.
- Port- Modus - Beenden. In Übereinstimmung mit der Dokumentation ist es notwendig, 01 in den entsprechenden Bereich ( MODER4 ) des entsprechenden Registers ( GPIOA_MODER ) zu schreiben, d. H. Bits 9 und 8 : im 9. Bit sollte Null sein, in der 8. Einheit:
GPIOA->MODER |= (1 << 8); //
GPIOA->MODER |= 0x100; //
GPIOA->MODER |= GPIO_MODER_MODER4_0;
- Art der Ausgabe. Ehrlich gesagt habe ich die Schaltkreise dieses Falls noch nicht vollständig herausgefunden (ich werde verstehen, die Foren erneut lesen usw.), aber das Studium anderer Ressourcen zur Konfiguration des MK-Ausgangs sowie der Logik und Intuition legt nahe, dass es einen Push geben sollte -Ziehen und danach sollte hochgezogen werden . In jedem Fall ist der Code geschrieben, alles funktioniert und nichts ist ausgebrannt. Es besteht echte Verbrennungsgefahr, wenn Sie den Open-Drain- Typ auswählen und diesen Ausgang mit einem anderen Gerät kurzschließen, z Dies ist ein offener Ausgang und durch nichts geschützt. Zusätzlich haben wir einen Strombegrenzungswiderstand vor der Diode - er wird hier sicherlich nicht brennen.
Nach der Dokumentation muss im 4. Bit Null geschrieben werden. Die Dokumentation besagt auch, dass nach dem Zurücksetzen Null sein wird.
GPIOA->OTYPER &= ~(1 << 4); //
GPIOA->OTYPER &= ~0x10; //
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_4;
GPIO-Port-Ausgangstypregister
- Ausgangsgeschwindigkeit. In unserem Fall spielt es keine Rolle, aber der Treue halber werde ich hier Null schreiben.
GPIOA->OSPEEDR &= ~(1 << 8); //
GPIOA->OSPEEDR &= ~0x100; //
GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR4_0;
GPIO-Port-Ausgangsgeschwindigkeitsregister
- ein Aufzug . Weil Der Ausgang versorgt die LED mit Strom. Sie müssen ihn auf Strom bringen, d. h. Klimmzug .
Der 4. Stift von Anschluss A muss festgezogen werden. Die Dokumentation besagt, dass dazu Null und Eins in 9 bzw. 8 Bit geschrieben werden müssen.
GPIOA->PUPDR |= (1 << 8); //
GPIOA->PUPDR |= 0x100; //
GPIOA->PUPDR |= GPIO_PUPDR_PUPDR4_0;
Pull-Up / Pull-Down-Register für GPIO-Ports
3.3.3 LED ein / aus und Verzögerung
Zuvor haben wir gelesen, dass jeder Port Register hat, einschließlich
IDR- und
ODR -Datenregister - Eingangs- bzw. Ausgangsdatenregister. Logische Nullen und Einsen auf dem MK-Bein - sind das Daten? - Ja, Daten. Daten können von außerhalb des Mikrocontrollers kommen (
eingegeben werden ) und den Mikrocontroller verlassen und zu einem anderen Gerät gehen (
ausgegeben werden ). Die Einheit auf dem MK-Bein ist das Vorhandensein eines Hochspannungspegels, d.h. Wenn Sie eine an den Ausgang bringen, liegt Spannung an, und diese LED kann unsere LED mit Strom versorgen. Die Ausgabe einer Einheit an den Mikrocontroller-Zweig ist etwas anderes als das Schreiben dieser Einheit in das
ODR- Ausgangsregister.
GPIO-Port-Ausgangsdatenregister Der Dokumentation zufolge sehen wir jedoch für jeden Port (
A ,
B ,
C ,
D ,
F ) ein 32-Bit-Register. Der Port kann nicht mehr als 16 Pins haben, dann werden nur die ersten 16 Bits des Registers verwendet. Jedes Bit entspricht einer Portnummer (Pin). Um eine Einheit an den
PA4-Zweig auszugeben, muss man eine Einheit in das 4. Bit schreiben, um eine Null auszugeben - schreibe eine Null in das 4. Bit, d.h. Entfernen Sie die Spannung vom Ausgang.

Der Code zum Einschalten der LED sieht folgendermaßen aus
GPIOA->ODR |= (1 << 4); //
GPIOA->ODR |= 0x10; //
GPIOA->ODR |= GPIO_ODR_4;
Code zum Ausschalten der LED
GPIOA->ODR &= ~(1 << 4); //
GPIOA->ODR &= ~0x10; //
GPIOA->ODR &= ~GPIO_ODR_4;
Wenn Sie jedoch die Zeile zum Ausschalten der LED nach der Zeile zum Einschalten schreiben, blinkt die LED nicht (wenn Sie daran interessiert sind, was passiert - Sie können es versuchen; es wird nichts brennen, dies wurde bereits oben erläutert) - müssen Sie eine Verzögerung vornehmen. Timer werden für Verzögerungen verwendet, aber Timer sind aufgrund der Komplexität eines separaten Artikels würdig, sodass wir eine Krückenverzögerung durchführen: Wir fahren den Leerlaufzyklus. Es gibt einen Punkt:
Wenn die Compileroptimierung aktiviert ist , wird der
Compiler unseren Leerlaufzyklus unterbrechen und es wird keine Verzögerung geben. Stellen Sie sicher, dass die Optimierung nicht aktiviert ist. Gehen Sie dazu in die Projektkonfiguration (klicken Sie mit der rechten Maustaste auf den Projektnamen in der Projektstruktur) und überprüfen Sie die Zeile
Compile Control String auf der Registerkarte
Compile : Sie muss das Argument
-O0 haben („ungefähr Null“ bedeutet, dass die Optimierung deaktiviert ist). Wenn Sie alles gemäß meinen Anweisungen gesammelt haben, haben Sie höchstwahrscheinlich auch
-O0 , weil Es war standardmäßig und ich habe hier nichts angefasst. Die Argumente
-O1 -O2 -O3 bedeuten, dass die Optimierung der entsprechenden Ebene aktiviert ist.
Compiler-Optimierungsprüfung Ein Leerlaufzyklus kann folgendermaßen geschrieben werden:
int t = 4000000; while(t > 0) t--;
Ich habe den Wert von
t nicht als solchen festgelegt. Ich habe Folgendes begründet: Wenn der Mikrocontroller mit 8 MHz läuft, führt er ungefähr 8.000.000 Anweisungen in einer Sekunde aus. Wenn Sie stark übertreiben, müssen Sie den Zyklus für eine halbe Sekunde Verzögerung 4.000.000 Mal ausführen.
Der Leerlaufzyklus muss nach dem Einschalten der LED und nach dem Ausschalten ausgeführt werden.
3.4 Code schreiben und ausführen
Lassen Sie uns alle Codezeilen zusammenstellen, die wir zuvor geschrieben haben. Sie müssen auch die Header-Datei
stm32f0xx.h als wir haben uns darauf verlassen und daraus Definitionen von Strukturen, Adressen und Werten abgeleitet. Das Ergebnis sollte sein:
#include "stm32f0xx.h" int main(void) { int t; // '' RCC->CR |= 0x1; // HSI RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // A GPIOA->MODER |= GPIO_MODER_MODER4_0; // PA4 GPIOA->OTYPER &= ~GPIO_OTYPER_OT_4; // push-pull PA4 GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR4_0; // PA4 GPIOA->PUPDR |= GPIO_PUPDR_PUPDR4_0; // pull-up PA4 while(1) { GPIOA->ODR |= GPIO_ODR_4; // PA4 t = 4000000; while(t > 0) t--; // GPIOA->ODR &= ~GPIO_ODR_4; // PA4 t = 4000000; while(t > 0) t--; // } }
Klicken Sie auf Neu erstellen und geben Sie den Code auf der Karte über das Dienstprogramm ein.

Vergessen Sie nicht, den BOOT-Jumper zu schließen und einen Reset (RESET) durchzuführen, damit die Karte eine neue Firmware startet.
4. Fazit
Der Code ist geschrieben, alles funktioniert. Kräfte verbrauchten ungemessen. Ich bin froh, dass sich aufgrund der Dokumentation herausgestellt hat, dass Arbeitscode geschrieben wurde, hauptsächlich aufgrund der Tatsache, dass STM über eine qualitativ hochwertige Dokumentation verfügt.
Es ist geplant, einen Artikel darüber zu schreiben, wie man alles von Hand ohne IDE über die Konsole,
echte Oldschool , zusammenbaut, idealerweise, damit all dies unter Linux möglich ist. Jetzt arbeite ich an PWM und ADCs (auch auf diesem Board) - ich werde auch einen Artikel darüber schreiben.