Forum: Mikrocontroller und Digitale Elektronik STM32 Timer2 Interrupt


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Hans M. (anno)


Lesenswert?

Hallo,

ich versuche einen Interrupt auf Timer 2 zu legen, damit TIM2_IRQHandler 
aufgerufen wird. Das funktioniert mit dem Code aber leider nicht.

Hat jemand eine Idee, was ich initialisieren und welche Methoden ich 
noch aufrufen muss?

Aktuell verwende ich einen STM32F401CE. Die LED toggelt im Interval von 
1 sec., die funktioniert soweit.
1
#include <Arduino.h>
2
#include "IWatchdog.h"
3
4
  /* Set TIMx instance */
5
  TIM_HandleTypeDef Tim2Handle;
6
 
7
/**
8
 * Blaue LED initialisieren
9
*/
10
void InitBlueLed()
11
{
12
   __HAL_RCC_GPIOC_CLK_ENABLE();
13
  GPIO_InitTypeDef BoardLEDs;
14
  BoardLEDs.Mode = GPIO_MODE_OUTPUT_PP;
15
  BoardLEDs.Pin = GPIO_PIN_13;
16
  HAL_GPIO_Init(GPIOC, &BoardLEDs);
17
 
18
}
19
20
static void InitTimer2(void)
21
{
22
  Tim2Handle.Instance = TIM2;
23
24
Tim2Handle.Init.Period = 32;
25
Tim2Handle.Init.Prescaler = 2500;
26
Tim2Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
27
Tim2Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
28
Tim2Handle.Init.RepetitionCounter = 0;
29
Tim2Handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
30
31
// Timer & Interrupt initialisieren
32
HAL_TIM_Base_Init(&Tim2Handle);
33
HAL_TIM_Base_MspInit(&Tim2Handle);
34
35
HAL_TIM_Base_Start(&Tim2Handle);
36
HAL_TIM_Base_Start_IT(&Tim2Handle);
37
38
__HAL_RCC_SYSCFG_CLK_ENABLE();
39
  __HAL_RCC_PWR_CLK_ENABLE();
40
41
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
42
HAL_NVIC_EnableIRQ(TIM2_IRQn);
43
}
44
45
/**
46
 * Interrupt an Timer 2
47
*/
48
void TIM2_IRQHandler(void)
49
{
50
    // Interrupt triggered
51
    if (TIM2->SR & TIM_SR_UIF) 
52
    {
53
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
54
    }
55
    
56
     HAL_TIM_IRQHandler(&Tim2Handle);
57
}
58
59
int main()
60
{
61
  HAL_Init();
62
  SystemClock_Config();  
63
  InitBlueLed();
64
  InitTimer2();
65
66
67
int state = 0;
68
69
  while (1)
70
  {
71
    // LED toggeln
72
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
73
    
74
    HAL_Delay(1000);
75
  }
76
77
  return 0;
78
}

: Bearbeitet durch User
von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Angehängte Dateien:

Lesenswert?

In welcher IDE schreibst Du das überhaupt? Sieht auf den ersten Blick 
irgendwie wie eine Mischung aus Arduino und HAL.

Vorab vielleicht noch das: war das Deine Idee, den PC13 für das Toggeln 
der LED zu nehmen oder ist das irgendwo original so angeschlossen und 
verbaut? Mit der Timergeschichte hat das natürlich nichts zu tun, ich 
erwähne das aber, weil das vom Hersteller plausibel erklärt und 
untersagt wird: PC13, PC14 und PC15 sind an einen Switch gekoppelt und 
man sollte diese Pins nicht für stromhungrige Aufgaben – wie z.B. 
LED-Blink-Experimente – nehmen; im Anhang der entsprechende Auszug aus 
dem Datenblatt. Das gilt mindestens auch für den STM32F411RE. Auf dem 
Nucleo Board, wo der verbaut ist, ist an PC13 der User-Button mit einem 
Pull-Up angeschlossen – das ist gerade noch so akzeptabel, weil hier 
nicht viel Strom fließen kann. Schaltplanauszug auch im Anhang.

