2018-05-29 12:43 AM
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.2018-05-29 05:11 AM
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.................
2018-05-29 05:30 AM
To me, this sounds like a perfect case for a hardware solution. Perhaps a FPGA, or similar.
2018-05-29 05:41 AM
The management will not spend a cent on something that is 'possible' to do with software.....
Software is 'free of charge'..........................
2018-05-29 06:19 AM
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.'
2018-05-29 06:33 AM
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.
2018-05-29 07:16 PM
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......
2018-05-29 07:50 PM
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; } } } }2018-05-30 04:00 AM
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.