2025-02-26 11:28 AM
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.
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 */);
}
}
}
}
2025-02-26 12:25 PM
>> .. 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
2025-02-26 1:19 PM
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.