I am trying to generate 3 channel center aligned PWM with complementary outputs and deadtime insertion on an STM32G474. To test functionality of the timers, I currently have the 6 outputs connected to 6 LEDS to hopefully see a visible time delay between the main outputs going low and the complementary outputs going high. This however isn't the case, and I can't see any delay between the toggling despite a calculated deadtime of around 98ms. There is no visible time where no LED is active
My timer initiation code is below
void TIM1_Init() {
// Enable clocks for GPIOA, GPIOB and TIM1
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
// Set relevant GPIO pins to AF mode
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
GPIO_InitStruct.Alternate = LL_GPIO_AF_6;
GPIO_InitStruct.Pin = LL_GPIO_PIN_8;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_13;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_14;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
GPIO_InitStruct.Pin = LL_GPIO_PIN_15;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
LL_TIM_InitTypeDef TIM_InitStruct;
LL_TIM_StructInit(&TIM_InitStruct);
TIM_InitStruct.Prescaler = 0xFFFF;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_CENTER_UP_DOWN;
TIM_InitStruct.Autoreload = 244;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
LL_TIM_Init(TIM1, &TIM_InitStruct);
LL_TIM_SetClockSource(TIM1, LL_TIM_CLOCKSOURCE_INTERNAL);
LL_TIM_OC_InitTypeDef TIM_OC_InitStruct;
LL_TIM_OC_StructInit(&TIM_OC_InitStruct);
TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM2;
TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE;
TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_ENABLE;
TIM_OC_InitStruct.CompareValue = 244/2;
//TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_LOW;
//TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_LOW;
TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW;
TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW;
LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct);
LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct);
LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH3, &TIM_OC_InitStruct);
LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1);
LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH2);
LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH3);
LL_TIM_BDTR_InitTypeDef bdtr = {0};
bdtr.OSSRState = LL_TIM_OSSR_ENABLE;
bdtr.OSSIState = LL_TIM_OSSI_ENABLE;
bdtr.LockLevel = LL_TIM_LOCKLEVEL_OFF;
bdtr.DeadTime = 24; // Try max for visible LED effect
bdtr.BreakState = LL_TIM_BREAK_DISABLE;
bdtr.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH;
bdtr.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_ENABLE;
LL_TIM_BDTR_Init(TIM1, &bdtr);
LL_TIM_EnableAllOutputs(TIM1);
LL_TIM_EnableCounter(TIM1);
LL_TIM_GenerateEvent_UPDATE(TIM1);
}
In the wider code, the main function simply runs this function only then does a simple LED blinking program for a separate LED. Nothing else is changed, including clock speed at 16MHz
I have tried many setups and configuration options and nothing is working, I appreciate all help.
How did you calculate the dead time?
As far as I can tell you cannot achieve such a long dead time.
I assume you calculated it based on the timer clock frequency divided by the prescaler.
The dead time generator used Tdts, which is not derived from the prescaled tim_psc_ck, it is based on the kernel timer, tim_ker_ck.
The reference manual gives examples based on an 8MHz clock, and the maximum dead time that can be inserted with this method is 31750ns. There is a register to prescale the Tdts, but only with a maximum of 4. I don't think you will be able to see it with a camera. Maybe if you slow down the entire clock tree to some extreme values.