Skip to main content
Graduate
February 26, 2025
Question

ARR update causing output glitch

  • February 26, 2025
  • 3 replies
  • 586 views

Using STM32F765, I'm using tim1 with OC toggle.

The issue is glitches when I update the ARR value within the Repetition UP ISR.  ARR Preload is enabled, not sure what to look at here.

D2 toggles when the TIM1_UP_TIM10_IRQHandler fires, and D3 is TIM1 CH1 output, and the glitch seems obviously caused by the SetAutoReload when it fires.

Screenshot 2025-02-26 14.23.59.png

Init code

void init_stepper(void) {
 ena_stepper();
 LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
 LL_TIM_InitTypeDef TIM_InitStruct = {0};
 /* USER CODE END TIM1_Init 2 */
 LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
 /**TIM1 GPIO Configuration
 PA8 ------> TIM1_CH1
 */
 GPIO_InitStruct.Pin = TMC_STEP_Pin;
 GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
 GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;
 GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
 GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
 GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
 LL_GPIO_Init(TMC_STEP_GPIO_Port, &GPIO_InitStruct);

 TIM_InitStruct.Prescaler = 0;
 TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
 TIM_InitStruct.Autoreload = 65535;
 TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
 TIM_InitStruct.RepetitionCounter = 0;
 LL_TIM_Init(TIM1, &TIM_InitStruct);

 LL_TIM_EnableARRPreload(TIM1);
 LL_TIM_SetClockSource(TIM1, LL_TIM_CLOCKSOURCE_INTERNAL);
 LL_TIM_DisableMasterSlaveMode(TIM1);
 LL_TIM_SetPrescaler(TIM1, 63);

 LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_TOGGLE);
 LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1);
 LL_TIM_OC_SetCompareCH1(TIM1, 0x0000);
 LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCPOLARITY_LOW);
 LL_TIM_EnableAllOutputs(TIM1);
 //
 NVIC_SetPriority(TIM1_UP_TIM10_IRQn, PRIORITY_TIMER1_PWM);
 NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
 LL_TIM_SetRepetitionCounter(TIM1, 31);
 LL_TIM_EnableIT_UPDATE(TIM1);
}

 

ISR

void TIM1_UP_TIM10_IRQHandler(void) {
 
 if (LL_TIM_IsActiveFlag_UPDATE(TIM1) == 1) {
 LL_GPIO_TogglePin(OUT_ALIVE_GPIO_Port, OUT_ALIVE_Pin);
 LL_TIM_ClearFlag_UPDATE(TIM1);
 stepTickCount += 16;
 // Stop here
 if (stepTickCount >= targetPosition) {
 LL_TIM_DisableCounter(TIM1);
 LL_TIM_SetCounter(TIM1, 0);
 LL_TIM_SetAutoReload(TIM1, SystemCoreClock / 128 / 500 /* HZ */);
 }
 uint32_t arr = LL_TIM_GetAutoReload(TIM1);
 if (!arr) {
 arr = 1;
 }
 uint32_t currHz = 1687500 / LL_TIM_GetAutoReload(TIM1);
 currHz = (currHz > 0 ? currHz : 1);
 if ((targetPosition - stepTickCount) < 200) {
 // Decel here
 if (currHz > 750) {
 currHz -= 750;
 if (currHz < 750) {
 currHz = 750;
 }
 LL_TIM_SetAutoReload(TIM1, SystemCoreClock / 128 / currHz /* HZ */);
 }
 } else {
 // Acceleration here
 if (currHz < targetSpeed) {
 currHz += 750;
 if (currHz > targetSpeed) {
 currHz = targetSpeed;
 }
 LL_TIM_SetAutoReload(TIM1, SystemCoreClock / 128 / currHz /* HZ */);
 }
 }
 }
}

 

 

 

 

    This topic has been closed for replies.

    3 replies

    Graduate II
    February 26, 2025

    >> .. the glitch seems obviously caused by the SetAutoReload when it fires.

    Or you manually clearing the COUNTER

    The general idea is that you set up the shadow registers ahead of time so they cleanly and consistently engage when the UPDATE event occurs, ie rolling into zero

    _EFrieAuthor
    Graduate
    February 26, 2025

    The counter isn't being cleared.  yeah, its in the code there, but it turns off the timer completely, it only fires at the end.

    Super User
    February 27, 2025

    I'd guess this is a measurement error.

    JW

    _EFrieAuthor
    Graduate
    February 27, 2025

    I think this was indeed a measurement error.  I upped the sample rate and it seems to have gone away.