2022-10-07 03:24 AM
I'm using a general-purpose timer to generate low level pulses, configuring one channel as PWM. The problem is when I disable the channel, the signal goes low, and I want it to remain high.
I played with the OCPolarity and PWM modes 1 and 2, but only take effect when the PWM is running, when disabling the pin always goes low
any suggestion?
MCU STM32F722ZETx (Nucleo F722ZE)
main
LL_TIM_EnableCounter(TIM9);
bool active_inactive = false;
while (1) {
if (HAL_GPIO_ReadPin(USER_Btn_GPIO_Port, USER_Btn_Pin) == GPIO_PIN_SET){
while(HAL_GPIO_ReadPin(USER_Btn_GPIO_Port, USER_Btn_Pin) == GPIO_PIN_SET);
if(active_inactive){
LL_TIM_CC_EnableChannel(TIM9, LL_TIM_CHANNEL_CH1);
LL_TIM_ClearFlag_UPDATE(TIM9);
LL_TIM_EnableIT_UPDATE(TIM9);
}
else{
LL_TIM_DisableIT_UPDATE(TIM9);
LL_TIM_CC_DisableChannel(TIM9, LL_TIM_CHANNEL_CH1);
}
active_inactive = !active_inactive;
HAL_Delay(50);
}
HAL_Delay(1);
}
Configuration generated by cubeMX
/**
* @brief TIM9 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM9_Init(void)
{
/* USER CODE BEGIN TIM9_Init 0 */
/* USER CODE END TIM9_Init 0 */
LL_TIM_InitTypeDef TIM_InitStruct = {0};
LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Peripheral clock enable */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM9);
/* TIM9 interrupt Init */
NVIC_SetPriority(TIM1_BRK_TIM9_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn);
/* USER CODE BEGIN TIM9_Init 1 */
/* USER CODE END TIM9_Init 1 */
TIM_InitStruct.Prescaler = 0;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 647;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
LL_TIM_Init(TIM9, &TIM_InitStruct);
LL_TIM_DisableARRPreload(TIM9);
LL_TIM_SetClockSource(TIM9, LL_TIM_CLOCKSOURCE_INTERNAL);
LL_TIM_OC_EnablePreload(TIM9, LL_TIM_CHANNEL_CH1);
TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM2;
TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
TIM_OC_InitStruct.CompareValue = 5;
TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
LL_TIM_OC_Init(TIM9, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct);
LL_TIM_OC_EnableFast(TIM9, LL_TIM_CHANNEL_CH1);
/* USER CODE BEGIN TIM9_Init 2 */
/* USER CODE END TIM9_Init 2 */
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOE);
/**TIM9 GPIO Configuration
PE5 ------> TIM9_CH1
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_5;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_3;
LL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}
2022-10-07 03:52 AM
this is a common problem when implementing six steps trapezoidal control for BLDC motors.
If my memory doesnt fail me i ended up doing something like @Antypas.Peter said here https://community.st.com/s/question/0D50X00009sW6qlSAC/hal-pwm-stop-with-defined-pin-output
2022-10-07 04:22 AM
set CH idle state - then you get hi idle
in cube:
maybe you need setting in break also:
...enable off state sel.
2022-10-07 07:02 AM
Or just switch the given pin to GPIO Out with whatever level you want.
[EDIT] Oh that's the same what Javier suggested above. [/EDIT]
JW
2022-10-10 12:56 AM
Thanks for the answers. What @AScha.3 suggests is only for advance timers and I'm using a general purpose one (I'm regrating this, but the PCB is already made)
So I will reconfigure the pin as gpio output and change the level before stopping the timer. Thanks again.