I'm having trouble with idle state for PWM generation .
I start a PWM output(using Timer3) on a STM32 Nucleo F303K8 board using HAL with:
HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1);
And I stop the PWM at an interrupt using HAL with:
HAL_TIM_PWM_Stop_IT(&htim3,TIM_CHANNEL_1)
;
But when the PWM is not pulsating it outputs around 2.4V as you see in the above snapshot. What would set it such that the PWM output would be zero instead of 2.4V?
Here is TIM 3 settings:
static void MX_TIM3_Init(void)
{
/* USER CODE BEGIN TIM3_Init 0 */
/* USER CODE END TIM3_Init 0 */
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM3_Init 1 */
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 72-1;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 655-1;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 327;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM3_Init 2 */
/* USER CODE END TIM3_Init 2 */
HAL_TIM_MspPostInit(&htim3);
}
Notes: I tried setting GPIO as pulldown but it didn't make any difference. I also tried PWM2 mode that also didn't help. And if I use advanced timer TIM 1 this issue doesn't appear. But I already use TIM 1 for another PWM so I need to use general purpose timer.
2 Answers 2
From the user manual of the board : https://www.st.com/resource/en/user_manual/dm00231744-stm32-nucleo-32-boards-mb1180-stmicroelectronics.pdf
PA6 is connected to PB6 through the jumper SB16 (which is its default state):
enter image description here *Arduino pin A5 being Stm32 pin PA5
Maybe you have PB6 high, pulled up or in Hi-Z state and that's causing the signal to float @ 2.4V.
If that's the case, you need to remove the 0R resistor on the board :
Calling the PWM stop command releases the control of the PWM to the GPIO controller, and if that is not set, it reverts to reset state - nothing is driving it.
What you seem to want is that your PWM duty is zero, so... Just write that.
htim3.Instance->CCR1 = 0;
Then you can put it back using
htim3.Instance->CCR1 = 327.
There are also HAL macros to set this for you, but I prefer the register access method. Avoids ST deciding to not do things for you.
EDIT, following comment below: You can start and stop the timer counter by setting the CEN bit in control register 1. This will stop it counting. Or you can change it to forced output mode. Something like: htim3.Instance->CR1 &= !0x1; //to clear the CEN bit htim3.Instance->CR1|=0x1; //To set CEN
You can do likewise with the interrupt enable bits if you want to disable interrupts, but they will not trigger with CEN disabled...
But if you are creating a phase delay between timers, beware that you might have to resynchronise them.
-
\$\begingroup\$ This wont work for me. I need to start and stop PWM in my application. I create a delay between two PWM by a third timer. Long story but these wont help my case. But how can we write HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1); without HAL? It would be great if you can also add that in your answer, Maybe I do some combination. \$\endgroup\$GNZ– GNZ2022年12月05日 19:06:00 +00:00Commented Dec 5, 2022 at 19:06