Timer-Interrupt auf stm32f103

Ich habe eine kleine Überraschung mit Timer-Interrupt bei Update-Ereignis. Ich dachte, dass, wenn der Timer so konfiguriert ist, dass er hochzählt, das Aktualisierungsereignis unmittelbar nach dem Überlauf auftritt, dh wenn CNT gleich Null wird. Gemäß den Abbildungen 103-105 aus dem Referenzhandbuch.

Aber das scheint aus irgendeinem Grund nicht der Fall zu sein. Ich habe es mit diesem einfachen Code getestet:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

// tick frequency in Hz
const uint32_t tickFreq = 1000*1000; 
const uint16_t timPrescaler = SystemCoreClock / (tickFreq ) - 1;

TIM_TimeBaseInitTypeDef timBaseStruct;
timBaseStruct.TIM_Prescaler = timPrescaler;
timBaseStruct.TIM_ClockDivision = 0; 
timBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
timBaseStruct.TIM_Period = 5;

TIM_TimeBaseInit(TIM2, &timBaseStruct);

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE );
NVIC_EnableIRQ(TIM2_IRQn);

Dann im IRQ-Handler:

void TIM2_IRQHandler(void)
{

    if(TIM2->CNT != 0)
    {
         TIM2->CNT = 1;   // <----------- and I put a breakpoint on this line
    }

    TIM2->SR = ( uint16_t ) ~TIM_IT_Update;
}

Ich habe nichts anderes aktiviert, keine kritischen Abschnitte, nur eine leere While-Schleife.

Ich habe auch eine INI-Datei für den Debugger. Wenn ich also die Ausführung stoppe, werden auch alle Timer gestoppt.

Jetzt das Interessante.

Wenn ich im Keil-Simulator debugge, stoppt die Ausführung nicht am Haltepunkt. Aber wenn ich auf dem Board debugge, stoppt die Ausführung am Haltepunkt und ich kann sehen, dass TIM2-> CNT gleich 1 ist!

Es scheint mit der Tick-Frequenz zusammenzuhängen, wenn ich es tausendmal weniger mache, hält der Haltepunkt die Ausführung nicht an. Aber was soll's, es ist nur 1 MHz; CPU wird mit 72 MHz getaktet!

Jetzt frage ich mich - ist es ein Fehler im Simulator oder in der Hardware? Oder habe ich mich einfach etwas verlesen und der Timer wird nicht richtig initialisiert?

Ich denke, es ist unsicher anzunehmen, dass das Verhalten des Simulators das Verhalten der Hardware perfekt nachahmt.

Antworten (2)

Okay, das scheint der Debugger zu sein, der die Timings durcheinander bringt.

Ich habe den Haltepunkt durch das Einschalten der LED ersetzt, und ohne Debugger bleibt sie aus. Wenn ich das Debugging betrete und den Haltepunkt vor dem Start nicht aktiviere, bleibt die LED aus.

Nur wenn ich den Haltepunkt aktiviere und dann die Ausführung starte, wird der Haltepunkt ausgelöst und die LED leuchtet auf.

Ich glaube nicht, dass es ein sicherer Modus ist, den Timer in der Interrupt-Routine zu lesen. Ich denke, wenn Ihr ISR aufgerufen wird, läuft der Timer noch!! Wenn die Interrupt-Priorität Ihres Systicks höher ist als die von TIM2, kann die Interrupt-Funktion des TIM2 verzögert werden. Wenn Ihr Code aufgerufen wird, hat sich der Timer möglicherweise geändert.

Ich schlage vor, Sie verbessern die Interrupt-Priorität von TIM2 auf höher als Systick und versuchen es.

Wie ich in der Frage erwähnt habe, ist alles andere deaktiviert, einschließlich Systick. Ich bezweifle wirklich, dass das Aufrufen des Interrupt-Handlers und das Überprüfen eines Registers länger als 1 Mikrosekunde dauert.
Ich bin mir sicher, dass die Debug-Funktion die Ausführung verlangsamen wird.
ja, das ist richtig.