Problem with PWM stopping after commutation event.
Hello - i'm new to STM32 MCU's (mostly have been using 8bit AVR's or OS based Raspberry Pi). I've been trying to implement a 6-step motor control (making everything from scratch as a learning experience). I picked TIM4 and TIM8 in a master-slave configuration, using complementary outputs of channel 1, 2 & 3 in TIM8. Everything is set so that PWM preloaded registers update happens in a commutation even, which is the TRGO of TIM4.
void motor6Step_Init(TIM_HandleTypeDef* htim4, TIM_HandleTypeDef* htim8){
htim4->Instance->CCR1 = (TIM4_ARR>>2);
htim8->Instance->CCR1 = 0;
htim8->Instance->CCR2 = 0;
htim8->Instance->CCR3 = 0;
htim8->Instance->CR1 &= ~( TIM_CR1_CEN );
htim8->Instance->CNT = 0;
__HAL_TIM_ENABLE_IT(htim8, TIM_IT_UPDATE);
HAL_TIMEx_ConfigCommutEvent_IT(htim8, TIM_TS_ITR2, TIM_COMMUTATION_TRGI);
}
void motor6Step_Start(TIM_HandleTypeDef* htim4, TIM_HandleTypeDef* htim8){
HAL_TIM_Base_Start(htim8);
HAL_TIM_OC_Start_IT(htim4, TIM_CHANNEL_1);
}
void motor6Stop_Stop(TIM_HandleTypeDef* htim4, TIM_HandleTypeDef* htim8){
HAL_TIM_OC_Stop_IT(htim4, TIM_CHANNEL_1);
HAL_TIM_Base_Stop(htim8);
htim4->Instance->CNT = 0;
htim8->Instance->CNT = 0;
}The code used for steps:
#define TIM8_DISABLE_ALL_CHANNELS \
TIM8->CCER = 0UL; \
TIM8->CCR1 = 0; \
TIM8->CCR2 = 0; \
TIM8->CCR3 = 0 \
#define TIM8_ENABLE_CHANNELS_STEP1 \
TIM8->CCR1 = TIM8_DUTY; \
TIM8->CCR2 = 0; \
TIM8->CCR3 = 0; \
TIM8->CCER = 0UL | ( TIM_CCER_CC1E | (TIM_CCER_CC2E) | (TIM_CCER_CC2NE) )
#define TIM8_ENABLE_CHANNELS_STEP2 \
TIM8->CCR1 = 0; \
TIM8->CCR2 = 0; \
TIM8->CCR3 = TIM8_DUTY; \
TIM8->CCER = 0UL | ( TIM_CCER_CC3E | (TIM_CCER_CC2E) | (TIM_CCER_CC2NE) )
#define TIM8_ENABLE_CHANNELS_STEP3 \
TIM8->CCR1 = 0; \
TIM8->CCR2 = 0; \
TIM8->CCR3 = TIM8_DUTY; \
TIM8->CCER = 0UL | ( TIM_CCER_CC3E | (TIM_CCER_CC1E) | (TIM_CCER_CC1NE) )
#define TIM8_ENABLE_CHANNELS_STEP4 \
TIM8->CCR1 = 0; \
TIM8->CCR2 = TIM8_DUTY; \
TIM8->CCR3 = 0; \
TIM8->CCER = 0UL | ( TIM_CCER_CC2E | (TIM_CCER_CC1E) | (TIM_CCER_CC1NE) )
#define TIM8_ENABLE_CHANNELS_STEP5 \
TIM8->CCR1 = 0; \
TIM8->CCR2 = TIM8_DUTY; \
TIM8->CCR3 = 0; \
TIM8->CCER = 0UL | ( TIM_CCER_CC2E | (TIM_CCER_CC3E) | (TIM_CCER_CC3NE) )
#define TIM8_ENABLE_CHANNELS_STEP6 \
TIM8->CCR1 = TIM8_DUTY; \
TIM8->CCR2 = 0; \
TIM8->CCR3 = 0; \
TIM8->CCER = 0UL | ( TIM_CCER_CC1E | (TIM_CCER_CC3E) | (TIM_CCER_CC3NE) )
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM8){
if(counter6Step == previousCounter6Step){
switch(counter6Step){
case 0:
TIM8_DISABLE_ALL_CHANNELS;
break;
case 1:
TIM8_ENABLE_CHANNELS_STEP1;
counter6Step++;
break;
case 2:
TIM8_ENABLE_CHANNELS_STEP2;
counter6Step++;
break;
case 3:
TIM8_ENABLE_CHANNELS_STEP3;
counter6Step++;
break;
case 4:
TIM8_ENABLE_CHANNELS_STEP4;
counter6Step++;
break;
case 5:
TIM8_ENABLE_CHANNELS_STEP5;
counter6Step++;
break;
case 6:
TIM8_ENABLE_CHANNELS_STEP6;
tim4_pscUpdate = 1;
counter6Step=1;
break;
default:
TIM8_DISABLE_ALL_CHANNELS;
counter6Step = 0;
break;
}
}
}
}
void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM8){
previousCounter6Step = counter6Step;
HAL_GPIO_TogglePin(LED_RED_GPIO_Port, LED_RED_Pin);
}
}The problem i'm experiencing, is that between steps using the same "high-side" PWM, the output goes low after changing the low side - for example:
going from step 2 to step 3, the PWM is correctly genrated on CH3 during step 2, but the outpul stays in the low state during step 3.
Funny thing is if i do a breakpoint in the callback and use the debug as a "step mode" the pwm is generated properly. Maybe anybody experienced something similar in the past?



