cancel
Showing results for 
Search instead for 
Did you mean: 

Reading actual TIM repetition count after manually stopping counter

Hi,

I am using an STM32H7 TIM8 unit to generate a PWM signal with a fixed number of pulses.  The TIM unit is configured in one-shot mode and the repetition counter is configured to generate the desired number of pulses, after which the timer automatically halts.  This all works great.

Occasionally we may wish to stop the counter early.  The pulses are triggering an external motor controller which moves a shaft forward or backwards based on the number of pulses received and an encoder wheel.  If an external sensor signals that the shaft is near a limit we'd like to halt its movement.  I think I can do this by just setting CEN=0 if the sensor is triggered.  It would also be nice to know how many pulses were actually generated (i.e. some way of reading the repetition counter's current value) since we are trying to keep track of the shaft's actual position, but I can't seem to find a way to do that.

I suppose we could use CEN in master mode to gate a second timer running in slave mode and after setting CEN=0 reading the other timer's CNT value to figure out how much time has elapsed and then calculating the number of pulses.  That seems like a lot of work to just read the repetition counter's internal value, though.

Thanks,

TG

1 REPLY 1

As the repetition counter itself is not readable, any solution is "lot of work" - depending on how you define "lot of" :)

One other method than yours, which came to my mind - and did not test - is to clock up until the repetition-update occurs, as indicated by TIM8_SR.UIF being set.

After stopping TIM8, set its outputs to "safe" state (that depends on your application, but may e.g. involve reading the respective GPIO_IDR, setting accordingly GPIO_ODR through GPIO_BSRR, and changing GPIO_MODER from AF to Out). Change TIM8_SMCR.TS so that it be slave to some other unused timer and change TIM8_SMCR.SMS to external clock, then reenable TIM8_CR1.CEN. The other (master) timer is supposed to be set in CR2 to output TRGO upon Update (that's the default), not running, and that results in one TIM8 clock pulse every time the master's TIMx_EGR.UG is set.

Clear TIM8_SR.UIF, if it's nonzero.

So now in a cycle, set TIM8_CNT to be equal to TIM8_ARR and issue on the master TIMx_EGR.UG to generate a clock and TIM8_CNT to roll over; repeat this until TIM8_SR.UIF is set. That will give you the number of cycles "remaining" in the repetition counter. The "spent" cycles are TIM8_RCR minus "remaining".

If you have TIM8_PSC nonzero, the procedure is somewhat more lengthy, as for one decrement of the repetition counter you have to issue clocks until TIM8_CNT rolls over and clears.

JW