cancel
Showing results for 
Search instead for 
Did you mean: 

Starting a Timer via a GPIO Pin at a changing edge and return the value into the DMA via another GPIO and changing edge

MHerz.1
Associate II

Hey,

I'm using a Nucleo-F446RE and the STM32 Cube IDE.

I want to start the Timer3 with a changing Edge at a GPIO Pin. Then the Timer should count till another GPIO has a changing Edge aswell. Now the timer should be disabled and the counter should be stored in the DMA.

Has anyone an idea how to implement this?

Markus

1 ACCEPTED SOLUTION

Accepted Solutions
MHerz.1
Associate II

I could solve it.

What made this process complicated was the fact, that i couldn't distinguish between counter clockwise or clockwise rotation of the encoder signal from the motor. To implement this by checking edges is (as far as i know impossible) impossible by using input capture compare withput encoder mode. What made this possible and why the solution by just using two input captures and measuring the time between them is simple and good is because the already implemented encoder mode of another timer has a direction bit. This bit tells me in which direction he is counting the angle of the encoder signal. This bit can be accessed via 'TIMx -> CR1 & 0x10;'

Thanks for helping me through this JW

View solution in original post

5 REPLIES 5

> I want to start the Timer3 with a changing Edge at a GPIO Pin.

Either start TIM3 in an EXTI interrupt set to that pin (with delay caused by interrupt latency), or use one of the TIM3_CHx pins and use the Slave-mode controller of TIM3 in Trigger mode, see TIM3_SMCR description and the TIM chapter in RM.

> Then the Timer should count till another GPIO has a changing Edge aswell. Now the timer should be disabled

This is tricky. Is it necessary? Why?

> and the counter should be stored in the DMA.

Counter's value can be Captured upon edge of another TIM3_CHx, simply set it to Capture mode and you'll see the captured value in TIM3_CCRx. There can be an interrupt invoked, or a DMA transfer, see TIMx_DIER register.

JW

MHerz.1
Associate II

Thank you for helping. I will take a closer look at your approach. Maybe it makes more sense to explain my problem because my solution is overcomplicated or just not possible to achive.

The controller is fed with a incremental encoder signal to determen a angle change of the motor. For my control algorithm I need to track position and angular velocity of the system. To accomplish the position monitoring i'm using the Timer 2 in Encoder mode. This works like a charm. Now i want to track the velocity by measuring the time between encoder signal A changing edges and encoder signal B changing edges. With this method i could measure a very low amount of angle change and achive my specification requirement.

If you have further questions please let me know.

I would simply set the timer as free running and the two channels to Input capture. You can find time differences simply by subtracting.

JW

MHerz.1
Associate II

Thats a good and simple idea I have not considered. Thank you. I'll take a look at this aproach.

Markus

MHerz.1
Associate II

I could solve it.

What made this process complicated was the fact, that i couldn't distinguish between counter clockwise or clockwise rotation of the encoder signal from the motor. To implement this by checking edges is (as far as i know impossible) impossible by using input capture compare withput encoder mode. What made this possible and why the solution by just using two input captures and measuring the time between them is simple and good is because the already implemented encoder mode of another timer has a direction bit. This bit tells me in which direction he is counting the angle of the encoder signal. This bit can be accessed via 'TIMx -> CR1 & 0x10;'

Thanks for helping me through this JW