Author Topic: Help with STM32duino timers and frequency measurement  (Read 5931 times)

0 Members and 1 Guest are viewing this topic.

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5890
  • Country: es
Re: Help with STM32duino timers and frequency measurement
« Reply #25 on: December 06, 2022, 12:43:25 pm »
Attached sample project.
- 401 working at 84MHz with external 25MHz crystal.
- TIM2 is the frequency counter. Slave Reset mode, taking TRGO signal from TIM3, external clock, no prescaler.
- TIM3 is the master. Prescaler=1399+1, 84MHz/1400=60KHz input clock.
  PWM match happens at 60.000 (1000ms), triggers a DMA transfer from TIM2 counter, overflows at 60.000+1 (16us later), resetting TIM2.

If you want faster readings (ex. every 100/10mS, adjust TIM3 prescaler:
Code: [Select]
Prescaler   TIM3 clock      Update rate     Resolution
1399        60KHz           0,999983Hz      1Hz         
139         600KHz          9,99983Hz       10Hz
13          6MHz            99,9983Hz       100Hz

My clock generator is not very accurate, neither will the chinesium 25MHz crystal, yet results were pretty good (50ppm error):
Code: [Select]
Freq        Counter
10KHz       10.000
100KHz      99.995
10MHz       9.999.543
25MHz       24.998.860

The whole thing takes just 4 lines, excluding the initialization generated by CubeMX:
Code: [Select]
volatile uint32_t counter;
HAL_DMA_Start(htim3.hdma[TIM_DMA_ID_CC4], (uint32_t)&TIM2->CNT, (uint32_t)&counter, 1);
__HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_CC4);
__HAL_TIM_ENABLE(&htim3);
__HAL_TIM_ENABLE(&htim2);


Ensure to read the STM32F401 datasheet, you'll find the AC characteristics there.
For the timer clock input input, max frequency is Ftim/2, where Ftim is the peripheral clock.
In this case, it's working at 84MHz, so max external clock will be 42MHz.

Also check: Reference manual, Timer cookbook.

Faster STM32 will sample faster frequencies, ex. the STM32G431 works at 170MHz, timer will be able to sample up to 85MHz.
« Last Edit: December 06, 2022, 01:15:14 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: timdf911

Offline timdf911Topic starter

  • Contributor
  • Posts: 23
  • Country: gb
Re: Help with STM32duino timers and frequency measurement
« Reply #26 on: December 06, 2022, 07:21:35 pm »
Hi DavidAlfa

thanks for taking the time creating this bit of code - I had read that using DMA would be the better way to go but was beyond my understanding.
I've down loaded your code and am studying it to learn how it works etc.

As I'm only interested in freqs up to 30MHz the F410 should handle it ok.

Your code looks very elegant and I've complied and run it ok - just got to add a couple of sanity checks to it for my own learning - such as flashing led on the gate signal and uart comms for frequency indication etc.

Then if that all goes well I'll try converting it to LL.

Regards Tim
« Last Edit: December 06, 2022, 07:23:59 pm by timdf911 »
Tinkering for over 50 years and still learning  G4WIM KT6UK
 

Offline timdf911Topic starter

  • Contributor
  • Posts: 23
  • Country: gb
Re: Help with STM32duino timers and frequency measurement
« Reply #27 on: December 13, 2022, 07:00:33 pm »
Hi DavidAlfa

hope you're still following this thread - I've been doing a bit of digging and while your example works nicely I'm puzzled how the DMA is working.

Seems according to the CubeMx file you're using DMA1 Stream 2 for peripheral to memory - but yet the data sheet says DMA1 is only for memory to memory so I'm confused as to how it can be accessing the timer register.

I would have thought DMA2 would be the correct one to use.

I mention this as I've been building my own bare metal code - I'm a glutton for punishment, but it helps me learn !

Basically I'm using TIM3 as a counter (16 bits is ok for my needs) with PD2 ETR2 input and TIM2 as the timebase generating TRGO into ITR2 of TIM3 - this forced me to use DMA1 and it didn't work - at which point I found from the data sheet I should have been using DMA2 - but yet your example works !

