2013-06-08 03:03 AM
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-counter2013-06-08 04:02 AM
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.2013-10-21 05:08 AM
#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 ?
2013-10-21 06:29 AM
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.