AnsweredAssumed Answered

STM32F103CB ADC Interrupt based on timer does not trigger each pwm period?

Question asked by ravnas.eirik on Jun 18, 2015
Latest reply on Jun 22, 2015 by Amel N
Hi everyone! I'm struggling a bit to get ADC interrupts to trigger on EVERY pwm period even though repetition counter is set to 0. Increasing the repetition counter makes the interrupt trigger only 1 out of 4 periods and so on..  
Can anybody help? 

The timer is initialised as follows:

    halHandle.pwmPeriod = 4096/2; 


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);




    halHandle.pwmNeutral = halHandle.pwmPeriod/2;
    /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */
    for (int i=0;i<3;i++)
    {
        halHandle.pwmDuty[i] = halHandle.pwmNeutral;
    }


    /* Time Base configuration */
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned3;
    /* TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned2; // generates */
                                                                            // events
                                                                            // on upcounting
    /* TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; */
    TIM_TimeBaseStructure.TIM_Period = halHandle.pwmPeriod;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;


    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);


    /* Channel 1, 2 and 3 Configuration in PWM mode */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
    TIM_OCInitStructure.TIM_Pulse = halHandle.pwmDuty[0];


    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);


    //used to trigger ADC
    /* TIM_OCInitStructure.TIM_Pulse = 1000;  */
    /* TIM_OC4Init(TIM1, &TIM_OCInitStructure); */


    TIM_UpdateDisableConfig(TIM1, DISABLE);
    TIM_UpdateRequestConfig(TIM1, TIM_UpdateSource_Regular);


     TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
     TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
     TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
     TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);


    /* Automatic Output enable, Break, dead time and lock configuration*/
    TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
    TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
    TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
    TIM_BDTRInitStructure.TIM_DeadTime = 22; //must be at least 300ns
    /* TIM_BDTRInitStructure.TIM_DeadTime = 30; //must be at least 300ns */
    TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
    TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
    TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;


     TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
     TIM_CCPreloadControl(TIM1, ENABLE);
    /* TIM_ITConfig(TIM1, TIM_IT_COM, ENABLE); */
     /* TIM_ARRPreloadConfig(TIM1, ENABLE); */
    


    /* TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_OC4Ref); */
    TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update);




     TIM_Cmd(TIM1, ENABLE);


    /* Main Output Enable */
    TIM_CtrlPWMOutputs(TIM1, DISABLE);


ADC is initialised as follows:

    ADC_InitTypeDef ADC_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;




  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_GPIOC, ENABLE);
    
  //............... ADC1 .........................................
  //no regular conversions
  ADC_InitStructure.ADC_Mode = ADC_Mode_InjecSimult;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 0;
  ADC_Init(ADC1, &ADC_InitStructure);


  ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);
  
  /* Set injected sequencer length */
  ADC_InjectedSequencerLengthConfig(ADC1, 4);
  /* ADC1 injected channel Configuration */ 
  ADC_InjectedChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5);
  ADC_InjectedChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_7Cycles5);
  ADC_InjectedChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SampleTime_7Cycles5);
  ADC_InjectedChannelConfig(ADC1, ADC_Channel_6, 4, ADC_SampleTime_7Cycles5);
  /* ADC1 injected external trigger configuration */
  ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T1_TRGO);
  /* ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T1_CC4); */
  ADC_InjectedDiscModeCmd(ADC1, ENABLE);


  /* Enable ADC1 external trigger */ 
  ADC_ExternalTrigInjectedConvCmd(ADC1, ENABLE);


  /* Enable JEOC interrupt */
  ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);


  
  NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);


  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
  
  ADC_InjectedSequencerLengthConfig(ADC2, 4);


  ADC_InjectedChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_7Cycles5);
  ADC_InjectedChannelConfig(ADC2, ADC_Channel_3, 2, ADC_SampleTime_7Cycles5);
  ADC_InjectedChannelConfig(ADC2, ADC_Channel_5, 3, ADC_SampleTime_7Cycles5);
  /* ADC_InjectedChannelConfig(ADC2, ADC_Channel_8, 4, ADC_SampleTime_7Cycles5); //temperature */
  ADC_InjectedChannelConfig(ADC2, ADC_Channel_7, 4, ADC_SampleTime_7Cycles5); //resolver


  /* ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None); */
  //set offsets
  /* ADC_SetInjectedOffset(ADC2, ADC_Channel_1, CURRENT_OFFSET); */
  /* ADC_SetInjectedOffset(ADC2, ADC_Channel_3, CURRENT_OFFSET); */
  /* ADC_SetInjectedOffset(ADC2, ADC_Channel_5, CURRENT_OFFSET); */
  /* ADC_SetInjectedOffset(ADC2, ADC_Channel_7, CURRENT_OFFSET); */


  ADC_InjectedDiscModeCmd(ADC2, ENABLE);


  /* Enable ADC1 external trigger */ 
  ADC_ExternalTrigInjectedConvCmd(ADC2, ENABLE);


  /* Enable JEOC interrupt */
  ADC_ITConfig(ADC2, ADC_IT_JEOC, ENABLE);


  /* Enable ADC2 */
  ADC_Cmd(ADC2, ENABLE);


  ADC_ResetCalibration(ADC1);
  while(ADC_GetResetCalibrationStatus(ADC1));
  ADC_StartCalibration(ADC1);
  while(ADC_GetCalibrationStatus(ADC1));


  
  ADC_ResetCalibration(ADC2);
  while(ADC_GetResetCalibrationStatus(ADC2));
  ADC_StartCalibration(ADC2);
  while(ADC_GetCalibrationStatus(ADC2));
  
  ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);
  ADC_SoftwareStartInjectedConvCmd(ADC2, ENABLE);




Outcomes