[STM32F407VG, Discovery-board] Timer-interrupt verwirrt mich

Gast #4998714
Servus zusammen,

ich steige gerade wieder auf den STM32 ein (hatte länger nix damit 
gemacht und fange bei den basics an) aber leider bin ich jetzt auf ein 
Problem gestoßen, dessen Hintergrund ich gerne Verstanden hätte. Sollte 
auch super leich zu reproduzieren sein, sofern ein STM32F4-discovery 
board und CooCox CoIDE vorliegen. (Damit hätte ich dann wohl auch meine 
Umgebung definiert)
Die veränderten Dateien habe ich angehängt, der Rest ist von den 
Standard-Libs, die man in CoIDE einfach aktiviert und die dann 
automatisch ins Projekt kopiert werden.

Folgende Aufgabe :
Ich will eine LED innerhalb einer Interruptroutine ein- und ausschalten. 
Etwa im 1s Zyklus.

Das Problem :
So gehts :
1
void TIM2_IRQHandler(void)
2
{
3
  static uint8_t i = 0;
4

5
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
6

7
  GPIO_ToggleBits(GPIOD, GPIO_Pin_13); // LD3, orange
8

9
  if( 2 == ++i )
10
  {
11
    GPIO_ToggleBits(GPIOD, GPIO_Pin_14); // LD5, red
12
    i=0;
13
  }
14
}
So gehts nicht :
  (nur die rote LED blinkt, die orange nicht)
1
void TIM2_IRQHandler(void)
2
{
3
  static uint8_t i = 0;
4

5
  GPIO_ToggleBits(GPIOD, GPIO_Pin_13); // LD3, orange
6

7
  if( 2 == ++i )
8
  {
9
    GPIO_ToggleBits(GPIOD, GPIO_Pin_14); // LD5, red
10
    i=0;
11
  }
12

13
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
14
}

Woran kann das liegen?
Ich stehe vollkommen auf dem Schlauch. Für mich ist das gerade völlig 
unerklärlich!

Vielen Dank für eure Hilfe!
Grüße
Luigi
Angehängte Dateien:
#4998720
PS:

Hervorzuheben ist vielleicht, dass nur die Zeile
1
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
in der Position verändert wird. Das ist der einzuge Unterschlied 
zwischen "funktionier" und "funktioniert nicht".



PPS:
war nicht eingelogt, bin aber ich
(Firma: matzetronics) #4998722
Da gabs mal was hier bei mc.net, man muss erst das Interrupt Flag 
löschen, bevor man an GPIOs rumfummelt. Ist mir auch mal beim STM32F100 
untergekommen.
Frag mich aber bitte nicht mehr nach dem Thread - ich habe nur diese 
Bemerkung in meinen Sourcen gefunden:
1
void TIM1_UP_TIM16_IRQHandler(void){
2
//uint8_t speedRegTicks = 0;
3
// microcontroller.net : Clear the IT pending bit before doing any GPIO stuff
4
TIM_ClearITPendingBit(TIM1,(TIM_IT_Update | TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3));
5
  LED_GPIO_PORT->BSRR = ERROR_LED_PIN;  // debug
6
//....
#4998727
Luigi schrieb:
> Woran kann das liegen?
> Ich stehe vollkommen auf dem Schlauch. Für mich ist das gerade völlig
> unerklärlich!

TIM_ClearITPendingBit() kommt im 2. Falls zu spät. Der µC braucht ein 
paar Takte bis das Timer Peripherial die Interrupt Anforderung 
wirklich zurück nimmt - man bedenke z.B. den Schreib Puffer.

Dummerweise macht der µC dadurch beim Interrupt Return ein Tail-Chain 
wieder in denselben Handler, der dadruch 2x hintereinander aufgerufen 
wird. Du solltest bei der roten LED die doppelte Frequenz erkennen 
können.

Abhilfe: Entweder rechtzeitig Flag zurück setzen (1. Variante) oder 
nochmal ein Dummy Lesezugriff auf die Hardware ausführen (z.B. irgenden 
Register lesen).
#4998810
Jim M. schrieb:
> TIM_ClearITPendingBit() kommt im 2. Falls zu spät. Der µC braucht ein
> paar Takte bis das Timer Peripherial die Interrupt Anforderung
> wirklich zurück nimmt - man bedenke z.B. den Schreib Puffer.
>
> Dummerweise macht der µC dadurch beim Interrupt Return ein Tail-Chain
> wieder in denselben Handler, der dadruch 2x hintereinander aufgerufen
> wird. Du solltest bei der roten LED die doppelte Frequenz erkennen
> können.

Eindeutig, du hast recht. Vielen Dank. Das Erklärt zu 100% das Phänomen.
Kurz Warten (2*NOP) nach dem rücksetzten ist ebenfalls eine Lösung, zu 
kurz warten (1*NOP) löst das Problem nicht (ich sage mal: q.e.d.)



Der vollständigkeit halber, so gehts auch :
1
void TIM2_IRQHandler(void)
2
{
3
  static uint8_t i = 0;
4

5
  GPIO_ToggleBits(GPIOD, GPIO_Pin_13); // LD3, orange
6

7
  if( 2 == ++i )
8
  {
9
    GPIO_ToggleBits(GPIOD, GPIO_Pin_14); // LD5, red
10
    i=0;
11
  }
12

13
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
14

15
  __asm volatile ("NOP");
16
  __asm volatile ("NOP");
17
}

Vielen Dank!

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.