Forum: Mikrocontroller und Digitale Elektronik STM32 HAL und interrupt


von rudolf (Gast)


Lesenswert?

Guten Tag,
ich möchte mit den STM32F103 anfangen und habe eine Grundsatz Frage 
nicht verstanden.
Im Referenzmanual steht das die Interrupt Vektoren sammel Vektoren sind 
und das das entsprechende Interrupt Flag gelöscht werden muss.
Wenn ich mir mit Cube Mx Code erzeuge und Zb den Timer 2 verwende wird 
in der stm32f1xx_it.c erzeugt
1
void TIM2_IRQHandler(void)
2
{
3
  /* USER CODE BEGIN TIM2_IRQn 0 */
4
5
  /* USER CODE END TIM2_IRQn 0 */
6
  HAL_TIM_IRQHandler(&htim2);
7
  /* USER CODE BEGIN TIM2_IRQn 1 */
8
  static uint16_t time;
9
  if (++time==500)
10
  {
11
    HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
12
    time=0;
13
  }
14
  /* USER CODE END TIM2_IRQn 1 */
15
}

Nun der Ausgang Pin macht was er tun soll obwohl ich das Interrupt Flag 
nicht lösche.
Dann gibt es noch
1
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
Auch diese Funktion macht das was ich mir erwarte.
Bitte bringt mir etwas Licht in diesen Junggel

DAnke
Rudolf

von STM Apprentice (Gast)


Lesenswert?

rudolf schrieb:
> Bitte bringt mir etwas Licht in diesen Junggel

Vielleicht bringst du erst mal mehr Licht in den Dschungel indem
du dein komplettes Programm zeigst.

In solchen Codefragmenten kann man zwar Fehler suchen aber
keine Fehler finden.

von Stefan F. (Gast)


Lesenswert?

Es gibt beim ARM Kern zwei Arten von Interrupts:

Flankengesteuerte: Triggern immer nur einmal beim Wechsel des 
Interrupt-Signals von 0 nach 1.

Pegelgesteuert: Triggern so oft und so lange das Interrupt-Signal 1 ist.

Je nach Gestaltung der jeweiligen Peripherie kann die eine oder andere 
Variante verwendet sein. Ich vermute, dass ST die Pegelgesteuerte 
Variante bevorzugt hat.

Bei der RTC vom STM32F103 weiss ich mit Sicherheit, dass der 
Sekunden-Interrupt Pegel-gesteuert ist. Da muss man das Flag innerhalb 
der ISR zurück setzen. Beim USART ist er auch Pegel-gesteuert, da setzt 
sich das Flag allerdings alleine zurück, wenn man das Data-Register 
ausliest bzw. das nächste Byte sendet.

Die Beschreibung des TIMx_SR Registers im Referenzhandbuch sagt, dass 
das Interrupt-Flag durch Software zurückgesetzt werden muss.

Hier hatte jemand ein Problem mit dem Zurücksetzen, weil er es an der 
falschen Stelle gemacht hat. Also muss es wohl auch mit der HAL 
notwendig sein: Beitrag "STM32: Timer Interrupt: Löschen des Pending Flags"

von Martin B. (ratazong)


Lesenswert?

Du rufst


HAL_TIM_IRQHandler(&htim2);

auf. Da wird das Flag gelöscht.

von Harry L. (mysth)


Lesenswert?

Martin B. schrieb:
> Du rufst
>
> HAL_TIM_IRQHandler(&htim2);
>
> auf. Da wird das Flag gelöscht.

Da geschieht bai den Timern in HAL/CubeMX automatisch, und man muß nur 
noch die gewünschten IRQ-Funktionen implementiren.
(z.B.: HAL_TIM_PeriodElapsedCallback)

Im HAL gibt es die bereits alle als weak Definitionen.

: Bearbeitet durch User
von tgdfgdf (Gast)


Lesenswert?

du nutzt am ende nur die callbackfunktion und filterst deinen timer raus
1
void TIM2_IRQHandler(void)
2
{
3
  HAL_TIM_IRQHandler(&htim2);
4
}
5
6
void TIM3_IRQHandler(void)
7
{
8
  HAL_TIM_IRQHandler(&htim3);
9
}
10
11
12
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
13
   static uint16_t time;
14
15
   switch ( htim->Instance )
16
   {
17
      case TIM2:       
18
        if (++time==500){
19
            HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
20
            time=0;
21
        } 
22
        break;
23
24
      case TIM3:
25
        break;
26
   }
27
   
28
29
}


so ähnlich ^^ hab keine IDE hier um das zu checken

von Harry L. (mysth)


Lesenswert?

Das reicht vollkommen:
1
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
2
   static uint16_t time;
3
4
   if (htim == &htim2)
5
   {
6
        if (++time==500){
7
            HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
8
            time=0;
9
        } 
10
   }
11
   
12
   if (htim == &htim3)
13
   {
14
// do something
15
   }
16
17
}

Wenn man TIM2_IRQHandler(void) auch überschreibt funktioniert das nicht 
mehr.

von rudolf (Gast)


Lesenswert?

tgdfgdf schrieb:

>
> void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
>    static uint16_t time;
>
>    switch ( htim->Instance )
>    {
>       case TIM2:
>         if (++time==500){
>             HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
>             time=0;
>         }
>         break;
>
>       case TIM3:
>         break;
>    }
>
>
> }
>
> so ähnlich ^^ hab keine IDE hier um das zu checken

Habe es glaube ich verstanden.
Aber wie und wo finde ich die Namen für diese callback Funktionen?

von Harry L. (mysth)


Lesenswert?

Im Atollic HAL_TIM_PeriodElapsedCallback markieren und F3 drücken.

von rudolf (Gast)


Lesenswert?

Harry L. schrieb:
> Im Atollic HAL_TIM_PeriodElapsedCallback markieren und F3 drücken.

und wenn ich den Namen nicht kenne?

von Harry L. (mysth)


Lesenswert?

HAL User-Manual

von Claudio F. (zunge)


Lesenswert?

in den jeweiligen .h Files der HAL Library ... oder der 
HAL-Dokumentation.

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.