FYI for hardware reasons I needed to use PD2 ETR2 as the signal input.  I have it working quite well as a frequency counter using a capture input but wanted to try DMA as a learning exercise.

Any thoughts (anyone) ?

Edit I've just found this page which seems to answer my DMA1 <> peripheral question
https://civilpedia.org/p/?t=STM32-DMA-Cheat-Sheet&pid=315

Regards Tim
« Last Edit: December 13, 2022, 07:33:25 pm by timdf911 »
Tinkering for over 50 years and still learning  G4WIM KT6UK
 

Offline ozcar

  • Frequent Contributor
  • **
  • Posts: 322
  • Country: au
Re: Help with STM32duino timers and frequency measurement
« Reply #28 on: December 13, 2022, 08:00:29 pm »
Ensure to read the STM32F401 datasheet, you'll find the AC characteristics there.
For the timer clock input input, max frequency is Ftim/2, where Ftim is the peripheral clock.
In this case, it's working at 84MHz, so max external clock will be 42MHz.

I have seen, in various places in the ST documentation the statement that maximum external clock is Ftim/3 or Ftim/4. I never had to determine which was the correct figure, and perhaps there was something that I was misunderstanding that lead to the apparent contradiction. Now, a third possibility, but whatever the true answer is, the prescaler mayl be required to reach 30MHz on the F401.
« Last Edit: December 13, 2022, 08:05:13 pm by ozcar »
 

Offline ozcar

  • Frequent Contributor
  • **
  • Posts: 322
  • Country: au
Re: Help with STM32duino timers and frequency measurement
« Reply #29 on: December 13, 2022, 09:51:42 pm »
I tried the code I posted earlier (without using prescaler) and found it maxes out at around 38MHz, so does not make it to 42MHz, but at 30MHz, or even 37MHz it seems OK.

Did a few more tests:

Changed ETPS in SMCR to divide by two, and it worked OK up to 60MHz (limit of the cheap-and-cheerful signal generator.)

Changed the timer clock to be 8.4MHz instead of 84MHz (gate time now 1 second), and it was good to around 4.1MHz. Not sure why that is slightly over 1/10 of the max I saw at 84MHz Ftim, but it does look like Something BadTM happens near to Ftim/2.
« Last Edit: December 14, 2022, 02:08:53 am by ozcar »
 

Offline timdf911Topic starter

  • Contributor
  • Posts: 23
  • Country: gb
Re: Help with STM32duino timers and frequency measurement
« Reply #30 on: December 14, 2022, 12:53:40 pm »
Hi Ozcar

I'm not using the DMA code but using my simpler capture compare code I found that it would only work upto 4MHz (using PD2 ETR2 input) but by using the ETPS prescaler to /8 it will work upto 55MHz which is odd as I was only expecting 8 x 4MHz.

The resolution of 1kHz is ok for my needs, now just need to tweak my code as currently the time base signal pops out from TIM2 on PA5 then is hard wired back into PB0 to gate the counter on TIM3.

I still plan on getting DMA going but I was spending too much time on DMA rather than the rest of the project - so for now I'll stick with my capture compare solution.

Regards Tim
Tinkering for over 50 years and still learning  G4WIM KT6UK
 

Offline ozcar

  • Frequent Contributor
  • **
  • Posts: 322
  • Country: au
Re: Help with STM32duino timers and frequency measurement
« Reply #31 on: December 15, 2022, 12:19:57 am »
Hi Ozcar

I'm not using the DMA code but using my simpler capture compare code I found that it would only work upto 4MHz (using PD2 ETR2 input) but by using the ETPS prescaler to /8 it will work upto 55MHz which is odd as I was only expecting 8 x 4MHz.

The resolution of 1kHz is ok for my needs, now just need to tweak my code as currently the time base signal pops out from TIM2 on PA5 then is hard wired back into PB0 to gate the counter on TIM3.

I still plan on getting DMA going but I was spending too much time on DMA rather than the rest of the project - so for now I'll stick with my capture compare solution.

Regards Tim

So, if I have got this right, you changed to using TIM2 for the gate time, and TIM3 to count your external signal, with TIM2 output wired externally to one of the TIM3 channels to use input capture?

