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
voidTIM2_IRQHandler(void)
2
{
3
staticuint8_ti=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
voidTIM2_IRQHandler(void)
2
{
3
staticuint8_ti=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
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
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
voidTIM1_UP_TIM16_IRQHandler(void){
2
//uint8_t speedRegTicks = 0;
3
// microcontroller.net : Clear the IT pending bit before doing any GPIO stuff
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).
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 :
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang