3
\$\begingroup\$

I am playing a tune on a speaker on an STM32G0B1 using PWM, however, sometimes after playing a tune the speaker continues to be driven despite Stop being called and the "idle state" being set to "Reset":

Idle state is set to "Reset" in Cube MX:

Cube MX screenshot showing CH Idle State set to Reset

When stopped the channel is driven High:

Scope Trace Showing Set at Idle

Code used to stop the PWM:

int bzStop(void)
{
 HAL_TIM_PWM_Stop(&htim17, TIM_CHANNEL_1);
 return 0;
}

Any ideas what I'm doing wrong here?

Thanks

asked Mar 10, 2022 at 11:22
\$\endgroup\$
3
  • \$\begingroup\$ Is the speaker directly connected? Or is a (say 10µF) AC coupling capacitor used? If the latter, "stopping high" shouldn't be an issue. \$\endgroup\$ Commented Mar 10, 2022 at 12:52
  • \$\begingroup\$ @rdtsc There isn't an AC coupling capacitor -- I'll put that in the next revision. \$\endgroup\$ Commented Mar 10, 2022 at 13:05
  • \$\begingroup\$ Is the "other side" of speaker connected to the same PWM, but with inverted levels? If so, does that "other side" idle high or low at the end? \$\endgroup\$ Commented Mar 10, 2022 at 14:09

3 Answers 3

1
\$\begingroup\$

I offer not a full solution or explanation, but a bandaid, having ran into the same.

When stopping the PWM (For example, in an appropriate interrupt handler), set the GPIO mode to output, and set it to the idle state you wish. When starting again, set its mode back to alternate.

answered Apr 11, 2022 at 9:45
\$\endgroup\$
0
\$\begingroup\$

I think what should you do is leave the timer channel running, e.g. not call HAL_TIM_PWM_Stop(&htim17, TIM_CHANNEL_1); which in turn calls TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); and stops the channel completely. What worked for me was setting the output always low by setting appropriate bits in the OC1M field in the CCMR1 register. Something like

htim4.Instance->CCMR1 = (TIM_CCMR1_OC1M_2);

which effectively sets the channel to mode always low. If you want to, you can stop the counter using __HAL_TIM_DISABLE() macro. Don't forget to start it again when you resume operation. When you want to resume the PWM, revert the bits to your wanted values accordingly.

I think that the Idle state setting applies only when you first start the channel and it is running.

Other thing to note is that output compare channel remembers its state even after completely resetting the peripheral.

answered Jun 29, 2022 at 13:03
\$\endgroup\$
-1
\$\begingroup\$

CH Idle State "reset" means the output pin will be pull high while stoped generate PWM, change it to "set" will solve your issue

answered Apr 3, 2022 at 16:44
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.