2025-11-17 12:53 PM - edited 2025-11-17 12:53 PM
Hey!
I will explain my setup and then paste the code. I have three different timers (TIM1, TIM2, TIM3) sending out PWMs to different parts of my board. All timers are set up the same way; the only difference is that TIM1 is an advanced timer.
What I do is initialize all my timers and start everything up. Then, much later, I switch my pins from GPIO output low to pin alternate mode to enable the PWM outputs. This works great 999 times out of 1000, but sometimes TIM1 (and it’s always TIM1) randomly decides to put the PWM high for a very long time and then, after about 20 ms, goes down to 0 and never starts again. Resetting the MCU fixes this, and everything works as expected.
(Using STM32G051)
Here is the initialization code for TIM1:
TIM1.CR1.CMS = 0x1; //Set TIM1 center aligned mode, trigger interrupt flags on compares in downcount
TIM1.CR2.MMS = 0x7; //OC4REFC signal is used as trigger output (TRGO)
TIM1.ARR = PERIOD_SIXTH * 3; //Auto-reload register
TIM1.CCMR1.OC1M = 0x6; //PWM mode 1 on channel 1; in upcounting PWM active below compare
TIM1.CCMR1.OC1PE = 1; //Enable preload
TIM1.CCMR1.OC2M = 0x7; //PWM mode 2 on channel 2; in upcounting PWM active above compare
TIM1.CCMR1.OC2PE = 1; //Enable preload
TIM1.CCMR2.OC4M = 0x6; //Set Channel Active on match
TIM1.CCMR2.OC4PE = 1; //Enable preload
TIM1.CCR4 = PERIOD_SIXTH * 2; //Sync pulse to TIM2
TIM1.CCER.CC1E = 1; //Enable output on channel 1
TIM1.CCER.CC2E = 1; //Enable output on channel 2
TIM1.CCER.CC4E = 1; //Enable output on channel 4
TIM1.BDTR.MOE = 1; //Enable MOE (main output enable)
TIM1.EGR.UG = 1; //Generate update event on TIM1
2025-11-17 1:55 PM
The TIM does what it's told. Debugging and examining the TIM1 registers after it "goes down to 0 and never starts again" may shed a clue as to what's happening. Perhaps a write out of bounds or stack overflow happens.