Skip to main content
_EFrie
Senior
February 26, 2025
Question

ARR update causing output glitch

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.

4 replies

Tesla DeLorean
Guru
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

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
_EFrie
_EFrieAuthor
Senior
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.

waclawek.jan
Super User
February 27, 2025

I'd guess this is a measurement error.

JW

_EFrie
_EFrieAuthor
Senior
February 27, 2025

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