Interrupción del temporizador en stm32f103

Estoy teniendo una pequeña sorpresa con la interrupción del temporizador en el evento de actualización. Pensé que si el temporizador está configurado para contar, el evento de actualización ocurrirá justo después del desbordamiento, es decir, cuando el CNT sea igual a cero. Según las figuras 103-105 del manual de referencia.

Pero ese no parece ser el caso por alguna razón. Lo probé con este simple código:

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);

Luego, en el controlador irq:

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;
}

No tengo nada más habilitado, no hay secciones críticas, solo un ciclo while vacío.

También tengo un archivo .ini para el depurador, por lo que cuando detengo la ejecución, también se detienen todos los temporizadores.

Ahora lo interesante.

Cuando depuro en Keil Simulator, la ejecución no se detiene en el punto de interrupción. Pero cuando depuro en la placa, la ejecución se detiene en el punto de interrupción y puedo ver que TIM2->CNT es igual a 1.

Sí parece estar conectado con la frecuencia de ticks, si lo hago mil veces menos, el punto de interrupción no detiene la ejecución. Pero qué diablos, es solo 1 MHz; ¡La CPU funciona a 72 MHz!

Ahora me pregunto: ¿es un error en el simulador o en el hardware? ¿O simplemente he leído mal algo y el temporizador no se inicializó correctamente?

Creo que no es seguro asumir que el comportamiento del simulador imita perfectamente el comportamiento del hardware.

Respuestas (2)

De acuerdo, parece ser que el depurador estropea los tiempos.

Sustituí el punto de interrupción con encender el LED, y sin depurador permanece apagado. Si entro en la depuración y no habilito el punto de interrupción antes del inicio, el LED permanece apagado.

Solo si habilito el punto de interrupción y luego comienzo la ejecución: el punto de interrupción se activa y el LED se enciende.

No creo que sea un modo seguro leer el temporizador en la rutina de interrupción. ¡Creo que cuando se llama a su ISR, el temporizador todavía está funcionando! Si la prioridad de interrupción de su sysstick es más alta que la de TIM2, la función de interrupción de TIM2 puede retrasarse. Entonces, cuando se llama a su código, es posible que el temporizador haya cambiado.

Le sugiero que mejore la prioridad de interrupción de TIM2 a más alta que systick, y que lo intente.

Como mencioné en la pregunta, todo lo demás está deshabilitado, incluido el sysstick. Realmente dudo que llamar al controlador de interrupciones y verificar un registro tome más de 1 microsegundo.
Estoy seguro de que la función de depuración ralentizará la ejecución.
si, eso es correcto.