cancel
Showing results for 
Search instead for 
Did you mean: 

Frequency Capture

aru
Associate II
Posted on June 08, 2013 at 12:03

I am using stm32f103rbt6 for frequency capturing. I am trying to use timer1 channel1 and channel2 to capture two different frequency say 1K and 500 hertz. Once 1k frequency rising edge is detected i am reading the CCMR1 value and clearing the CNT register for next rising edge so 500 hertz frequency is not detecting properly because only one counter register is available pls let me known how to over come this problem. Thank u all in advance.....

#frequency-counter
3 REPLIES 3
Posted on June 08, 2013 at 13:02

I am using stm32f103rbt6 for frequency capturing. I am trying to use timer1 channel1 and channel2 to capture two different frequency say 1K and 500 hertz. Once 1k frequency rising edge is detected i am reading the CCMR1 value and clearing the CNT register for next rising edge so 500 hertz frequency is not detecting properly because only one counter register is available pls let me known how to over come this problem. Thank u all in advance.....

Why would you zero CNT? It's the only timebase counting element in the timer, everything else is a latch. Do a delta measurement between what CCRx was last time you measured it, and the next. ie delta = (b - a). This will give you the periods in ticks of the timebase clock between the two events.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
smeric
Associate II
Posted on October 21, 2013 at 14:08 hi clive I wanna measure frequency with stm32f4.

#include ''stm32f4xx.h''
#include ''string.h''
#include ''stdint.h''
#include ''stdlib.h''
#include ''stdio.h''
#include ''delay.h''
#include ''stm32f4xx_it.h''
#include ''stm32f4xx_gpio.h''
#include ''stm32f4_discovery.c''
#define ADC3_DR_ADDRESS ((uint32_t)0x4001224C)
extern

unsigned

char

flag;
uint16_t i;
uint16_t Xpos;
uint16_t Ypos;
uint16_t a;
uint16_t Width;
uint16_t Height;
uint16_t Length;
uint8_t Direction;
char

stringas[8];
int

xold, yold;
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
int

x;
u32 timer3Value;
u32 timer3IRQvalue;
u32 frequencyH;
u32 frequencyL;
void

TIM3_Configuration(

void

)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure3;
/* GPIOC clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* GPIOA Configuration: TIM3 CH1 (PC6) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

// Input/Output controlled by peripheral

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

// Button to ground expectation

GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Connect TIM3 pins to AF */
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);
TIM_TimeBaseStructure3.TIM_Period = 65535;
TIM_TimeBaseStructure3.TIM_Prescaler = 0;
TIM_TimeBaseStructure3.TIM_ClockDivision = 0;
TIM_TimeBaseStructure3.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure3);
TIM_TIxExternalClockConfig(TIM3, TIM_TIxExternalCLK1Source_TI1,
TIM_ICPolarity_Rising, 0);
TIM_Cmd(TIM3, ENABLE);
}
/**
* @brief Setup an interval timer
* @param None
* @retval None
*/
void

INTTIM_Config(

void

)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure2;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM2 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* Time base configuration */
TIM_TimeBaseStructure2.TIM_Period = 1000000 - 1;

// 1 MHz down to 1 KHz (1 ms)

TIM_TimeBaseStructure2.TIM_Prescaler = 84 - 1;

// 24 MHz Clock down to 1 MHz (adjust per your clock)

TIM_TimeBaseStructure2.TIM_ClockDivision = 0;
TIM_TimeBaseStructure2.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure2);
/* TIM IT enable */
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
}
char

buffer[40];
float

ubuffer[40];
char

bufferx[40];
u32 total = 0;
u32 cycles0 = 0;
u32 cycles1 = 0;
u32 cycles2 = 0;
u32 freqc_high = 0;
u32 freqc_low = 0;
u32 get_freq()
{
int

m = 0;
cycles0 = 0;
cycles1 = 0;
cycles2 = 0;
freqc_high = 0;
TIM3->CNT = 0;
/*_ wait one second___ */
TIM_Cmd(TIM3, ENABLE);
while

(cycles1 != 0x1) {

//dogru=3, yanlis=4

cycles0 = 0;

//1 cycle

//start inner loop
while

(cycles0 != 0xA412) {

//dogru=3, yanlis=4

if

(TIM3->SR & TIM_SR_UIF) {
TIM3->SR = 0;
freqc_high++;
}

else
// // |-- 8 cycles

{
m = 0;
m = 0;
m = 0;
m = 0;
m = 0;
}
cycles0++;

//1

}
cycles1++;

//1 cycle

}
TIM_Cmd(TIM3, DISABLE);
/*_ 1 saniye sonunda bekle___ */
if

(TIM3->SR & TIM_SR_UIF) {
frequencyH++;
}
freqc_low = TIM3->CNT;
total = ((freqc_high * 65536) + freqc_low);
return

total;
}

in this code

get_freq function is sniffing ccp interrupt register and if its changeed its incriment of Frequency high value. but most importand thing is in while must be fix cycle to calculate timing. so I did that algoritm in other MCU. but now I wanna use STM32 series for my all project. but when I did debug every time if statement is using different cycles ( sometimes 3 sometimes 4 sometimes 5, so I can not calculate total cycle in while. as you know F= 1/T so I know F but dont know T so I can not be sure real frequency. with this method I read 90mhz sinus signal with pic18f series. could you help me ?

while

(cycles0 != 100) { |--

true

=3 cycles ,

false

=4 cycles
if

(TIM3->SR & TIM_SR_UIF) {
|--
TIM3->SR = 0; |-- 8 cycles
freqc_high++; |--
}

else

{
m = 0; m = 0; m = 0; m = 0; m = 0; |-- 8 cycles
}
cycles0++;

//1

}
// total cycles in while => ((3+8+1)*100)+4 => f = 1/t.
// if MCU is working with 168mhz total time in while ?

Posted on October 21, 2013 at 15:29

Indeed the joys of using a pipelined processor with a cache, slow flash, aggressive prefetch and instructions/bus interactions that can increase the latency of an interrupt. Employ a better technique.

Use another timer and DMA to snap-shot the TIMx->CNT register, this will have far better repeatability over an IRQ. For a 16-bit timer the integration period must be shorter, but there are 32-bit timers capable of 84-MHz operation.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..