cancel
Showing results for 
Search instead for 
Did you mean: 

Input Capture on very high frequency

Ngai yuk kong
Associate II
Posted on May 29, 2018 at 09:43

Hi All,

I am now working on STM32F071 running at 48MHz. I would like to use timer to capture a signal at frequency higher than 400KHz.

Originally I use the input capture interrupt to read the period and duty cycle. The method is ok up to 4xxKHz. Then when the signal frequency becomes higher (600kHz for example), my software in main loop does not have chance to run at all.

I want to ask:

1. Is there any one shot input capture mode so that the software will not keep entering the input capture interrupt ? (if yes, how to set?)

2. What normally people will do if they require to continuously monitor a very high frequency input signal using input capture mode?

Thank you very much.

Note: this post was migrated and contained many threaded conversations, some content may be missing.
17 REPLIES 17
Posted on May 29, 2018 at 12:11

I want to do is: 

Input capture an external clock, check its frequency. If it is valid, use it as a source for one pulse mode to generate a phase shift clock. If it is invalid (frequency too high or too low), self generate a 400KHz PWM as an input clock source, still use one pulse mode to generate a phase shift clock.

I will have several cascaded units so the generated phase shift clock will pass to the next unit as an external clock and so on.................

Posted on May 29, 2018 at 12:30

To me, this sounds like a perfect case for a hardware solution. Perhaps a FPGA, or similar.

Posted on May 29, 2018 at 12:41

The management will not spend a cent on something that is 'possible' to do with software.....

Software is 'free of charge'..........................

Posted on May 29, 2018 at 13:19

Well, I am no hardware guy, but I expect a proper hardware solution to be cheaper and more robust than a software-based. Especially since the cheap M0/M0+ devices are ill-equipped for tasks demanding high throughput with short cycle times.

But, as the old saying goes:'If your only tool is a hammer, every problem begins to look like a nail.'

Posted on May 29, 2018 at 13:33

my suggestion, it is Free of Charge, likely to work with work on your part.

come back to us with code and your actual issues.

Posted on May 30, 2018 at 02:16

I did the self disable in the input capture routine and got fxxk by the supervisor. He said the decision has to be made in the main loop, not inside the interrupt routine. This is the beginning of the story I posted here......

Posted on May 30, 2018 at 02:50

Now, I have two routines called in main loop periodically:

//3ms

static void ServicePWM(void *arg)

{

uint8_t re_exit = 0;

svcMngr_StartTimer(&tim_pwm, SVCMNGR_MS_TO_TICKS(PWM_SERVICE_TIME));

if(no_ext_clk_cnt > 0)

no_ext_clk_cnt--;

if(ext_clock_status == EXT_CLK_READY)

{

re_exit = 1;

}

else if(ext_clock_status == EXT_CLK_INVALID || no_ext_clk_cnt == 0)

{

DISABLE_EXT_CLK_INPUT;

//self generate PWM

initPWMOutputTim16();

period = TIMER_PERIOD_400K;

pulse_width = TIMER_DUTY_CYCLE_400K;

re_exit = 1;

//TODO:

//if (!i_am_1st_module)

//PMBUS report error -> LED freshing..

}

// exit and turn off necesary service.

if(re_exit)

{

initOnePulseModeTim1(period, pulse_width);

svcMngr_StopTimer(&tim_input_capture);

svcMngr_UnregisterService(input_capture_service_id);

svcMngr_StopTimer(&tim_pwm);

svcMngr_UnregisterService(pwm_service_id);

}

}

//500us

static void ServiceInputCapture(void *arg)

{

static uint8_t ext_clk_valid_cnt = 0;

static uint8_t ext_clk_invalid_cnt = 0;

svcMngr_StartTimer(&tim_input_capture, SVCMNGR_US_TO_TICKS(CAPTURE_SERVICE_TIME));

if(TIM1->SR & TIM_SR_CC1IF)

{

pulse_width = TIM1->CCR1;

period = TIM1->CCR2;

if(period != 0 && pulse_width != 0 && (period > pulse_width))

{

pulse_width += TIMER_COMPENSATE;

period += TIMER_COMPENSATE;

if(period > TIMER_PERIOD_500K && period < TIMER_PERIOD_200K)

{

ext_clk_valid_cnt++;

ext_clk_invalid_cnt = 0;

if(ext_clk_valid_cnt >= 5 && ext_clock_status != EXT_CLK_INVALID)

ext_clock_status = EXT_CLK_READY;

}

else

{

ext_clk_valid_cnt = 0;

ext_clk_invalid_cnt++;

if(ext_clk_invalid_cnt >= 5)

ext_clock_status = EXT_CLK_INVALID;

}

}

}

}

henry.dick
Senior II
Posted on May 30, 2018 at 13:00

If you are trying to measure high frequency using input capture interrupts you are going down a very wrong path. Instead configure the timer as a counter for the external pulse train.