Ich benutze für die STM32 die STM32CubeIDE – lasse mir aber nur das 
Minimum initialisieren und mache alles andere dann explizit auf der LL- 
und Registerebene selbst, insbesondere bei den Timern weiß man dann ganz 
genau, was passiert, weil man die Register selbst beeinflusst. Wenn man 
den Timer richtig initialisiert, die Interruptpriorität einstellt, den 
Interrupt einschaltet und den Timer startet [!], dann funktioniert es 
auch wie gewünscht. Du müsstest Deinen Code selbständig debuggen und 
z.B. schauen, ob die CPU überhaupt in den Tim2_IRQHandler reinspringt. 
Wenn NEIN, ist etwas nicht richtig initialisiert oder eingeschaltet 
worden. Wenn JA, dann ev. diese IF-Abfrage auskommentieren, aber den 
Togglebefehl selbst normal stehen lassen, damit ohne IF getoggelt werden 
kann und am Ende das Flag gelöscht wird. Vielleicht wird in Deinem Code, 
der hier ja nicht sichtbar ist, der Clock für den Timer2 nicht 
aktiviert, dann läuft dieser Timer auch nicht. Im F411RE ist das im 
Register RCC_APB1ENR, in HAL müsste aber auch eine explizite Anweisung 
dafür existieren, die könntest Du testweise vor dem Tim2-Init und ev. 
auch danach aufrufen – das muss man sich dann im HAL-F4-Datenblatt 
heraussuchen, nennt sich 'HAL and LL drivers STM32F4' (UM1725 User 
Manual). Für Timer2-Start gibt es in HAL möglicherweise auch ein 
Äquivalent zu meiner LL-Anweisung – muss man auch dort nachschauen.

Hinzu kommt noch, dass Deine Interruptfrequenz vermutlich so hoch 
gewählt worden ist, dass man das Toggeln der LED, sofern es überhaupt 
liefe, gar nicht sehen würde, sondern die LED einfach mit einer 
geringeren Helligkeit leuchten würde, quasi so eine PWM angesteuert mit 
50% – das ist aber nur eine Vermutung, da hier leider nicht ersichtlich 
ist, mit welcher Frequenz Tim2 überhaupt getaktet wird. Also im Main das 
Toggeln auskommentieren und die Tim2-Parameter ändern, um mit der 
Interruptfrequenz entsprechend runterzugehen und es erstmal überhaupt 
sehen und debuggen zu können. Auch Deine Reihenfolge der Befehle könnte 
möglicherweise nicht richtig sein, denn die zwei NVIC-Zeilen sollten 
normalerweise vor dem Tim2-Init stehen und nicht danach, aber vielleicht 
ist das in HAL anders als in LL; die Clock-Enable-Anweisung in LL muss 
jedenfalls auf jeden Fall zuerst erfolgen.
1
void TIM3_IRQHandler(void)
2
{
3
  (...)
4
  LL_TIM_ClearFlag_CC1(TIM3);
5
}
6
7
void MX_TIM3_Init(void)
8
{
9
  (...)
10
11
  /* Peripheral clock enable */
12
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
13
14
  (...)
15
  
16
  /* TIM3 interrupt Init */
17
  NVIC_SetPriority(TIM3_IRQn, 0);
18
  NVIC_EnableIRQ(TIM3_IRQn);
19
}
20
21
(...)
22
23
LL_TIM_EnableCounter(TIM3); // [!] - Timer starten

: Bearbeitet durch User
von Andreas B. (abm)


Lesenswert?

Was soll "einen Interrupt auf Timer 2 zu legen" denn heißen???
Bei welchem Ereignis soll denn überhaupt ein Interrupt ausglöst werden?
Da gäbe es TIE, CC4IE, CC3IE, CC2IE, CC1IE, UIE zur Auswahl des/der
Ereigniss(e).

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.