cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F405 - measure two frequencies >= 10MHz

michael239955_stm1
Associate II
Posted on January 27, 2014 at 11:46

Hey at all,

First of all I want to say that my english isn't the best.

I have got a new project to do it on a STM32F405 controller.

I must measure two frequencies:

1. f1 = 13 to 16MHz

2. f2 = 10 to 13MHz

my plan to do it is:

 - create a internal time base 0.1ms

 - count at two input pins the edge of the two external frequencies,

 - and calculate it.

So what is the best way to do it on STM32? I read something with master and slave timers. ?!?

Further I want to do it in the peripherals to hold the cpu work very low.

the next step is to save the calculated frequencies in two ring buffers. because i have to make a filter over some samples to get the correct value.

what ist the best way to implement a ring buffer?

I hope somebody can give me some tips, especially for the different timers.

BR michael.

17 REPLIES 17
Posted on January 27, 2014 at 12:59

Isn't the point of homework that you study the material well enough to do it yourself?

Have the primary timers (you'll need two, as each has a single counting element) count external pulses. Either gate that timer with some integration pulse at your 0.1 ms periodicity, or sample the CNT register periodically using DMA
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
michael239955_stm1
Associate II
Posted on January 27, 2014 at 13:54

hey,

I am starting to get some knowledge about timers and counters.

but I don't know which parts I should study to relize the project.

So, I don't need a timebase generator? the Counter are able to counts edges for 0.1ms? How I can do that? Do you have an example which is nearly the same?

Thank you very much!!!

michael
Posted on January 27, 2014 at 17:14

Well you could probably read over the Timer chapter in the reference manual several times, it's pretty dense stuff, and the timers are both mindbogglingly awkward, and disappointingly inflexible. I feel your pain, but you'll have to work through it, and the examples in the STM32F4, and STM32F4-DISCO firmware examples.

Counting external pulses. [DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/STM32F4%20Timer%20External%20Pulse%20counting&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&currentviews=921]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Discovery%2FSTM32F4%20Timer%20External%20Pulse%20counting&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=921

You can use DMA to create a circular buffer, you can drive the DMA with another timer which can provide your sampling periodicity. With a large enough buffer, and HT/TC interrupts you can compute the deltas in the timer CNT measurements at a more leisurely pace, and filter/integrate/average your measurements over a longer window. You might get a little jitter in the measurement time (based on DMA latency/contention), but over the long haul this will even out, as the time base marches along at a consistent rate. ie it's not going to drift anymore than the clock source you utilize.

There are multiple master/slave modes, and methods of gating one slower timer against another, you'll have to experiment in your own time. These may well take a lot more management with interrupts than you suggest you want.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on January 27, 2014 at 17:44

> Well you could probably read over the Timer chapter in the reference manual several times,

> it's pretty dense stuff,

While the timers are quite complex (and, as Clive says, awkward at the same time) indeed, the description in the Reference Manual is poor in many respects. On the other hand, it's the basic reference material so you are bound to go through it.

There is also an appnote, AN4013, explaining the timers perhaps from a slightly different viewpoint, although it's not a well written material either. However, I recommend you to have a look also at that one.

Don't be puzzled by multiple timer chapters in the Reference Manual - there are several instances of the same basic design, but with variants - some of them are 32-bits, some do have extra features for motor control you won't need, some are stripped down versions. Which is which is described in a table in the appnote. I suggest to start with the TIM2-TIM5 chapter, they are the ''intermediate'' version.

JW

michael239955_stm1
Associate II
Posted on January 28, 2014 at 07:55

thank you...

it's really hard.

is there any documentation/manual about the standard_peripheral-library???

do you know if there is a possibility to measure the frequency and if there is a delta occured than start to buffer the values with dma? I want to realize that all in the pheripheral to hold the cpu fast!!!

 

Posted on January 28, 2014 at 08:37

> it's really hard.

Hard??? No. Complex, no doubt. But not hard. Keep reading. Do exercises. Proceed from simple to complex. It's no rocket science, it is solid engineering.

> is there any documentation/manual about the standard_peripheral-library???

C'mon. In the root of the ''library'', as a .chm file. Although its utility is similar as the whole ''library'''s.

> do you know if there is a possibility to measure the frequency and if there is a delta occured than start to buffer the values with dma?

I again suggest you to proceed step by step. First, learn how to use one timer as a timebase, perhaps outputting it to a pin to watch on an oscilloscope or LA. Second, learn how to use this timer as a gate for another timer which acts as a counter for the input signal. Then calculate and output/display the resulting frequency. Then calculate the error of measurement. By the time you get here, you should know, how to proceed next.

JW

michael239955_stm1
Associate II
Posted on January 28, 2014 at 13:56

so, started already with some little exercises as you suggested.
 at the moment I try to implement the gated timer.
 whats the best way the get the counter state at tim2? make a interruptroutine for tim3 and make counts = GetCounter(TIM2) ??
 is the following code correct for master Tim3 and gated TIM2 ???


 //-----------------------------------------------------------------------------
// Name : tim3_time_base
// Function : Configure Timer3 timbe base generator 10kHz
// Parameter : no
// Return : no
//-----------------------------------------------------------------------------
void tim3_time_base(void)
{
//TIM3 Clock Enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// Time Base Configuration
TIM_TimeBaseStructure.TIM_Period = 7199;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// Master Configuration in ??
/*
*/
// Select the Master Slave Mode for TIM3
// Enable: the counter enable signal is used as a trigger output TRGO. It is used to control a window
// in which a slave timer is enabled
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
// Master Mode selection
TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);
// Start the TIM3
TIM_Cmd(TIM3, ENABLE);
}//tim3_time_base
//======================================================================================
//-----------------------------------------------------------------------------
// Name : tim2_input_counter
// Function : Configure Timer2 as input counter and gated timer, master is timer3
// Parameter : no
// Return : no
//-----------------------------------------------------------------------------
void tim2_input_counter(void)
{
//TIM2 Clock Enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// Time Base Configuration
TIM_TimeBaseStructure.TIM_Period = 10;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_TIxExternalClockConfig(TIM2, TIM_TIxExternalCLK1Source_TI2, TIM_ICPolarity_Falling, 0);
// Slave Mode Selection TIM2
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(TIM2, TIM_TS_ITR1);
TIM_Cmd(TIM2, ENABLE);
}//tim2_input_counter
//======================================================================================
//-----------------------------------------------------------------------------
// Name : PORTA_Setup
// Function : Configure Pins on PORTA
// Parameter : no
// Return : no
//-----------------------------------------------------------------------------
void PORTA_Setup(void)

 {
GPIO_InitTypeDef GPIO_InitStructure;
//GPIOA Clock Enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//Configure PORTA Pin1 as input PIN
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}// PORTA_Setup
//======================================================================================

