Forum: Mikrocontroller und Digitale Elektronik STM32G0xx Timer Interrupt


von Obelix X. (obelix)


Lesenswert?

Ersteinmal die Facts:
Customboard mit STM32G07KB programmiert mit PlatformIO und geflasht mit 
STLINK v2. Das Board tut aber eigentlich auch nichts zur Sache, wenn ich 
das Programm für den "bluepill_f103c6" compiliere bekomme ich die 
gleiche Fehlermeldung.

Ich habe schon eine Weile im Internet gesucht aber keine passende Lösung 
gefunden. Es geht nur um eine Demo in der ein Interruppt-Routine 
aufgerufen wird die von Timer TIM2 ausgelöst wird. Mit anderen MCUs habe 
ich schon einiges gemacht aber bei den STM32 bin ich Anfänger.

Ich bin zum Beispiel nach folgendem Tutorial vorgegangen:
https://hackmd.io/@0xff07/Sy8U-l7Ec

Hier mein Code-Ausschnitt
1
#include <stm32g071xx.h>
2
#include <stm32g0xx_hal.h>
3
#include <stm32g0xx_hal_rcc.h>
4
#include <stm32g0xx_hal_usart.h>
5
#include <stm32g0xx_hal_tim.h>
6
#include <stm32g0xx_hal_tim_ex.h>
7
8
static TIM_HandleTypeDef my_tim2;
9
10
void timerInit() 
11
{
12
  __TIM2_CLK_ENABLE();
13
  my_tim2.Instance = TIM2;  // siehe oben
14
  my_tim2.Init.CounterMode = TIM_COUNTERMODE_DOWN;
15
  my_tim2.Init.Prescaler = 64000;
16
  my_tim2.Init.Period = 50000;
17
  my_tim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
18
  my_tim2.Init.RepetitionCounter = TIM_AUTORELOAD_PRELOAD_DISABLE; // for PWM mode
19
  my_tim2.Channel = HAL_TIM_ACTIVE_CHANNEL_1;
20
  HAL_TIM_Base_Init(&my_tim2);
21
  HAL_TIM_Base_Start(&my_tim2);
22
}

Bis dahin funktioniert auch alles. In der main.cpp lese ich den 
Zählerwert periodisch aus und gebe ihn aus. Um jetzt den Interrupt 
hinzuzufügen  ändere ich
1
HAL_TIM_Base_Start(&my_tim2);
zu
1
HAL_TIM_Base_Start_IT(&my_tim2);

Dann hält das Programm an wenn der Timer bei 0 angekommen ist. 
Wahrscheinlich ganz klar weil ich noch keine Interrupt Routine 
gwschrieben habe. Also noch
1
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 
2
{
3
  if (htim == &my_tim2) {
4
    i++;
5
  }
6
}

hinzugefügt. Aber da bekomme ich die Compiler/Linker Fehlermeldung:

