AnsweredAssumed Answered

Synchronising timers - STM32F4

Question asked by MrStive on Oct 1, 2012
Latest reply on Oct 2, 2012 by MrStive
Hi guys,
I'm trying to synchronise timers and wondering what is the best way to do this. I need 3 set time points for my project; A continuous interrupt at 5uS intervals, an interrupt excatly 2uS after the first, and then a further interrupt 1uS after the second. i.e 5uS, 7uS, 8uS, 10uS, 12uS, 13uS, 15uS, 17uS,18uS... and so on..

Obviously i could implement this with 1 timer with 1uS interrupt and some sort of counter, however some of the code executed in the first and last trigger cannot be limited to 1uS. It still could work, but i have started now developing the code with 3 timers.

Currently i have set up 3 timers which i just enable and disable to start and stop them, but i think this is not correct and may be causing inaccuracies to my timing. I see in the reference manual that TIM9, and 12 have 'one-pulse mode' , should i be using these?

Overview of my code:
Timer3 interrupt should occur every 5uS, this enables TIM5 (2uS - 500khz) and triggers an ADC reading (triple simultaneous - 3 cycle sample time).  Once TIM5 interrupt is called, TIM5 is disabled and TIM2 (1uS - 1Mhz) is enabled. Once TIM2 interrupt is called, TIM2 is disabled. This then repeats when TIM3 is triggered again (every 5uS) as it was never disabled.

Code:
// Timer3 (every 5uS)
void TIM3_IRQHandler(void)
{
    TIM_Cmd(TIM5, ENABLE); //ENABLE TIMER5
  ADC_SoftwareStartConv(ADC1);                    // Start ADC conversion - will trigger DMA2 when complete
  GPIOE->BSRRL = GPIO_Pin_8; //set  
  if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
  }
}


// INTERRUPT AFTER ADC READINGS
void DMA2_IRQHANDLER(void)
{
    GPIOE->BSRRH = GPIO_Pin_8; //reset
    GPIOE->BSRRL = GPIO_Pin_10; //set   
    if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0) != RESET)
    {
        DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0); // Reset Flag
 
    }
}

// Timer5 - 2uS
void TIM5_IRQHandler(void)
{
  TIM_Cmd(TIM2, ENABLE); //ENABLE DEADTIME TIMER
  TIM_Cmd(TIM5, DISABLE); //DISABLE current timer
 
  GPIOE->BSRRH = GPIO_Pin_10; //reset
  GPIOE->BSRRL = GPIO_Pin_12; //set
 
  if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM5, TIM_IT_Update);    
  }
}


// Timer2 - 1uS
void TIM2_IRQHandler(void)
{
  TIM_Cmd(TIM2, DISABLE); //DISABLE current timer  
  GPIOE->BSRRH = GPIO_Pin_12; //reset
  if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);    
  }
}


I've hooked up a Saleae logic analyzer (dont have CRO with me atm) to pins PE.8, PE.10 and PE.12 but i'm not getting the expected output. The Saleae is sampling at 24MHz...

PIN8 is high from anywhere between 5.2uS to 5.95uS.
PIN10 comes on 41.7ns after PIN8 goes low, and stays on for 1.95-2.05uS - sometimes even exactly 2.0uS.
PIN12 comes on at the the same time PIN10 goes low, and stays high for either exactly 1.1250uS or 1.0833uS, or about every fourth time two short pulses of 0.4-0.5uS with a ~0.7uS low inbetween.
Whats happening!!?? Is it my Saleae giving me this weird result?


Outcomes