1.1 Einstieg in Arduino für STM32
Forum der STM32 Boardleute: https://www.stm32duino.com
Anleitung für MacOS
Arduino Software laden und installieren.
Unter Voreinstellungen zusätzliche Boardverwalter-URL eingeben damit die Erweiterung gefunden wird:
Das Kopieren und einfügen: https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json
Arduino-IDE NEU Starten => Dann wird Eintrag unter Voreinstellungen erst aktiv!
DANN In den Boardverwalter gehen und STM32 MCU based borads installieren
Werkzeuge => Board => Boardverwalter => STM32 => Installieren
Das richtige Board auswählen:
Werkzeuge => Board => STM32 boards => Nucleo-64
Den richtigen Chip auswählen
Werkzeuge => Board part number => Nucleo 152RE
Einstecken des Nucleo zum Programmieren
Wie bei Arduino gewohnt:
Werkzeuge => Port => COM ??? –Nein!
Unter MacOS wird das Board als Volume eingebunden.
Die Software wird auf das erscheinende externe Laufwerk NODE_L152RE kopiert.
Upload method: “Mass Storage” auswählen.
Nicht 😭 wenn der Mac beim Upload über nicht richtig ausgeworfene Volumes 🤬.
Testprogramm
#define BOARD_LED D13 // grüne LED auf dem Board
void setup(){ // Einmalige Ausführung => Initialisierungen...
pinMode(BOARD_LED, OUTPUT); // Pin als Ausgang schalten
}
void loop(){
digitalWrite(BOARD_LED, HIGH);// High ausgeben
delay(200); // warte 200ms
digitalWrite(BOARD_LED, LOW); // Low ausgeben
delay(200); // warte 200ms
}
Erläuterungen
Die grüne LED auf dem Board ist an D13 angeschlossen, damit im Quelltext statt D13 das aussagekräftigere Board_LED verwendet werden kann lässt man mit #define Board_LED D13 den Präprozessor (Textverarbeitung vor dem Compiler) alle Vorkommen des Textes Board_LED durch den Text D13 ersetzen.
Im setup() werden alle Initialisierungen beim Programmstart oder nach einem Reset durchgeführt.
Bevor ein Pin als Ausgang verwendet werden kann muss er als Ausgang definiert werden: pinMode(Board_LED, OUTPUT) stellt die Hardware so ein, dass D13 als Ausgang funktioniert.
Die loop()-Funktion wird endlos ständig wiederholt.
Anleitung für Windows
Ausgeben und Einlesen von Werten über den seriellen Monitor
Arduino-Doku zur seriellen Schnittstelle Serial. Zur besseren Lesbarkeit der Ausgaben wird printf verwendet:
#define BOARD_LED D13 // grüne LED auf dem Board
char empfangByte = 0; // für empfangenes Byte
void setup(){ // Einmalige Ausführung => Initialisierungen...
pinMode(BOARD_LED, OUTPUT); // Pin als Ausgang
Serial.begin(9600); // Serielle Schnittstelle starten und Baudrate festlegen
}
void loop(){
digitalWrite(BOARD_LED, HIGH); // LED einschalten
Serial.println("an"); // Ausgabe auf Seriellen Monitor
delay(1000); // 1s warten
digitalWrite(BOARD_LED, LOW); // LED ausschalten
Serial.println("aus"); // Ausgabe auf Seriellen Monitor
delay(1000); // 1s warten
Serial.printf("Analogwert: %4d\n",analogRead(A0)); // AD-Wert ausgeben von A0
if(Serial.available()>0){ // wurde was empfangen?
empfangByte = Serial.read(); // lies ein Byte
Serial.printf("Ich empfing: %3d 0x%2x %c\n",empfangByte,empfangByte,empfangByte);
}
}
Pin-Namen des Chips verwenden statt Arduino-Bezeichnungen
Der µC hat viel mehr Pins als bei den Arduino-Anschlüssen verwendet werden, dazu müssen die Bezeichnungen des Chips verwendet werden.
void setup(){ // Einmalige Ausführung => Initialisierungen...
pinMode(PC0, OUTPUT); // PC0 als Ausgang
pinMode(PC1, OUTPUT); // PC1 als Ausgang
pinMode(PC2, OUTPUT); // PC2 als Ausgang
pinMode(PA1, INPUT_PULLDOWN); // PA1 als Eingang mit Pulldown einschalten
}
void loop(){
digitalWrite(PC2,digitalRead(PA1)); // PA1 einlesen und auf PC2 ausgeben
digitalWrite(PC0, HIGH); // PC0 <- 1
delay(300); // warte 300ms
digitalWrite(PC0, LOW); // PC0 <- 0
digitalWrite(PC1, HIGH); // PC1 <- 1
delay(300); // warte 300ms
digitalWrite(PC1, LOW); // PC1 <- 0
}
Ok, könnte man es auch über die I/O-Register direkt hin kriegen?
void setup(){ // Einmalige Ausführung => Initialisierungen...
Serial.begin(115200);
RCC->AHBENR |= (1<<2); // Enable the GPIOC clock
GPIOC->MODER = 0x5555; // PC0..PC7 als Ausgang
GPIOC->ODR = 0xff; // PC0..PC7 einschalten
Serial.printf("GPIOC->MODER: %4x\n",GPIOC->MODER);
pinMode(PA1, INPUT_PULLDOWN); // PA1 als Eingang mit Pulldown
Serial.printf("GPIOA->MODER: %4x\n",GPIOA->MODER); // PinMode
Serial.printf("GPIOA->PUPDR: %4x\n",GPIOA->PUPDR); // PullUpMode
}
void loop(){
digitalWrite(PC0, HIGH); // PC0 <-1
digitalWrite(PC1, LOW); // PC1 <-0
delay(200);
// ohne Arduino Watte
GPIOC->ODR &=~1; // PC0 <-0
GPIOC->ODR |=2; // PC1 <-1
delay(200);
if(GPIOA->IDR & 0b10){ // wenn PA1
GPIOC->ODR |= (1<<2); // setzte PC2
}
else{ // sonst
GPIOC->ODR &= ~(1<<2); // lösche PC2
}
// mit Arduino Watte
digitalWrite(PC3,digitalRead(PA1)); // PC3 <- PA1
}
Ohne Umverpackung direkt auf der Hardware des Chips agieren geht auch mit Arduino in diesem Beispiel.
Einmal muss pinMode() aufgerufen werden sonst funktioniert GPIOC->MODER nicht.
Ergänzender Link: Introduction to GPIO