Configuración de la tasa de interrupciones del temporizador para la placa de descubrimiento STM32F4xx

1

Estoy trabajando en un proyecto con la placa STM32F407 y Keil, y como parte de un proyecto más grande en el que estoy trabajando, necesito configurar una interrupción del temporizador. Eventualmente, funcionará a alrededor de 46 kHz, pero por ahora solo estoy tratando de controlar la velocidad a la que se interrumpe.

En su estado actual, el temporizador y la interrupción funcionan, de modo que cuando TIM3 termina de contar su período, se produce una interrupción para la que tengo un controlador escrito. Entonces puedo parpadear un LED o hacer lo que sea necesario en este controlador. Mi problema es que no importa cómo parezca configurarlo, no puedo ajustar la velocidad a la que se interrumpe. He puesto un contador que aumenta cada vez que se produce la interrupción. Lo he usado para cronometrarlo y descubrí que parece funcionar a una velocidad de aproximadamente 245 kHz (quizás 5 kHz).

He usado la hoja de cálculo de Excel que genera el archivo system_stm32f4xx para configurar un reloj de 168 MHz. Configuré el reloj TIM3 usando la siguiente función:

void InitializeTimer() {
    TIM_TimeBaseInitTypeDef SetupTimer;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    SetupTimer.TIM_Prescaler = 167-1;
    SetupTimer.TIM_Period = 1000-1;
    SetupTimer.TIM_CounterMode = TIM_CounterMode_Up;
    SetupTimer.TIM_ClockDivision = TIM_CKD_DIV1;

    TIM_TimeBaseInit(TIM3, &SetupTimer);
    TIM_Cmd(TIM3, ENABLE); 
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
}

Configuro la interrupción con la siguiente función:

void EnableTimerInterrupt()
{
    NVIC_InitTypeDef nvicStructure;
    nvicStructure.NVIC_IRQChannel = TIM3_IRQn;
    nvicStructure.NVIC_IRQChannelPreemptionPriority = 0;
    nvicStructure.NVIC_IRQChannelSubPriority = 1;
    nvicStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvicStructure);
}

Ambos se llaman desde main en este orden. Basado en este post encontré los valores prescalar y período anteriores Para obtener una interrupción de 1 kHz. Sin embargo, éste no es el caso. En ningún orden en particular, una lista de cosas que he probado incluye:

  • Numerosas combinaciones diferentes de valores prescalar / período
  • Cambiar el HSE_VALUE en stm32f4xx.h de 25 MHz a 8 MHz (todo lo que he visto dice que el oscilador externo funciona a 8 MHz, no 25; pero eso es lo que el archivo excel lo configuró para
  • agregando lo siguiente a mi función de inicialización del temporizador:

    uint16_t prescalar_val = (uint16_t) ((SystemCoreClock / 2) / 6000000) - 1; //6 MHz
    ...
    TIM_PrescalerConfig(TIM3, prescalar_val, TIM_PSCReloadMode_Immediate);
    

    Que es un fragmento de código que encontré que dijo que configura el temporizador para que se ejecute a 6 MHz

Estoy bastante perplejo en este punto. He leído sección de este documento sobre cronómetros de propósito general (ch 18 ), y en base a eso y otros ejemplos que he encontrado en línea, estoy haciendo todo bien. Tal vez haya algo que me esté perdiendo, lo cual no sería sorprendente, soy bastante nuevo en esto. En el peor de los casos, solo uso la interrupción tal como está y uso un contador para dividir la frecuencia, pero eso parece una solución bastante tonta.

Cualquier ayuda que alguien pudiera darme sería muy apreciada. Si alguien quiere ver cualquier otro archivo o función en particular, puedo publicarlo.

    
pregunta dmoreno92

1 respuesta

0

Luego de mucha frustración, descubrí cómo escalar mi temporizador / interrumpir. Intenté hacerlo todo de una vez en lugar de desarrollarlo de manera incremental.

En caso de que alguien encuentre esta pregunta, encontré este artículo y seguí sus instrucciones paso a paso: configurar el temporizador, luego la interrupción, luego el controlador de interrupción. Creo que mi problema fue que no estaba eliminando el bit pendiente después de cada interrupción, como lo hicieron en el paso 9:

TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

Añadir eso al final de mis controladores de interrupción parecía hacer el truco. Puedo escalar el tiempo como lo esperaría al proporcionar argumentos variables al período preescolar y al período.

    
respondido por el dmoreno92

Lea otras preguntas en las etiquetas