Posted on January 28, 2014 at 20:41

The slave counter counts while the gate signal is positive. The ''update event'' signal (UEV) is positive only for one input clock of the master timer - the one when the timer's counter is reloaded. I doubt this is what you want.

So you should resort to setting TRGO to some of the output compare and set that channel appropriately (while letting the timer run up far beyond the compare value, leaving enough time for the ISR to happen). You'd then need to restart the master in the ISR, after you've read out the slave and reset it.

You know what, there's even a sub-chapter in the manual describing this. You seriously should read it carefully.

Also, check the slave trigger selection - my reading of Tab97 is, that for master=TIM3 and slave=TIM2 it's ITR2.

JW

michael239955_stm1
Associate II
Posted on February 05, 2014 at 11:48

At the moment I can count the external pulses. And calculate the Frequency of the external Signal. But I do this at the moment with Interrupts of my TimeBase generator.

And thats happens every 100µs. :\

What I want to realize next is following:

check the frequency with my existing timebase.

if the frequency is = 1MHz don't save the values and don't interrupt the main program.

if the frequency is = 2MHz or higher!! start saving the values still the frequency drops down to 1MHz.

my approach is: to generate the timebase of 0.1ms. (Timer1) reset after every UEV the Timer2 compare register.

counts the external pulses. with two compare registers (Timer2)

compare1  value = 200 (2MHz)   (2MHz/10kHz)

how I can realize to compare the compare1-value with the counter of the external pulses??

if compare1 reaches the value save the compare2-value every 0.1ms in the ring buffer.

is it possible to do this with one Timer?

It doesn't matter if the main programm is interrupted while the frequency is > 2MHz.

BR M.