"main.cpp:(.text.HAL_TIM_PeriodElapsedCallback+0x0): multiple definition 
of `HAL_TIM_PeriodElapsedCallback'; ... 
SrcWrapper/src/HardwareTimer.cpp.o:HardwareTimer.cpp: 
.text.HAL_TIM_PeriodElapsedCallback+0x0): first defined here"

Ich verstehe das eigentlich so, im HAL-Driver ist diese Funktion als 
"weak" gekennzeichnet und es sollte meine Funktion verwendet werden.

Was mache ich falsch?

: Bearbeitet durch User
von Wastl (hartundweichware)


Lesenswert?

Obelix X. schrieb:
> Ich verstehe das eigentlich so, im HAL-Driver ist diese Funktion als
> "weak" gekennzeichnet und es sollte meine Funktion verwendet werden.

Ich verstehe das so dass deine Umgebung (PlatformIO) die Callback-
Funktion bereits implementiert hat und du nur das Ganze nochmals
tust. Das ist natürlich nicht hilfreich. Ich folgere das aus der
Zeile
1
SrcWrapper/src/HardwareTimer.cpp.o:HardwareTimer.cpp

Aber ich kann mich täuschen ....

Wenn du PlatformIO nicht verwenden würdest sondern die ganz
normale CubeIDE oder Atollic Studio dann könnte dir leichter
geholfen werden. Zumindest aus meiner Sicht. Denn eine andere
IDE die nach eigenem Gusto ein Framework á la Arduino bereit-
stellt bin ich nicht bereit zu unterstützen oder auch nur
anzuschauen.

Ja, nicht sehr hilfreich, aber vielleicht kommt jemand anderes
daher der was mit PlatformIO am Hut hat.

von Obelix X. (obelix)


Lesenswert?

Danke für deinen Kommentar. Es ist natürlich klar, das man sich nicht 
mit jeder IDE auskennt. Da ich auch anderen MCUs nutze und viele Open 
Source Projekte Platform IO nutzen, nutze ich das auch und ich möchte 
auch dabei bleiben.

Wastl schrieb:
> Denn eine andere
> IDE die nach eigenem Gusto ein Framework á la Arduino bereit-
> stellt

PlatformIO ist aber auch sehr flexibel und ich habe mal probiert, als 
framework nicht "arduino" auszuwählen, sondern "stm32cube" (Es mussten 
noch ein paar Dinge mehr angepasst werden). Und schon läuft der Compiler 
ohne Fehler durch.

Ich probiere noch ein bissl rum. Wenn ich neue Infos habe, kann ich sie 
hier mitteilen aber ich bin auch weiterhin an Infos von euch 
interessiert.

von Obelix X. (obelix)


Lesenswert?

Was habe ich heraus gefunden : Arduino und HAL beißt sich.

Bei Adruino als Framework wird die HardwareTimer.h/.cpp verwendet in 
diesen Dateien ist die Funktion "HAL_TIM_PeriodElapsedCallback" 
deklariert. Deswegen die Fehlermeldung des Compilers. Unter Arduino muss 
also die Klasse "HardwareTimer" verwendet werden. Der Code sind dann so 
aus :
1
HardwareTimer *MyArduinoTim = new HardwareTimer(TIM2);
2
3
void myArduinoCollback(void) {
4
  i++;
5
}
6
7
void timerInit() {
8
  MyArduinoTim->setMode(1, TIMER_DISABLED);
9
  MyArduinoTim->setPrescaleFactor(64000);
10
  MyArduinoTim->setOverflow(50000);
11
  MyArduinoTim->attachInterrupt(myArduinoCollback);
12
  MyArduinoTim->resume();
13
}

So funktioniert es.

https://github.com/stm32duino/Arduino_Core_STM32/wiki/HardwareTimer-library

: Bearbeitet durch User
von Obelix X. (obelix)


Lesenswert?

Wastl schrieb:
> Ich verstehe das so dass deine Umgebung (PlatformIO) die Callback-
> Funktion bereits implementiert hat und du nur das Ganze nochmals
> tust. Das ist natürlich nicht hilfreich. Ich folgere das aus der
> ZeileSrcWrapper/src/HardwareTimer.cpp.o:HardwareTimer.cpp

Ich hatte übersehen, dass sie quasi 3 mal implementiert ist.
1. In der stm32g0xx_hal_tim als weak markiert (sollte also nicht genutz 
werden wenn noch eine Funktion implementiert ist)
2. Meine eigene
3. Die bei Arduino die ich nicht beachtet hatte.

Also Danke nochmal für die Hinweis.

von Obelix X. (obelix)


Angehängte Dateien:

Lesenswert?

Oben habe ich den Arduino weg per PlatformIO beschrieben. Wie schon 
beschriben wollte ich die CubeIDE nicht verwenden aber fast alle 
Tutorial verwenden Cube. Man sieht also immer nur das die Funktion 
"MX_TIM2_Init();" Aufgerufen wird aber nicht was dort konfiguriert wird 
bzw. wie der Interrupt für den Timer funktioniert.

Desweg hier im Anhang der PlatformIO Weg mit "stm32cube" als framework.

Auf diesem Weg können sich dann wahrscheinlich die PlatformIO User und 
die Cube User gegenseitig helfen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.