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:
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
}
void loop(){
digitalWrite(Board_LED, HIGH); //Output Bitwise High
delay(200); //Wait...
digitalWrite(Board_LED, LOW); //Output Bitwise High
delay(200); //Wait...
}
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
char empfangByte = 0; // für empfangenes Byte
void setup(){ // Einmalige Ausführung => Initialisierungen...
pinMode(Board_LED, OUTPUT); // Pin als Ausgang
Serial.begin(115200); // Serielle Schnittstelle starten und Baudrate festlegen
}
void loop(){
digitalWrite(Board_LED, HIGH); //Output Bitwise High
Serial.println("an"); // Ausgabe auf Seriellen Monitor
delay(1000); //Wait...
digitalWrite(Board_LED, LOW); //Output Bitwise LOW
Serial.println("aus");
delay(1000); //Wait...
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
Kann ich auch die Bezeichnungen des Chips benutzen ohne die Ummodelung durch Arduino?
Ja, das geht, die Bezeichnungen des Chips sind verfügbar.
void setup(){ // Einmalige Ausführung => Initialisierungen...
pinMode(PC0, OUTPUT); // PC0 als Ausgang
pinMode(PC1, OUTPUT);
pinMode(PC2, OUTPUT);
pinMode(PC3, OUTPUT);
pinMode(PA1, INPUT_PULLDOWN); // PA1 als Eingang mit Pulldown einschalten
}
void loop(){
digitalWrite(PC2,digitalRead(PA1)); // PA1 auf PC2 ausgeben
digitalWrite(PC0, HIGH); //Output Bitwise High
delay(300); //Wait...
digitalWrite(PC0, LOW); //Output Bitwise High
digitalWrite(PC1, HIGH); //Output Bitwise High
delay(300); //Wait...
digitalWrite(PC1, LOW); //Output Bitwise High
}
Bonus: Ports direkt adressieren
Wäre es nicht schön, in einer Schleife viele Pins bequem initialisieren zu können? Leider geht das nicht so einfach, da hinter den Bezeichnern eine wirre Zuordnung zu Werten steckt, zur besseren Lesbarkeit wird printf verwendet:
void setup(){ // Einmalige Ausführung => Initialisierungen...
Serial.begin(115200);
Serial.printf("PC0: %d\n",PC0);
Serial.printf("PC1: %d\n",PC1);
Serial.printf("PC2: %d\n",PC2);
Serial.printf("PC3: %d\n",PC3);
Serial.printf("PC4: %d\n",PC4);
Serial.printf("PC5: %d\n",PC5);
Serial.printf("PC6: %d\n",PC6);
Serial.printf("PC7: %d\n",PC7);
}
void loop(){
}
Ok, könnte man es auch über die I/O-Register direkt hin kriegen?
Ja, Anleitungen gibt es z.B.: STM32 GPIO OUTPUT Config using REGISTERS und STM32 GPIO INPUT Configuration
Mit diesen Erkenntnissen ein wenig HardCore-Code:
void setup(){ // Einmalige Ausführung => Initialisierungen...
Serial.begin(115200);
pinMode(PC0, OUTPUT); // ohne diese Zeile klappts nicht
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