If so, I'm not sure where the maximum of 4MHz would come from. Maybe show us the actual code.

Using the 16-bit TIM3 to count the external signal, you would have to keep the gate time below about 2ms though to avoid complications with the counter overflowing.
 

Offline profdc9

  • Frequent Contributor
  • **
  • Posts: 319
  • Country: us
Re: Help with STM32duino timers and frequency measurement
« Reply #32 on: December 15, 2022, 03:11:47 am »
I built an antenna tuner based on the STM32F103 which includes code for measuring the frequency of the RF signal.  I included a 74HC393 so I could cut down the frequency and implement an inverse frequency counter if necessary.

https://github.com/profdc9/ModularTuner

https://github.com/profdc9/ModularTuner/blob/master/code/tuner/frequencyCounter.cpp

There's also circuitry there that helps condition the RF signal for counting that took some effort to get right, as well as circuitry to measure the phase of the reflected RF signal to get the complex phase coefficient.
 
The following users thanked this post: timdf911

Offline timdf911Topic starter

  • Contributor
  • Posts: 23
  • Country: gb
Re: Help with STM32duino timers and frequency measurement
« Reply #33 on: December 15, 2022, 08:32:42 pm »
Hi ozcar

the 4MHz limit was because I had the system clock set to about 8MHz rather than 84MHz.  Yes because the frequency counter is only 16 bits I have to make sure the max count is within limits so I have the ETR2 prescaler set to /8 and use a 8mS gate as this gives more stable results compared to no ETR2 prescaler and a 1mS gate.

The counter easily goes to over 55MHz with 1kHz resolution.

As mentioned above due to HW constraints I'm forced to us PD2 input pin which connects to 16 bit timer.

Certainly has been a good learning exercise and worth the effort and time - I appreciate your help.

Regards Tim
Tinkering for over 50 years and still learning  G4WIM KT6UK
 

Offline timdf911Topic starter

  • Contributor
  • Posts: 23
  • Country: gb
Re: Help with STM32duino timers and frequency measurement
« Reply #34 on: December 15, 2022, 08:37:14 pm »
profdc9

Thanks for the links - I'll study them and hopefully learn something.

Looks like an interesting project, has it been published anywhere in full ?

Regards Tim
Tinkering for over 50 years and still learning  G4WIM KT6UK
 

Offline profdc9

  • Frequent Contributor
  • **
  • Posts: 319
  • Country: us
Re: Help with STM32duino timers and frequency measurement
« Reply #35 on: December 16, 2022, 02:37:07 am »
I attempted to publish in QST/QEX but they rejected.  Also in another UK amateur radio society journal.

There is a 60 page document in the project explaining how it works.

https://github.com/profdc9/ModularTuner/blob/master/doc/ModularTuner-Guide.pdf
 

Offline timdf911Topic starter

  • Contributor
  • Posts: 23
  • Country: gb
Re: Help with STM32duino timers and frequency measurement
« Reply #36 on: December 16, 2022, 08:37:52 pm »
Surprised it was rejected as they are usually begging for contributions.  I have subscriptions to both QEX and RadCom.

I've had several articles published in RadCom over the years most recently in January 2023 and this problem of measuring frequency is part of a follow up article.

I'm licensed as KT6UK / G4WIM

Making good headway with the design now I've found an adequate frequency measuring solution.

Edit - just been reading your document and what a great piece of work which has many parallels to what I'm working on.

Regards Tim
« Last Edit: December 16, 2022, 09:31:47 pm by timdf911 »
Tinkering for over 50 years and still learning  G4WIM KT6UK
 

Offline ozcar

  • Frequent Contributor
  • **
  • Posts: 322
  • Country: au
Re: Help with STM32duino timers and frequency measurement
« Reply #37 on: December 16, 2022, 11:05:06 pm »
Hi ozcar

the 4MHz limit was because I had the system clock set to about 8MHz rather than 84MHz.  Yes because the frequency counter is only 16 bits I have to make sure the max count is within limits so I have the ETR2 prescaler set to /8 and use a 8mS gate as this gives more stable results compared to no ETR2 prescaler and a 1mS gate.

