TIM1 parece no detenerse

1

Estoy usando TIM1 para conducir un canal DMA que está enviando bytes a GPIOF en un STM32F407. TIM1 se inicia mediante un canal OC en un temporizador diferente. En el controlador de interrupción de flujo DMA, estoy intentando detener TIM1 y también reiniciar el contador al generar un evento de Actualización. Para solucionar problemas, he configurado un canal OC en TIM1 para que pueda confirmar que se está iniciando y deteniéndose como se esperaba.

Parece que se inicia y se detiene en los momentos correctos cuando se ve la salida del pin con un analizador lógico, pero al pasar por el controlador de interrupciones en el depurador, veo que el bit CEN todavía está configurado después de borrarlo. Además, TIM1- > CNT continúa aumentando a medida que paso por cada línea.

El controlador de interrupciones es el siguiente:

void __attribute__((interrupt("IRQ"))) DMA2_Stream5_IRQHandler(void)
{
    // Clear interrupt flags
    do
    {
        DMA2->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5;
    }
    while(DMA2->HISR & DMA_HISR_TCIF5);

    // Stop TIM1, TIM5 will re-enable it
    //TIM1->CR1 &= (u16)~TIM_CR1_CEN;
    do
    {
        TIM1->CR1 &= (u16)~TIM_CR1_CEN;
    }
    while(TIM1->CR1 & TIM_CR1_CEN);
    TIM1->EGR = TIM_EventSource_Update;     // Trigger an Update to reset the counter

    // Re-enable DMA for next TIM5 event
    DMA2_Stream5->CR |= DMA_SxCR_EN;
}

El código sale del bucle que borra el CEN, pero luego de ver los registros de TIM1, el CEN aún está configurado. ¿Cómo puedo asegurarme de que el temporizador se haya detenido realmente y comenzará a contar desde 0 la próxima vez que se inicie?

    
pregunta Batperson

2 respuestas

3

Parece que borrar el indicador habilitado no tiene efecto cuando el temporizador está en modo esclavo. He cambiado mi controlador de interrupciones de la siguiente manera, y ahora está funcionando como se esperaba. El temporizador se detiene y se restablece, hasta que TIM5 lo vuelva a iniciar.

// Clear interrupt flags
DMA2->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5;

// Disable slave move, can't stop the timer unless we do this first
TIM1->SMCR = 0;

// Stop TIM1, TIM5 will re-enable it
TIM1->CR1 = 0;// &= (u16)~TIM_CR1_CEN;
TIM1->EGR = TIM_EventSource_Update;     // Trigger an Update to reset the counter

// Re-enable slave mode
TIM1->SMCR = TIM_SlaveMode_Trigger;
    
respondido por el Batperson
-1
  1. es generalmente una (muy, muy) mala práctica dar vueltas en un isr.

  2. no tiene sentido hacer un bucle para borrar el CEN. si vuelve a establecerse, en otro lugar, su código lo hizo.

  3. voltea un pin en el isr para ver el tiempo.

respondido por el dannyf

Lea otras preguntas en las etiquetas