0

As the title says, with an STM32 if an interrupt lasts for 1 microsecond should one compensate the CCR by 1 microsecond converted in counter cycles in order to achieve the correct duty cycle?

For example with a period of 100Khz and an overflow interrupt of 1 microsecond should i use a CCR = 50Khz to achieve duty cycle of 50% or should i use a CCR = 50kHz - interrupt delay? Keep in mind that i'm using shadow register to preload the next period/duty cycle combination dynamically.

Oscilloscope readings tells me the second.

Does a flag for automatic compensation exist?

Below some code snippets

void MX_TIM9_Init(void){
    TIM_OC_InitTypeDef sConfigOC;
    htim9.Instance = TIM9;
    htim9.Init.Prescaler = PSC; // Get clock to <freq> Hz
    htim9.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim9.Init.Period = 250;
    htim9.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    HAL_TIM_PWM_Init(&htim9);

    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 125;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
    sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
    HAL_TIM_PWM_ConfigChannel(&htim9, &sConfigOC, TIM_CHANNEL_1);

    __HAL_TIM_ENABLE_IT(&htim9, TIM_IT_UPDATE);
    TIM9->CR1 |= TIM_CR1_ARPE;
}

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* htim_pwm){
    GPIO_InitTypeDef GPIO_InitStruct;
    if(htim_pwm->Instance==TIM9){    
         __TIM9_CLK_ENABLE();
         /* Peripheral interrupt init*/
        HAL_NVIC_SetPriority(TIM1_BRK_TIM9_IRQn, 1, 1);
        HAL_NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn);
        GPIO_InitStruct.Pin = GPIO_PIN_5;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
        GPIO_InitStruct.Alternate = GPIO_AF3_TIM9;
        HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
    }
}

void TIM1_BRK_TIM9_IRQHandler(void){
    if(__HAL_TIM_GET_FLAG(&htim9, TIM_FLAG_UPDATE) != RESET){
        if(__HAL_TIM_GET_IT_SOURCE(&htim9, TIM_IT_UPDATE) !=RESET){
            __HAL_TIM_CLEAR_IT(&htim9, TIM_IT_UPDATE);
            myFunction(void);
        }
    }
}

void myFunction(){
    //perform logics with if
    tim9->ARR = r; // r is a value coming from the logics above
    tim9->CCR1 = r / 2;
}
Luigi
  • 376
  • 3
  • 16

1 Answers1

1

No - interrupts have not anything with the timers. When the interrupt line is set by the timer, it counts as normally - and the interrupt is dealt by the interrupt controller & the core. You do not have to compensate anything.

0___________
  • 60,014
  • 4
  • 34
  • 74
  • If that's the case why in my code i need to compensate for it? Otherwise i'm not reading half of the period as duty cycle – Luigi Jul 04 '17 at 17:52
  • You can only answer this question. You know the code, and you know what the code should do. But from the hardware point of view triggering of the interrupt does not affect any peripheral activity.The code execution is completely independent from the timers. – 0___________ Jul 04 '17 at 17:59
  • PS CCRx registers are not programmed in xHz only in the clock ticks. – 0___________ Jul 04 '17 at 18:02
  • regarding CCRx since it depends on PSC i didnt want to bother you with calculations. Anyway my code once entered in the interrupt is only preloading ARR and CCR – Luigi Jul 04 '17 at 18:22
  • probably you are missing one update during your interrupt routine & calculations. DWhat uC & speed – 0___________ Jul 04 '17 at 19:08
  • What is the meaning? i'm not that expert in STM and uC. STM32F4 and 84Mhz – Luigi Jul 05 '17 at 07:10
  • if your PWM period is 1us then then you have only less than 84 clock ticks to perform your calculations and interrupt routines, – 0___________ Jul 05 '17 at 07:16
  • That was just an example, my interrupt is 1-2 us at most and it happens already at 130khz of frequency but i've already preloaded it in the previous interrupt (preload register is on) – Luigi Jul 05 '17 at 07:23
  • have you set the URS bit? – 0___________ Jul 05 '17 at 08:01
  • Let me try to see if i've understood. If i dont set the URS bit, an UEV is generated also when an interrupt different from the overflow happens, right? "When the USR bit of the TIMx_CR1 register is set, only counter overflow/underflow generates an update interrupt or DMA request (if enabled)". This means i need __HAL_TIM_URS_ENABLE(&htim9) – Luigi Jul 05 '17 at 08:08
  • http://mazsola.iit.uni-miskolc.hu/~drdani/docs_arm/st/f4/DM00042534_stm32f4_timer.pdf – 0___________ Jul 05 '17 at 08:24
  • As the buffered registers (ARR, PSC, CCRx) need an update event to be loaded with their preload values, set the URS (Update Request Source) to 1 to avoid the update flag each time these values are loaded. In this case, the update event is only generated if the counter overflow/underflow occurs. So not only i have an UEV in overflow but right now i also have an UEV when i use TIMx->ARR ? – Luigi Jul 05 '17 at 08:41
  • The cmd TIM9->CR1 |= TIM_CR1_URS; is leading to an even worse situation. – Luigi Jul 05 '17 at 16:33