The counter easily goes to over 55MHz with 1kHz resolution.

As mentioned above due to HW constraints I'm forced to us PD2 input pin which connects to 16 bit timer.

Certainly has been a good learning exercise and worth the effort and time - I appreciate your help.

Regards Tim

Definitely something not right there in regard to the 55MHz max. I tried with 8.4MHz timer clock, and ETPS set to divide by 8, so expected max frequency of (8.4/2)*8 = 33.6MHz. I found that it worked for input frequency 33MHz, but failed for 34MHz.

It somehow hurts to think that you have two 32-bit timers, but can't make use of either of them. You don't seem to be short of pins if you can afford to use two of them, PA5 and PB0, to tie two timers together, so what is it exactly that forces you to used PD2 as the input? 

And why the 8MHz system clock?
 

Offline timdf911Topic starter

  • Contributor
  • Posts: 23
  • Country: gb
Re: Help with STM32duino timers and frequency measurement
« Reply #38 on: December 17, 2022, 07:32:10 pm »
yes it's very sad that I'm confined to use a 16 bit counter but none the less it provides adequate performance for my needs.

As for using some other counter / pin which is 32 bit, sadly as this part of the design is an after thought all the other counter pins have other stuff attached to them for control / sensing of ancilliary hardware.

If I had a clean sheet of paper I would have mapped things differently - but as it stands I've effectively painted myself into a corner and thus PD2 is the only option.

Just to clarify when I accidentally set the system clock to 8MHz I was not using the /8 ETPS thus 4MHz maximum. 

Regards Tim
Tinkering for over 50 years and still learning  G4WIM KT6UK
 

Offline ozcar

  • Frequent Contributor
  • **
  • Posts: 322
  • Country: au
Re: Help with STM32duino timers and frequency measurement
« Reply #39 on: December 17, 2022, 09:23:33 pm »
Quite likely I am flogging a horse that you have already interred, but my excuse is that I want to learn more about the STM32 timers myself.

yes it's very sad that I'm confined to use a 16 bit counter but none the less it provides adequate performance for my needs.

As for using some other counter / pin which is 32 bit, sadly as this part of the design is an after thought all the other counter pins have other stuff attached to them for control / sensing of ancilliary hardware...

However, prior to this afterthought, you were evidently not using PA5 and PB0, because according to this, you have now tied them together:

... the time base signal pops out from TIM2 on PA5 then is hard wired back into PB0 to gate the counter on TIM3.

Now, it just so happens that one of the alternate functions for PA5, is the 32-bit TIM2 ETR input. That would require using some other pair of available pins to tie together, but did you really go through all the spare pins you have without finding a way to get an input capture trigger to a TIM2 channel? Even if there really is no pair of pins that allow that, the gated slave mode, which does not require any external cross link, is still possible.   
 

Offline timdf911Topic starter

  • Contributor
  • Posts: 23
  • Country: gb
Re: Help with STM32duino timers and frequency measurement
« Reply #40 on: December 17, 2022, 10:38:36 pm »
Ha Ha, yes dead and buried, train has left the station, ship has sailed etc......
Anyway to answer your question I was experimenting with timers generally on a stand alone STM32F401 with no hard io limitations - just  to see how things worked without worrying about pin mapping.

I knew at some point I'd have to migrate my experimental code to the final target with its IO limitations.

I've learnt a lot from this process - not only related to timers but other things as well such as MODER and alternate functions etc.

When time permits I'll have another go at bare metal DMA as I find using bare metal really helps me understand whats actually going rather than use HAL and cubemx etc.

Regarding other pins, I have an IO map and have crossed checked using CubeMX to identify which pins have timers hidden behind them and due to my bad choices I have blocked them all - doh !

This design uses a lot of IO as it has a lot of peripherals - spi LCD plus touch screen , I2C for EEPROM, stepper motor drives, PWM output, four analog inputs, serial comms, 6 push buttons, rotary encoder plus push button, 3 relays drives, 4 logic inputs.

Code size is currently 157kB and growing...

Regards Tim
Tinkering for over 50 years and still learning  G4WIM KT6UK
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf