cancel
Showing results for 
Search instead for 
Did you mean: 

Is it Possible to change the timer count direction dynamically without having to wait for it to over- or underflow?

JHöfl.1
Associate III

Hello dear ST-Community,

here is a brief explaination of my problem:

I'm using multiple stepper-motors in my system.

I want to use 3 timers per stepper.

  1. Timer generates the PWM signal for the stepper-driver (easy to achive)
  2. Timer captures the signal of the 1. Timer. It has a low arr and increases the stepper-speed (aka decreases 1. Timer arr and ccr) after every overflow to achive ramps when accelerating/decelerating. (also no Problem)
  3. Timer also captures the signal of the 1. Timer and is supposed to keep track of the position of the stepper. This mens the CNT value of the 3. Timer always corresponds to the Position of the motor.

My Problem is, that I need to change the conting direction of the 3. Timer according to the rotational direction of the motor. I change direction of the motor in software, so all I thougt I needed to do was to change the count-direction of the 3. Timer simultaniously.

Is this possible? I coundn't find a __HAL-Macro for chainging the timers counting direction at runtime. I know it corresponds to the timers CR1 register, but woudn't it wait for the timer to over- or underflow until the change takes effect? Sadly I can't confirm it with hardware atm because I'm still waiting for my drivers.

My last resort would be to store the timers value befor chainging direction and resetting it with a new arr. So if I'm changing from a up-couting mode to down-counting, I'd have to store the CNT, reset the timer, change direction and use the stored CNT as new ARR. Then the down-counting would start from that ARR.

The whole reason for using 3 timers for one motor is to minimize cpu time, so I'd like to just change a register when I change direction and nothing more.

I'd love to here from an experienced timer-user if this approch is an good or if there is something more elegant.

Thanks in andvance!

Greetings from Germany

johofz

1 ACCEPTED SOLUTION

Accepted Solutions

I'm not trying to understand and critique your particular application/approach.

> I coundn't find a __HAL-Macro for chainging the timers counting direction at runtime.

Cube/HAL is a "library" which inevitably implements only a fraction of what's possible with the hardware. It's main purpose is to support the clicky CubeMX. There's no reason to seek constraints in Cube/HAL; read the TIM chapter in RM and proceed accordingly.

> I know it corresponds to the timers CR1 register, but woudn't it wait for the timer to over- or underflow until the change takes effect?

No. Just read the description of the TIMx_CR1.DIR bit.

> Sadly I can't confirm it with hardware atm because I'm still waiting for my drivers.

You surely can play with the timer itself on any cheap Nucleo board. Do it, it's fun.

JW

View solution in original post

3 REPLIES 3

I'm not trying to understand and critique your particular application/approach.

> I coundn't find a __HAL-Macro for chainging the timers counting direction at runtime.

Cube/HAL is a "library" which inevitably implements only a fraction of what's possible with the hardware. It's main purpose is to support the clicky CubeMX. There's no reason to seek constraints in Cube/HAL; read the TIM chapter in RM and proceed accordingly.

> I know it corresponds to the timers CR1 register, but woudn't it wait for the timer to over- or underflow until the change takes effect?

No. Just read the description of the TIMx_CR1.DIR bit.

> Sadly I can't confirm it with hardware atm because I'm still waiting for my drivers.

You surely can play with the timer itself on any cheap Nucleo board. Do it, it's fun.

JW

TDK
Guru

You can use LL_TIM_SetCounterMode(TIMx, LL_TIM_COUNTERMODE_UP) to do this.

Modifying registers directly seems smarter here.

If you feel a post has answered your question, please click "Accept as Solution".
JHöfl.1
Associate III

Thanks for the answers!

It worked with just modifying the DIR bit like so:

m_positionTimer->Instance->CR1 |= TIM_CR1_DIR;

and

m_positionTimer->Instance->CR1 &= ~(TIM_CR1_DIR);