STM32F1 problemas con un temporizador

Tengo algunos problemas para configurar un temporizador de 1 segundo en STM32F103 mcu.

He configurado el temporizador 2 para que tenga un preescalador de 1099 y un período de 65514, por lo que espero tener una tasa de interrupción de 1 segundo: 72 MHz/1099/65514 = 1 Hz.

Sin embargo, en realidad recibo la primera interrupción incluso antes de terminar la rutina de configuración del temporizador (no es una gran preocupación en este momento), la siguiente interrupción ocurre después de 1000 ms como se esperaba, la siguiente interrupción ocurre después de 322 ms, y la siguiente después de 32 ms y la siguiente después 590 ms. (estos se midieron de acuerdo con el temporizador sysstick que tengo funcionando a 1 ms).

Parece bastante aleatorio, ¿qué está pasando?

Aquí hay parte del código relevante:

void RCC_Configuration() {
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA |
                        RCC_APB2Periph_GPIOB |
                        RCC_APB2Periph_AFIO  |
                        RCC_APB2Periph_USART1, ENABLE);

RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 |
                        RCC_APB1Periph_TIM2, ENABLE);
}

void Timer2_4_5_Configuration() {
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Prescaler = (1099-1);
TIM_TimeBaseStructure.TIM_Period = (65514-1);


TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

TIM_Cmd(TIM2, ENABLE);
}

void NVIC_Configuration () {
NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);
}

void TIM2_IRQHandler() {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
GPIOA->ODR ^= GPIO_Pin_2;
}

EDITAR: Logré que esto funcionara, cometí un error tonto en el resto de mi código. He usado el mismo pin para otra cosa, olvidé comentar la línea, oopsy.

El led en el pin 2 cambia a 1 Hz según lo previsto, pero surge una nueva pregunta:

Establecí un punto de interrupción en la línea de alternancia del pin en el controlador de interrupciones TIM y parece que se activa en momentos aleatorios como se indicó anteriormente. Pero cuando elimino el punto de interrupción, el led cambia según lo previsto.

Qué está sucediendo ?

PD: estoy usando CooCox IDE.

¿Está su PLL funcionando antes de comenzar a configurar el temporizador? ¿Tiene divisores válidos para relojes AHB, APB y Flash? Aparte de eso, revisaría los registros ARR y PSC si no están sobrescritos por accidente.
Estoy bastante seguro de que el código de inicio lo cubrió. He comprobado los registros ARR y PSC y tienen el valor necesario.
¿Tu código funciona en el simulador?
Estoy usando Coocox IDE, no tiene un simulador integrado. ¿Tienes una recomendación para uno?
@Mike: ¿alguna vez ha tenido algún temporizador trabajando en ese tablero antes?
Sí, tengo el temporizador 3 haciendo algo de pwm con 3 canales. Creo que he encontrado el problema, pero eso me lleva a nuevas preguntas. Editaré las preguntas.
Es posible que desee detener el temporizador en la parada de la CPU, está configurado en DBG->DBGMCU_CR.
¡Eso fue todo @venny! Gracias ! Es posible que desee formular eso en una respuesta.

Respuestas (1)

Cuando un depurador detiene la ejecución del programa, manualmente o al alcanzar un punto de interrupción, congela el núcleo de Cortex-M (incluido el contador de pulsaciones del sistema) mientras deja el resto del sistema en ejecución.

Los periféricos continúan contando, leyendo y escribiendo en la memoria y las E/S, y activando banderas de interrupción. Las banderas se acumulan y una vez que se reanuda el procesador, comienza a repararlas.

La mayoría de los periféricos pueden configurarse para suspenderse cuando la CPU está suspendida, esto es útil cuando se necesita la intervención del programa para mantener la función correcta. De forma predeterminada, generalmente no se ven afectados por el depurador, aunque existen excepciones (el temporizador Freescale FTM que se detiene de forma predeterminada).

Los MCU STM32F1 tienen un registro dedicado para configurar el comportamiento de depuración de los periféricos, el DBG->DBGMCU_CR.