Showing results for 
Search instead for 
Did you mean: 

DMA + Input Capture only runs one time at TIM16, but TIM17 works great!

Senior II

I have two Input Capture. One at channel 1 at TIM16 and one at channel 1 at TIM17.

But only TIM17 calls sevral times. TIM16 only calls one time. Then it seems that it stops.

Only call one time is a sign of the DMA is in normal mode. If I can call DMA servral times, that means that the DMA is in cirular mode.

What happens:

For input_capture0 (TIM17) array, it works like a charm. Every time I pulse 3.3v onto the input, I get a different value.

But for input capture1 (TIM16) array, the function compute_frequency always return 0.153186 and the value never changes any more. No matter how much I pulse 3.3v onto the input.

Can it be that even if I have selected cirular mode for's still normal mode?

Because if I have normal mode on DMA for TIM17, the the same behaviour occurs, with a different value of course.

The MCU is STM32F373VBTx and STM32CubeIDE 1.7.0

My code:

volatile static uint16_t input_capture0[2] = {0};
volatile static uint16_t input_capture1[2] = {0};
void STM32_PLC_Start_Input_Capture(TIM_HandleTypeDef* htim17, TIM_HandleTypeDef* htim16) {
	 * Input capture for measuring frequency
	 * For TIM17 and TIM16
	 * Timer clock: 48 Mhz
	 * Prescaler: 4799
	 * Counter: 65535 (0xffff)
	 * Update frequency: 0.1526 Hz (1/0.1526 = 6.5535 seconds)
	 * Example: For every second, it will count 10000
	 * Lowest frequency measurement: 1/(0xFFFF*0.0001) = 0.1526 Hz
	 * Highest frequency measurement: 1/(1*0.0001) = 10000 Hz
	if(HAL_TIM_IC_Start_DMA(htim16, TIM_CHANNEL_1, (uint32_t*)input_capture1, 2) != HAL_OK)
	if(HAL_TIM_IC_Start_DMA(htim17, TIM_CHANNEL_1, (uint32_t*)input_capture0, 2) != HAL_OK)
static float compute_frequency(uint16_t input_capture[]) {
	 * Typical worst case scenarios:
	 * T1: 0xFFFF - T0: 0x0
	 * T1: 0x0    - T0: 0xFFFF
	 * T1: 0x7FFF - T0: 0x7FFF
	 * T1: 0x0	  -	T0: 0x0
	if(input_capture[1] > input_capture[0]) {
		return (float) 1/((input_capture[1] - input_capture[0])*0.0001f);
	} else if(input_capture[1] < input_capture[0]) {
		return (float) 1/((input_capture[1] + 0xFFFF - input_capture[0])*0.0001f);
	} else if(input_capture[1] == 0x7FFF && input_capture[0] == 0x7FFF){
		return (float) 1/(0xFFFF*0.0001f);
	} else {
		return 0;
float STM32_PLC_Input_Capture_Get(uint8_t i) {
	if(i == 0)
		return compute_frequency((uint16_t*)input_capture0);
		return compute_frequency((uint16_t*)input_capture1);

Here is my setup for TIM17.

0693W00000D1pJNQAZ.png0693W00000D1pJSQAZ.pngAnd here is for TIM16.


Principal III

Have you checked the Cube generated code and the DMA register settings at runtime?

I have generate the code bit I don't know where to look if at.​