Hinweise zu Arduino
Als Ergänzung zu meiner STM32 Anleitung gebe ich hier Tipps zum Umgang mit Arduino.
Die Arduino richtet sich primär an Bastler, die schnelle Ergebnisse wollen. Das Framework vereinheitlicht die Programmierung unterschiedlicher Mikrocontroller-Boards, so weit es geht. Auf diese Weise kann man nicht alle Funktionen der Mikrocontroller nutzen, allerdings hindert Arduino niemanden daran, das Ding teilweise am Framework vorbei zu programmieren. Ein großer Vorteil ist die Verfügbarkeit zahlreicher Bibliotheken.
Wenn du im Internet etwas für STM32duino findest, musst du zwischen dem aktuellen STM32duino Core von ST und dem alten STM32duino Core von Roger Clarks unterscheiden. Sie sind nur teilweise kompatibel.
STM32duino Core von ST
Für diesen STM32duino Core muss dein Mikrocontroller mindestens 32 KiB Flash und 8 KiB RAM haben. Nimm besser ein größeres Modell.
Falls du mit STM32duino programmieren möchtest, kannst du so anfangen:
- Installiere die aktuelle Arduino IDE
- Gehe ins Menü Datei/Voreinstellungen. Gebe ins Feld "Zusätzliche Boardverwalter-URLs" die Adresse
https://github.com/stm32duino/
BoardManagerFiles/raw/main/ package_stmicroelectronics_index.json ein. - Gehe ins Menü Werkzeuge/Board/Boardverwalter um die "STM32 MCU based boards" von STMicroelectronics zu installieren.
Lies die Dokumentation von ST (auch das Wiki) und die Dokumentation von Arduino.
Für den Upload werden folgende Adapter direkt unterstützt: ST-Link, Black Magic Probe und DAPLink. Zusätzlich unterstützt die IDE auch J-Link und Bootloader (seriell und USB), wenn der STM32CubeProgrammer installiert ist.
Debuggen geht aber nur mit ST-Link.
Taktfrequenz
Der Code für die generischen Boards und für Nucleo Boards nutzt standardmäßig den internen HSI Oszillator, keinen Quarz. Andere Boards mit Quarz benutzen den HSE Oszillator. Alle Boards werden mit der höchstmöglichen Taktfrequenz betrieben, die sich daraus ergibt. Das ist in der Regel gleich der maximalen Taktfrequenz der CPU.
Aber nicht immer. Als Negativ-Beispiel picke ich den alten STM32F103 heraus:
- Das Blue-Pill Board läuft mit 72 MHz (HSE mit Quarz und PLL).
- Das Nucleo-F103 Board läuft mit 64 MHz (HSI und PLL), mehr als 64 MHz geht nicht mit dem internen Oszillator.
- Das generische Board läuft normalerweise ebenfalls mit 64 MHz (HSI und PLL). Aber wenn USB aktiviert ist, dann sind es nur 48 MHz, weil die USB Schnittstelle nur mit 48 oder 72 MHz getaktet werden kann und mit dem internen Oszillator keine 72 MHz erreichbar sind.
An dieser Stelle möchte ich erwähnen, dass die internen Oszillatoren nur in Kombination mit dem "Clock Recovery System" (CRS) für USB taugen. Dabei wird die Taktfrequenz an den Host (PC) angeglichen. Der STM32F103 hat aber kein CRS!
`F_CPU` ist als Alias für die Variable `SystemCoreClock` definiert, die mit der tatsächlichen Taktfrequenz der CPU initialisiert wird.
Um die Taktfrequenz zu ändern soll man die Funktion `SystemClock_Config()` überschreiben. Darin kannst du wahlweise direkte Registerzugriffe oder LL/HAL Bibliotheken benutzen. Beachte dabei die notwendige Prozedur aus dem Referenzhandbuch des STM32, einschließlich dem "voltage scaling" (falls vorhanden) und den "wait states" für den Flash Speicher.
// Change system clock to 32 MHz
void SystemClock_Config(void) {
... model specific code
SystemCoreClock=32000000;
SysTick_Config(SystemCoreClock/1000);
}
Zum Stromsparen bieten sich eher die Befehle `__WFI()` und `__WFE()` aus dem Power Management, sowie die STM32LowPower Bibliothek an. Oft ist "schnell rechnen und schlafen" effizienter als "langsam dauerhaft laufen".
Serielle Ports
In der Board-Konfiguration taucht der Begriff "generic serial" auf, damit ist die Variable `Serial` gemeint. Wenn sie aktiviert ist, dann verweist sie auf den bevorzugten seriellen Port des Boardes. Beim Nucleo64 Board ist `Serial=Serial2`, weil USART2 mit dem ST-Link Adapter verbunden ist.
Für die anderen Ports muss man selber Instanzen von `HardwareSerial` anlegen. Welche Pins dazu geeignet sind, steht im Datenblatt des Mikrocontrollers. Kopiervorlage:
HardwareSerial Serial1(PA10,PA9);
HardwareSerial Serial2(PA3,PA2);
HardwareSerial Serial3(PB11,PB10);
HardwareSerial Serial4(PC11,PC10);
HardwareSerial Serial5(PD2,PC12);
void setup() {
Serial1.begin(115200);
Serial2.begin(115200);
Serial3.begin(115200);
Serial4.begin(115200);
Serial5.begin(115200);
}
Virtueller COM Port
Der virtuelle COM Port über USB (auch VCP oder CDC genannt) ist unter dem Namen `SerialUSB` nutzbar, sofern in der Board-Konfiguration aktiviert. Zusätzlich kann der "generic serial" darauf referenzieren, dann ist `Serial=SerialUSB`. Die Einstellung der Baudrate kann entfallen, weil sie keine Rolle spielt.
Das folgende Beispiel lässt die LED an PA5 blinken und gibt dabei abwechselnd die Worte "Tick" und "Tack" aus:
void setup() {
pinMode(PA5, OUTPUT);
}
void loop() {
digitalWrite(PA5, LOW);
SerialUSB.println("Tick");
delay(500);
digitalWrite(PA5, HIGH);
SerialUSB.println("Tack");
delay(500);
}
Die Ausgabe kann man mit dem seriellen Monitor oder einem Terminal-Programm anzeigen. Sie findet nur statt, wenn das DTR Signal (im Terminalprogramm) eingeschaltet ist. Es sei denn, man ruft vorher `SerialUSB.dtr(false)` auf, dann wird das DTR Signal ignoriert.
Bitte beachte meinen Hinweis zu CDC Geräten unter Linux, er erspart dir womöglich eine langwierige Fehlersuche.
Historische Informationen
Das Arduino Framework begann 2005 mit kleinen 8 Bit AVR Mikrocontrollern als Fork von Wiring (die ganze hässliche Story).
Die ersten inoffizellen 32 Bit Boards kamen 2009 von der Firma Leaflabs: Das "Maple" Board und das kleinere "Maple Mini", beide mit STM32F103C8T6. Leaflabs musste dazu einen anderen Compiler und eigene Bibliotheken in die Arduino IDE integrieren. Kurz danach kam das ähnliche Blue Pill Board auf den Markt, das heute noch angeboten wird.
Das erste "offizielle" 32 Bit Board von Arduino war das Arduino Due von 2012. Dieses Board wurde von den Makern weitgehend ignoriert, vielleicht weil es viel zu teuer ist. Erst 2015 nahmen die offiziellen 32 Bit Boards mit dem Arduino Zero langsam Fahrt auf.
Als Leaflabs den Produktsupport für die Maple Boards im Jahr 2016 beendete, übernahm Roger Clarks wesentliche Teile des Codes in sein STM32duino Projekt. Er hielt damit die Unterstützung für die STM32F103 am Leben. Der Compiler vom Arduino Due Board unterstützt auch STM32, so dass Roger diesen Compiler nun mit benutzen konnte. Dan Drown hat den Code von Roger Clarks so verpackt, dass man ihn bequem mit dem Boardmanager der IDE installieren kann.
Im Jahr 2018 übernahm die Firma ST die Rechte am Namen "STM32duino" und schrieb den Code auf Basis des Cube HAL Frameworks um. So konnte ST schnell fast alle STM32 Modelle unterstützen. Die damit erzeugten Programme sind größer und etwas langsamer als mit dem alten Code.
STM32duino Core von Roger Clarks
So installierst du den alten STM32duino Core von Roger Clarks:
- Installiere die alte Arduino IDE Version 1.8.x, aber noch nicht starten
- Erstelle im Verzeichnis der Installation ein leeres Unterverzeichnis mit dem Namen "portable"
- Jetzt die IDE starten.
-
Gehe ins Menü Datei/Voreinstellungen. Gebe ins Feld "Zusätzliche Boardverwalter-URLs" die Adresse
http://dan.drown.org/stm32duino/
package_STM32duino_index.json ein. -
Gehe ins Menü Werkzeuge/Board/Boardverwalter um die folgenden beiden Cores in dieser Reihenfolge zu
installieren:
- Arduino SAM Boards (32Bits ARM Cortex-M3) by Arduino (enthält den benötigten Compiler).
- STM32F1xx/GD32F1xx boards by stm32duino.
Lies die Dokumentation von Roger Clarks und die Dokumentation von Arduino.
Beim STM32duino Core von Roger Clarks ist das `Serial` Objekt ein virtueller COM Port über den USB Anschluss des Mikrocontrollers. Für die echten seriellen Schnittstellen (USART) gibt es die Objekte `Serial1, Serial2` und `Serial3`.
Die Pins PA13, PA14, PA15, PB3 und PB4 sind standardmäßig für die ungenutzte JTAG Schnittstelle reserviert. Das kann man so ändern:
void setup() {
// Disable both SWD and JTAG to free PA13, PA14, PA15, PB3 and PB4
afio_cfg_debug_ports(AFIO_DEBUG_NONE);
or:
// Disable JTAG only to free PA15, PB3 and PB4. SWD remains active
afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY);
}
Dieser Arduino Core basiert nicht auf dem CMSIS, daher heißen dort die Konstanten für die Register und
Bitmasken etwas anders. Werfe dazu ggf. einen Blick in die Dateien
packages/stm32duino/
Für den Upload werden folgende Adapter unterstützt: ST-Link, J-Link, Black Magic Probe,
USB-UART (Serieller Bootloader), USB (STM32duino Bootloader).
Der STM32duino Bootloader ist nur eine Sekunde lang nach dem Loslassen des Reset-Knopfes aktiv. Dies
zeigt er durch schnelles Blinken der Status-LED an. Innerhalb dieser kurzen Zeit kann man mit der
Arduino IDE einen Sketch hochladen. Im Gerätemanager von Windows erscheint der Bootloader als
"libusb-win32 devices/Maple DFU". Nach einer Sekunde verschwindet er wieder, danach erscheint der
virtuelle serielle COM Port des Sketches.
Wegen des schwierigen Timings finde ich den Bootloader unhandlich und benutze ihn nicht gerne.
Damit Windows den USB Bootloader wie gezeigt erkennt, braucht es einen Treiber aus
dem Arduino_STM32 Paket.
Führe zur Installation die Datei drivers/win/STM32duino Bootloader
Für einige STM32F103 Boards steht der
STM32duino Bootloader zur
Verfügung, der das Hochladen von Programmen über den USB Anschluss des Mikrocontrollers ermöglicht.
Er belegt die ersten 8 KiB vom Flash Speicher.
Für das Blue Pill Board ist die Datei
generic_boot20_pc13.bin
die richtige.