2021-08-08 02:46 AM
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 TIM16...it'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)
Error_Handler();
if(HAL_TIM_IC_Start_DMA(htim17, TIM_CHANNEL_1, (uint32_t*)input_capture0, 2) != HAL_OK)
Error_Handler();
}
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);
else
return compute_frequency((uint16_t*)input_capture1);
}
Here is my setup for TIM17.
And here is for TIM16.
2021-08-08 03:20 AM
Have you checked the Cube generated code and the DMA register settings at runtime?
2021-08-08 05:22 AM
I have generate the code bit I don't know where to look if at.