ARM ST32F400 - can one use a timer to get the period of a waveform directly? - Page 1
Forum section: electronics / general

author: peter-h
author_rank: Super Contributor
timestamp: February 09, 2021, 07:33:49 am
content: Is it possible to configure one of the timers to return the period of a waveform?One would make an external circuit which picks up just the positive going transitions through zero and turn that into a square wave. Use that to enable a counter (when it is positive) to count up from zero. Then when it goes negative the counter must stop and generate an interrupt or set a flag which can be polled, so it can be read, and zeroed.Not sure from reading the massively complicated manual whether this can be done directly.

author: capt bullshot
author_rank: Super Contributor
timestamp: February 09, 2021, 07:44:24 am
content: It's called "PWM input mode", look up this chapter in the reference manual to see if it fits your requirement. Two capture registers of one timer module capture at the rising / falling edge of one input signal, and can generate interrupt requests. By subtracting the captured values from the previous ones, one can derive cycle time (period), pulse width and duty cycle of the signal.I've used this mode before to capture a duty cycle encoded signal of a temperature sensor.

author: @rt
author_rank: Super Contributor
timestamp: February 09, 2021, 10:28:25 am
content: Here’s an implementation with a pic, to determine audio frequency for AFSK decode.http://www.n9cx.net/BobBall.htm

author: S. Petrukhin
author_rank: Super Contributor
timestamp: February 11, 2021, 08:17:05 am
content: Quote from: @rt on February 09, 2021, 10:28:25 amIt seems that PIC is used there, not STM32

author: mikerj
author_rank: Super Contributor
timestamp: February 11, 2021, 08:29:38 am
content: Quote from: S. Petrukhin on February 11, 2021, 08:17:05 amThe words "Here’s an implementation with a pic" kind of gave that away!

author: S. Petrukhin
author_rank: Super Contributor
timestamp: February 11, 2021, 12:03:07 pm
content: Quote from: mikerj on February 11, 2021, 08:29:38 amI probably didn't understand something...

author: SiliconWizard
author_rank: Super Contributor
timestamp: February 11, 2021, 02:38:44 pm
content: You can of course do that with just interrupts on rising/falling edge of the input signal. That's ok if the input frequency is low compared to the system clock, otherwise it may not be doable or would yield unacceptable jitter/accuracy.You can do that much more accurately with what is called on most MCUs "input capture". It's usually a featured tied to peripheral timers.The STM32F4xx have a handful of timers, some of which support input capture. Look this up in the ref manual of your MCU.

author: S. Petrukhin
author_rank: Super Contributor
timestamp: February 11, 2021, 03:00:10 pm
content: Quote from: SiliconWizard on February 11, 2021, 02:38:44 pmWould have already written part of the timer setup code...

author: ucanel
author_rank: Regular Contributor
timestamp: February 12, 2021, 11:25:54 am
content: Here is an example i run into.It uses input capture, stm32f, hal libraries.https://controllerstech.com/how-to-use-input-capture-in-stm32/

author: peter-h
author_rank: Super Contributor
timestamp: February 14, 2021, 01:11:54 pm
content: I don't think there is any way to do this without the timer generating an interrupt, IOW it won't store the "duration" value for later retrieval. One has to interrupt from it and the ISR needs to grab that value.

author: S. Petrukhin
author_rank: Super Contributor
timestamp: February 15, 2021, 09:53:18 am
content: Quote from: peter-h on February 14, 2021, 01:11:54 pmI'm not sure, I haven't learned all the ins and outs very well yet, but can't a timeout trigger a DMA to send a value to memory without code in the interrupt handler?

author: DavidAlfa
author_rank: Super Contributor
timestamp: February 16, 2021, 11:53:14 am
content: Yes, the input capture mode can set a dma transfer at every pin level change.You also have the pwm input that will store separate values for high state time and total period.Read the reference manual, it has a lot of information and very clearly explained.It's a shame that the HAL is nowhere that well documented.

author: peter-h
author_rank: Super Contributor
timestamp: February 17, 2021, 08:41:09 am
content: Thank you for these inputs. It is a great idea to use DMA to store the timer value, butnotincrement the DMA address pointer

author: DavidAlfa
author_rank: Super Contributor
timestamp: February 17, 2021, 10:39:38 am
content: That also can be done. Please read the reference manual! You can set it to increase or not the dma memory pointer.

author: bson
author_rank: Unknown
timestamp: February 19, 2021, 12:21:46 am
content: Why use DMA if you're not going to fill a buffer with the captures? You can just read the capture registers directly in that case.You only need to capture on the leading active edge to measure the period; you need to capture on both edges to also get duty cycle. The thing to keep in mind is the period and duty may not be for the same cycle, but if the period is invariant that's not a problem. Timers usually have multiple capture registers that can capture a timer count on different conditions.

author: S. Petrukhin
author_rank: Super Contributor
timestamp: February 19, 2021, 08:08:51 am
content: Quote from: bson on February 19, 2021, 12:21:46 amCorrect me, but DMA is needed to read the final value of the capture register when it is already formed, so as not to track the capture completion flag or handle it with an interrupt. During the capture process, the timer registers have an increasing count, if I'm not mistaken. DMA allows you to avoid this collision, it will always form the last value in the variable at any time, even if there is now a counting capture period.

author: peter-h
author_rank: Super Contributor
timestamp: February 19, 2021, 09:10:04 am
content: I need only the period. The DC is not important.I will be using this to generate a 400Hz sinewave (which seems easy enough with a RAM area feeding a DAC via DMA, repetitively) which needs to be phase locked (to a fraction of a degree accuracy) to the incoming reference signal, which is a poor waveform (some mixture of sine and square).The generated 400Hz then needs to be phase shifted in small increments relative to this reference input. I posted about this on another thread. It seems easy enough to do: bump the DMA source pointer a little, while keeping the circular buffer limits in the same place.AFAICT the zero crossings can be measured by reading the (continually incrementing) timer value, which got zeroed at the last +ve edge.It could have been done with analog. A CD4046 PLL can work quite well, but to get < 1 degree phase lock would need a high gain. And then the phase shifting is non trivial.I want to avoid interrupts on this cycle measurement and zero crossing detection, because the latency could be a bit long, due to other stuff going on.

author: bson
author_rank: Unknown
timestamp: February 23, 2021, 08:52:11 pm
content: Quote from: S. Petrukhin on February 19, 2021, 08:08:51 amYou have essentially two options:1. Have the timer capture and interrupt2. Have the interrupt handler read the timer capture value from the peripheral into memory and do something (maybe unblock a thread to operate on the in-memory value)1. Have the timer activate a DMA transfer2. DMA transfers timer capture value to memory3. DMA interrupts4. Have the interrupt handler do something (maybe unblock a thread to operate on the in-memory value)The latter, with just one capture value per transfer, is just extra work. Having the interrupt handler grab the capture register and put it somewhere static is about as cheap as it gets.

author: peter-h
author_rank: Super Contributor
timestamp: February 24, 2021, 09:30:03 pm
content: Except, the DMA can catch the timer value at the moment of the edge arriving, whereas interrupting and reading the timer from the ISR will have some latency, which could be substantial.

author: capt bullshot
author_rank: Super Contributor
timestamp: February 25, 2021, 09:55:37 am
content: Quote from: peter-h on February 24, 2021, 09:30:03 pmThat's what the capture registers are intended for. An edge at the counter input transfers the counter value to the register, then DMA or ISR can read that register before the next edge occurs. So for 400Hz, there's plenty of time to read that register available. So the timer value is captured at the edge, no matter if your readout is slower.